static FAR struct fb_vtable_s *trv_get_fbdev(void) { FAR struct fb_vtable_s *fbdev; int ret; /* Initialize the frame buffer device */ ret = up_fbinitialize(); if (ret < 0) { trv_abort("ERROR: up_fbinitialize failed: %d\n", -ret); } /* Set up to use video plane 0. There is no support for anything but * video plane 0. */ fbdev = up_fbgetvplane(0); if (!fbdev) { trv_abort("ERROR: up_fbgetvplane(0) failed\n"); } return fbdev; }
int trv_servertask(int argc, char *argv[]) { FAR struct fb_vtable_s *fbdev; int ret; /* Get the framebuffer device */ fbdev = trv_get_fbdev(); /* Then start the server */ ret = nx_run(dev); trv_abort("nx_run returned: %d\n", errno); }
static void trv_fb_initialize(FAR struct trv_graphics_info_s *ginfo) { struct fb_videoinfo_s vinfo; struct fb_planeinfo_s pinfo; FAR struct fb_vtable_s *fbdev; int ret; /* Get the framebuffer device */ fbdev = trv_get_fbdev(); /* Get information about video plane 0 */ ret = fbdev->getvideoinfo(fbdev, &vinfo); if (ret < 0) { trv_abort("ERROR: getvideoinfo() failed\n"); } ginfo->xres = vinfo.xres; ginfo->yres = vinfo.yres; ret = fbdev->getplaneinfo(fbdev, 0, &pinfo); if (ret < 0) { trv_abort("ERROR: getplaneinfo() failed\n"); } ginfo->stride = pinfo.stride; ginfo->hwbuffer = pinfo.fbmem; if (vinfo.fmt != TRV_COLOR_FMT || pinfo.bpp != TRV_BPP) { trv_abort("ERROR: Bad color format(%d)/bpp(%d)\n", vinfo.fmt, pinfo.bpp); } }
static void trv_use_bgwindow(FAR struct trv_graphics_info_s *ginfo) { /* Get the background window */ ret = nx_requestbkgd(g_hnx, &g_trv_nxcallback, ginfo); if (ret < 0) { trv_abort("nx_requestbkgd failed: %d\n", errno); } /* Wait until we have the screen resolution. We'll have this immediately * unless we are dealing with the NX server. */ while (!g_trv_nxresolution) { (void)sem_wait(&g_trv_nxevent); } }
static inline int trv_nxsu_initialize(FAR struct trv_graphics_info_s *ginfo) { FAR struct fb_vtable_s *fbdev; int ret; /* Get the framebuffer device */ fbdev = trv_get_fbdev(); /* Open NX */ ginfo->hnx = nx_open(fbdev); if (!ginfo->hnx) { trv_abort("trv_nxsu_initialize: nx_open failed: %d\n", errno); } /* And use the background window */ trv_use_bgwindow(ginfo); }
FAR void *trv_nxlistener(FAR void *arg) { int ret; /* Process events forever */ for (;;) { /* Handle the next event. If we were configured blocking, then * we will stay right here until the next event is received. Since * we have dedicated a while thread to servicing events, it would * be most natural to also select CONFIG_NX_BLOCKING -- if not, the * following would be a tight infinite loop (unless we added addition * logic with nx_eventnotify and sigwait to pace it). */ ret = nx_eventhandler(g_hnx); if (ret < 0) { /* An error occurred... assume that we have lost connection with * the server. */ trv_abort("Lost server connection: %d\n", errno); } /* If we received a message, we must be connected */ if (!g_trv_nxrconnected) { g_trv_nxrconnected = true; sem_post(&g_trv_nxevent); trv_debug("Connected to server\n"); } } }
void trv_color_allocate(FAR struct trv_palette_s *pinfo) { #if RGB_CUBE_SIZE < MIN_LUM_LEVELS dev_pixel_t *lut; int uvndx; int lumndx; int index; /* Check if a color lookup table has been allocated */ pinfo->lut = (dev_pixel_t*) trv_malloc(sizeof(dev_pixel_t) * (NUNIT_VECTORS*NLUMINANCES)); if (!pinfo->lut) { trv_abort("ERROR: Failed to allocate color lookup table\n"); } lut = pinfo->lut; /* Save the color information and color lookup table for use in * color mapping below. */ g_pixel2um_lut = (struct trv_color_lum_s*) trv_malloc(sizeof(struct trv_color_lum_s) * (NUNIT_VECTORS*NLUMINANCES)); if (!g_pixel2um_lut) { trv_abort("ERROR: Failed to allocate luminance table\n"); } /* Allocate each color at each luminance value */ pinfo->ncolors = 0; index = 0; for (uvndx = 0; uvndx < NUNIT_VECTORS; uvndx++) { for (lumndx = 0; lumndx < NLUMINANCES; lumndx++) { struct trv_color_rgb_s color; FAR struct trv_color_lum_s *lum; /* Get a convenience pointer to the lookup table entry */ lum = &g_pixel2um_lut[index]; *lum = g_unit_vector[uvndx]; /* Get the luminance associated with this lum for this * unit vector. */ lum->luminance = (lum->luminance * (float)(lumndx + 1)) / NLUMINANCES; /* Convert to RGB and allocate the color */ color.red = (short) (lum->red * lum->luminance); color.green = (short) (lum->green * lum->luminance); color.blue = (short) (lum->blue * lum->luminance); /* Save the RGB to pixel lookup data */ lut[index] = TRV_MKRGB(color.red, color.green, color.blue); pinfo->ncolors = ++index; } } #else dev_pixel_t *lut; int index; struct trv_color_rgb_s rgb; /* Check if a color lookup table has been allocated */ pinfo->lut = (dev_pixel_t*) trv_malloc(sizeof(dev_pixel_t) * (TRV_PIXEL_MAX+1)); if (!pinfo->lut) { trv_abort("ERROR: Failed to allocate color lookup table\n"); } /* Save the color information and color lookup table for use in * subsequent color mapping. */ lut = pinfo->lut; /* Check if a Pixel-to-RGB color mapping table has been allocated */ g_pixl2rgb_lut = (struct trv_color_rgb_s*) trv_malloc(sizeof(struct trv_color_rgb_s) * (TRV_PIXEL_MAX+1)); if (!g_pixl2rgb_lut) { trv_abort("ERROR: Failed to allocate luminance table\n"); } for (index = 0; index <= TRV_PIXEL_MAX; index++) { g_pixl2rgb_lut[index].red = g_pixl2rgb_lut[index].green = g_pixl2rgb_lut[index].blue = 0; } /* Calculate the cube to trv_pixel_t scale factor. This factor will * convert an RGB component in the range {0..RGB_CUBE_SIZE-1} to * a value in the range {0..TRV_PIXEL_MAX}. */ g_trv_cube2pixel = (float)TRV_PIXEL_MAX / (float)(RGB_CUBE_SIZE-1); /* Allocate each color in the RGB Cube */ pinfo->ncolors = index = 0; for (rgb.red = 0; rgb.red < RGB_CUBE_SIZE; rgb.red++) for (rgb.green = 0; rgb.green < RGB_CUBE_SIZE; rgb.green++) for (rgb.blue = 0; rgb.blue < RGB_CUBE_SIZE; rgb.blue++) { struct trv_color_rgb_s color; color.red = (short) (rgb.red * 65535 / (RGB_CUBE_SIZE - 1)); color.green = (short) (rgb.green * 65535 / (RGB_CUBE_SIZE - 1)); color.blue = (short) (rgb.blue * 65535 / (RGB_CUBE_SIZE - 1)); /* Save the RGB to pixel lookup data */ lut[index] = TRV_MKRGB(color.red, color.green, color.blue); pinfo->ncolors = ++index; /* Save the pixel to RGB lookup data */ if (color.pixel <= TRV_PIXEL_MAX) { g_pixl2rgb_lut[color.pixel] = rgb; } } #endif }
void trv_input_read(void) { #if defined(CONFIG_GRAPHICS_TRAVELER_JOYSTICK) #if defined(CONFIG_GRAPHICS_TRAVELER_AJOYSTICK) struct ajoy_sample_s sample; int ret; /* Read data from the analog joystick */ ret = trv_joystick_read(&sample); if (ret < 0) { trv_abort("ERROR: trv_joystick_read() failed: %d\n", ret); } /* Determine the input data to return to the POV logic */ /* Assuming moving slowing so we cannot step over tall things */ g_trv_input.stepheight = g_walk_stepheight; /* Move forward or backward OR look up or down */ g_trv_input.leftrate = 0; g_trv_input.yawrate = 0; g_trv_input.pitchrate = 0; g_trv_input.fwdrate = 0; if ((sample.as_buttons & AJOY_BUTTON_FIRE_BIT) != 0) { /* Move left/rignt */ g_trv_input.leftrate = trv_scale_input_x(&sample); /* Look upward/downward */ g_trv_input.pitchrate = trv_scale_input_pitch(&sample); /* If we are moving faster than a walk, we can jump higher */ if (g_trv_input.leftrate < -WALK_RATE || g_trv_input.leftrate > WALK_RATE) { g_trv_input.stepheight = g_run_stepheight; } } else { /* Turn left/right */ g_trv_input.yawrate = trv_scale_input_yaw(&sample); /* Move forward/backward */ g_trv_input.fwdrate = trv_scale_input_y(&sample); /* If we are moving faster than a walk, we can jump higher */ if (g_trv_input.fwdrate < -WALK_RATE || g_trv_input.fwdrate > WALK_RATE) { g_trv_input.stepheight = g_run_stepheight; } } g_trv_input.dooropen = ((sample.as_buttons & AJOY_BUTTON_SELECT_BIT) != 0); #elif defined(CONFIG_GRAPHICS_TRAVELER_DJOYSTICK) struct djoy_buttonset_t buttonset; ssize_t nread; int16_t move_rate; int16_t turn_rate; /* Read data from the discrete joystick */ nread = read(g_trv_joystick.fd, &buttonset, sizeof(djoy_buttonset_t)); if (nread < 0) { trv_abort("ERROR: Joystick read error: %d\n", errno); } else if (nread != sizeof(struct djoy_buttonset_t)) { trv_abort("ERROR: Unexpected joystick read size: %ld\n", (long)nread); } /* Determine the input data to return to the POV logic */ if ((buttonset & DJOY_BUTTON_RUN_BIT) != 0) { /* Run faster/step higher */ g_trv_joystick.stepheight = g_run_stepheight; move_rate = RUN_RATE; turn_rate = ANGLE_9; } else { /* Normal walking rate and stepping height */ g_trv_joystick.stepheight = g_walk_stepheight; move_rate = WALK_RATE; turn_rate = ANGLE_6; } /* Move forward or backward OR look up or down */ g_trv_joystick.pitchrate = 0; g_trv_joystick.fwdrate = 0; switch (buttonset & (DJOY_UP_BIT | DJOY_DOWN_BIT)) { case 0: case (DJOY_UP_BIT | DJOY_DOWN_BIT): /* Don't move, don't nod */ break; case DJOY_UP_BIT: if ((buttonset & DJOY_BUTTON_FIRE_BIT) != 0) { /* Look upward */ g_trv_input.pitchrate = turn_rate; } else { /* Move forward */ g_trv_input.fwdrate = move_rate; } break; case DJOY_DOWN_BIT: if ((buttonset & DJOY_BUTTON_FIRE_BIT) != 0) { /* Look downward */ g_trv_input.pitchrate = -turn_rate; } else { /* Move Backward */ g_trv_input.fwdrate = -move_rate; } break; } /* Move or loook left or right */ g_trv_input.yawrate = 0; g_trv_input.leftrate = 0; switch (buttonset & (DJOY_LEFT_BIT | DJOY_RIGHT_BIT)) { case 0: case (DJOY_LEFT_BIT | DJOY_RIGHT_BIT): /* Don't move, don't nod */ break; case DJOY_LEFT_BIT: if ((buttonset & DJOY_BUTTON_FIRE_BIT) != 0) { /* Turn left */ g_trv_input.yawrate = turn_rate; } else { /* Move left */ g_trv_input.leftrate = move_rate; } break; case DJOY_RIGHT_BIT: if ((buttonset & DJOY_BUTTON_FIRE_BIT) != 0) { /* Turn right */ g_trv_input.yawrate = -turn_rate; } else { /* Move right */ g_trv_input.leftrate = -move_rate; } break; } g_trv_input.dooropen = ((buttonset & DJOY_BUTTON_SELECT_BIT) != 0); #endif /* CONFIG_GRAPHICS_TRAVELER_DJOYSTICK */ #elif defined(CONFIG_GRAPHICS_TRAVELER_NX_XYINPUT) /* Make position decision based on last sampled X/Y input data */ #warning Missing logic #endif }
void trv_input_initialize(void) { #if defined(CONFIG_GRAPHICS_TRAVELER_DJOYSTICK) struct djoy_notify_s notify; /* Open the joy stick device */ g_trv_joystick.fd = open(CONFIG_GRAPHICS_TRAVELER_JOYDEV, O_RDONLY); if (g_trv_joystick.fd < 0) { trv_abort("ERROR: Failed to open %s: %d\n", CONFIG_GRAPHICS_TRAVELER_JOYDEV, errno); } #elif defined(CONFIG_GRAPHICS_TRAVELER_AJOYSTICK) struct ajoy_notify_s notify; int ret; /* Open the joy stick device */ g_trv_joystick.fd = open(CONFIG_GRAPHICS_TRAVELER_JOYDEV, O_RDONLY); if (g_trv_joystick.fd < 0) { trv_abort("ERROR: Failed to open %s: %d\n", CONFIG_GRAPHICS_TRAVELER_JOYDEV, errno); } /* Register to receive a signal on any change in the joystick buttons. */ notify.an_press = BUTTON_SET; notify.an_release = 0; notify.an_signo = CONFIG_GRAPHICS_TRAVELER_JOYSTICK_SIGNO; ret = ioctl(g_trv_joystick.fd, AJOYIOC_REGISTER, (unsigned long)((uintptr_t)¬ify)); if (ret < 0) { fprintf(stderr, "ERROR: ioctl(AJOYIOC_REGISTER) failed: %d\n", errno); goto errout_with_fd; } /* Calibrate the analog joystick device */ ret = trv_joystick_calibrate(); if (ret < 0) { trv_abort("ERROR: Failed to calibrate joystick: %d\n", ret); goto errout_with_fd; } /* Disable any further button events. */ notify.an_press = 0; notify.an_release = 0; notify.an_signo = CONFIG_GRAPHICS_TRAVELER_JOYSTICK_SIGNO; ret = ioctl(g_trv_joystick.fd, AJOYIOC_REGISTER, (unsigned long)((uintptr_t)¬ify)); if (ret < 0) { fprintf(stderr, "ERROR: ioctl(AJOYIOC_REGISTER) failed: %d\n", errno); goto errout_with_fd; } return; errout_with_fd: close(g_trv_joystick.fd); g_trv_joystick.fd = -1; #elif defined(CONFIG_GRAPHICS_TRAVELER_NX_XYINPUT) /* Set the position to the center of the display at eye-level */ #warning Missing logic #endif }
int trv_graphics_initialize(FAR struct trv_graphics_info_s *ginfo) { int width; int height; int scale; /* Initialize the graphics device and get information about the display */ #if !defined(CONFIG_NX) trv_fb_initialize(ginfo); #elif defined(CONFIG_NX_MULTIUSER) trv_nxmu_initialize(ginfo); #else trv_nxsu_initialize(ginfo); #endif /* Check the size of the display */ width = ginfo->xres; height = ginfo->yres; if (width < TRV_SCREEN_WIDTH || height < TRV_SCREEN_HEIGHT) { trv_abort("ERROR: Display is too small\n"); } /* Check if we need to scale the image */ scale = 0; while (width >= TRV_SCREEN_WIDTH) { width -= TRV_SCREEN_WIDTH; scale++; } ginfo->xscale = scale; ginfo->xoffset = (width >> 1); ginfo->imgwidth = scale * TRV_SCREEN_WIDTH * sizeof(dev_pixel_t); scale = 0; while (height >= TRV_SCREEN_HEIGHT) { height -= TRV_SCREEN_HEIGHT; scale++; } ginfo->yscale = scale; ginfo->yoffset = (height >> 1); /* Allocate buffers * * ginfo->swbuffer - Software renders into this buffer using an 8-bit * encoding and perhaps at a different resolution that the final * image. */ ginfo->swbuffer = (trv_pixel_t*) trv_malloc(TRV_SCREEN_WIDTH * TRV_SCREEN_HEIGHT * sizeof(trv_pixel_t)); if (!ginfo->swbuffer) { trv_abort("ERROR: Failed to allocate render buffer\n"); } /* Using the framebuffer driver: * ginfo->hwbuffer - This address of the final, expanded frame image. * This address is determined by hardware and is neither allocated * nor freed. * * Using NX * ginfo->hwbuffer - This address of one line of the final expanded * image that must transferred to the window. */ #ifdef CONFIG_NX ginfo->hwbuffer = (trv_pixel_t*)trv_malloc(ginfo->imgwidth); if (!ginfo->hwbuffer) { trv_abort("ERROR: Failed to allocate hardware line buffer\n"); } #endif /* Allocate color mapping information */ trv_color_allocate(&ginfo->palette); trv_vdebug("%d colors allocated\n", ginfo->palette.ncolors); return OK; }