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");
        }
    }
}
示例#7
0
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
}
示例#8
0
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
}
示例#9
0
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)&notify));
  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)&notify));
  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;
}