Correct graphics scaling logic

This commit is contained in:
Gregory Nutt 2014-12-03 18:19:10 -06:00
parent 2d8e0458d1
commit bfd9cfe0e5
3 changed files with 54 additions and 33 deletions

View File

@ -86,14 +86,16 @@ struct trv_graphics_info_s
NXHANDLE hnx; /* The connection handle */ NXHANDLE hnx; /* The connection handle */
NXHANDLE bgwnd; /* Background window handle */ NXHANDLE bgwnd; /* Background window handle */
#else #else
trv_coord_t stride; /* Length of a line in bytes */ trv_coord_t hoffset; /* Horizontal to start of data (in columns) */
trv_coord_t voffset; /* Offset to start of data (in rows) */
trv_coord_t stride; /* Length of a line (in bytes) */
#endif #endif
trv_coord_t hwwidth; /* Display width (pixels) */ trv_coord_t hwwidth; /* Display width (pixels) */
trv_coord_t hwheight; /* Display height (rows) */ trv_coord_t hwheight; /* Display height (rows) */
trv_coord_t swwidth; /* Software render width (pixels) */ trv_coord_t swwidth; /* Software render width (pixels) */
trv_coord_t swheight; /* Software render height height (rows) */ trv_coord_t swheight; /* Software render height height (rows) */
uint8_t vscale; /* Log2 vertical image scale factor */ uint8_t vscale; /* Vertical image scale factor */
uint8_t hscale; /* Log2 horizontal image scale factor */ uint8_t hscale; /* Horizontal image scale factor */
struct trv_palette_s palette; /* Color palette */ struct trv_palette_s palette; /* Color palette */
FAR dev_pixel_t *hwbuffer; /* Hardware frame buffer */ FAR dev_pixel_t *hwbuffer; /* Hardware frame buffer */
FAR trv_pixel_t *swbuffer; /* Software render buffer */ FAR trv_pixel_t *swbuffer; /* Software render buffer */

View File

@ -41,12 +41,16 @@
****************************************************************************/ ****************************************************************************/
#include "trv_types.h" #include "trv_types.h"
#include "trv_graphics.h"
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
/* This is the size of the buffer supported by the ray caster */
#define TRV_SCREEN_WIDTH 320
#define TRV_SCREEN_HEIGHT 200
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
@ -55,6 +59,9 @@
* Public Function Prototypes * Public Function Prototypes
****************************************************************************/ ****************************************************************************/
struct trv_camera_s;
struct trv_graphics_info_s;
void trv_raycaster(FAR struct trv_camera_s *player, void trv_raycaster(FAR struct trv_camera_s *player,
FAR struct trv_graphics_info_s *ginfo); FAR struct trv_graphics_info_s *ginfo);

View File

@ -41,6 +41,7 @@
#include "trv_main.h" #include "trv_main.h"
#include "trv_mem.h" #include "trv_mem.h"
#include "trv_color.h" #include "trv_color.h"
#include "trv_raycntl.h"
#include "trv_debug.h" #include "trv_debug.h"
#include "trv_graphics.h" #include "trv_graphics.h"
@ -329,24 +330,21 @@ void trv_row_update(struct trv_graphics_info_s *ginfo,
FAR const trv_pixel_t *src, FAR const trv_pixel_t *src,
FAR dev_pixel_t *dest) FAR dev_pixel_t *dest)
{ {
trv_coord_t hexpand;
dev_pixel_t pixel; dev_pixel_t pixel;
trv_coord_t srccol; trv_coord_t srccol;
int i; int i;
/* Loop for each column in the src render buffer */ /* Loop for each column in the src render buffer */
hexpand = (1 << ginfo->hscale); for (srccol = 0; srccol < TRV_SCREEN_WIDTH; srccol++)
for (srccol = 0; srccol < ginfo->swwidth; srccol++)
{ {
/* Map the source pixel */ /* Map the source pixel */
pixel = ginfo->palette.lut[*src++]; pixel = ginfo->palette.lut[*src++];
/* Copy it to the destination, expanding as necessary */ /* Expand pixels horizontally via pixel replication */
for (i = 0; i < hexpand; i++) for (i = 0; i < ginfo->hscale; i++)
{ {
*dest++ = pixel; *dest++ = pixel;
} }
@ -383,8 +381,8 @@ void trv_display_update(struct trv_graphics_info_s *ginfo,
int trv_graphics_initialize(FAR struct trv_graphics_info_s *ginfo) int trv_graphics_initialize(FAR struct trv_graphics_info_s *ginfo)
{ {
int swwidth; int width;
int swheight; int height;
int scale; int scale;
/* Initialize the graphics device and get information about the display */ /* Initialize the graphics device and get information about the display */
@ -397,31 +395,38 @@ int trv_graphics_initialize(FAR struct trv_graphics_info_s *ginfo)
trv_nxsu_initialize(ginfo); trv_nxsu_initialize(ginfo);
#endif #endif
/* Check the size of the display */
width = ginfo->hwwidth;
height = ginfo->hwheight;
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 */ /* Check if we need to scale the image */
swwidth = ginfo->hwwidth; scale = 0;
scale = 0;
while (swwidth > MAX_REND_WIDTH) while (width >= TRV_SCREEN_WIDTH)
{ {
swwidth >>= 1; width -= TRV_SCREEN_WIDTH;
scale++; scale++;
} }
ginfo->swwidth = swwidth; ginfo->hscale = scale;
ginfo->hscale = scale; ginfo->hoffset = (width >> 1);
swheight = ginfo->hwheight; scale = 0;
scale = 0; while (height >= TRV_SCREEN_HEIGHT)
while (swheight > MAX_REND_WIDTH)
{ {
swheight >>= 1; height -= TRV_SCREEN_HEIGHT;
scale++; scale++;
} }
ginfo->swheight = swheight; ginfo->vscale = scale;
ginfo->vscale = scale; ginfo->voffset = (height >> 1);
/* Allocate buffers /* Allocate buffers
* *
@ -431,7 +436,7 @@ int trv_graphics_initialize(FAR struct trv_graphics_info_s *ginfo)
*/ */
ginfo->swbuffer = (trv_pixel_t*) ginfo->swbuffer = (trv_pixel_t*)
trv_malloc(swwidth * swheight * sizeof(trv_pixel_t)); trv_malloc(TRV_SCREEN_WIDTH * TRV_SCREEN_HEIGHT * sizeof(trv_pixel_t));
if (!ginfo->swbuffer) if (!ginfo->swbuffer)
{ {
trv_abort("ERROR: Failed to allocate render buffer\n"); trv_abort("ERROR: Failed to allocate render buffer\n");
@ -503,8 +508,8 @@ void trv_graphics_terminate(FAR struct trv_graphics_info_s *ginfo)
void trv_display_update(struct trv_graphics_info_s *ginfo) void trv_display_update(struct trv_graphics_info_s *ginfo)
{ {
FAR const uint8_t *src = (FAR const uint8_t *)ginfo->swbuffer; FAR const uint8_t *src;
FAR uint8_t *dest = (FAR uint8_t *)ginfo->hwbuffer; FAR uint8_t *dest;
trv_coord_t srcrow; trv_coord_t srcrow;
#ifdef CONFIG_NX #ifdef CONFIG_NX
trv_coord_t destrow; trv_coord_t destrow;
@ -512,12 +517,19 @@ void trv_display_update(struct trv_graphics_info_s *ginfo)
FAR uint8_t *first; FAR uint8_t *first;
trv_coord_t lnwidth; trv_coord_t lnwidth;
#endif #endif
trv_coord_t vexpand;
int i; int i;
/* Loop for each row in the srce render buffer */ /* Get the star tof the first source row */
src = (FAR const uint8_t *)ginfo->swbuffer;
/* Get the start of the first destination row */
dest = (FAR uint8_t *)ginfo->hwbuffer +
(ginfo->hoffset * ginfo->stride) + ginfo->voffset;
/* Loop for each row in the src render buffer */
vexpand = (1 << ginfo->vscale);
#ifdef CONFIG_NX #ifdef CONFIG_NX
destrow = 0; destrow = 0;
#else #else
@ -543,7 +555,7 @@ void trv_display_update(struct trv_graphics_info_s *ginfo)
/* Then replicate as many times as is necessary */ /* Then replicate as many times as is necessary */
for (i = 1; i < vexpand; i++) for (i = 1; i < ginfo->vscale; i++)
{ {
#ifdef CONFIG_NX #ifdef CONFIG_NX
/* Transfer the row buffer to the NX window */ /* Transfer the row buffer to the NX window */
@ -560,7 +572,7 @@ void trv_display_update(struct trv_graphics_info_s *ginfo)
/* Point to the next src row */ /* Point to the next src row */
src += ginfo->swwidth; src += TRV_SCREEN_WIDTH;
} }
} }