mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-01-01 06:23:35 +01:00
render-cg: decently implement basic functions
This commit is contained in:
parent
04231ea5d6
commit
f3c8964b84
12 changed files with 409 additions and 88 deletions
|
@ -4,6 +4,8 @@
|
||||||
// This module covers all 16-bit opaque rendering functions. For
|
// This module covers all 16-bit opaque rendering functions. For
|
||||||
// gamma-related functions, color composition, check out a color library.
|
// gamma-related functions, color composition, check out a color library.
|
||||||
//
|
//
|
||||||
|
// All the functions in this module work on a 396x224 resolution - gint
|
||||||
|
// lets you use the full surface!
|
||||||
//---
|
//---
|
||||||
|
|
||||||
#ifndef GINT_DISPLAY_CG
|
#ifndef GINT_DISPLAY_CG
|
||||||
|
@ -11,10 +13,119 @@
|
||||||
|
|
||||||
#ifdef FXCG50
|
#ifdef FXCG50
|
||||||
|
|
||||||
/* Screen dimensions on fxcg50 - never mind the borders, gint lets you use the
|
#include <gint/defs/types.h>
|
||||||
full surface! */
|
|
||||||
#define DWIDTH 396
|
/* Expose the VRAM variable if GINT_NEED_VRAM is defined. It must always point
|
||||||
#define DHEIGHT 224
|
to a 32-aligned buffer of size 177408. Any function can use it freely to
|
||||||
|
perform rendering or store data when not drawing. Triple buffering is
|
||||||
|
already implemened in gint, see the dvram() function below.
|
||||||
|
|
||||||
|
In this module, colors are in the 16-bit R5G6B5 format, as it is the format
|
||||||
|
used by the display controller. */
|
||||||
|
|
||||||
|
#ifdef GINT_NEED_VRAM
|
||||||
|
extern uint16_t *vram;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Video RAM management
|
||||||
|
//---
|
||||||
|
|
||||||
|
/* dvram() - Control video RAM address and triple buffering
|
||||||
|
|
||||||
|
Normal rendering under gint uses double-buffering: there is one image
|
||||||
|
displayed on the screen and one in memory, in a region called the video RAM
|
||||||
|
(VRAM). The application draws frames in the VRAM then sends them to the
|
||||||
|
screen only when they are finished, using dupdate().
|
||||||
|
|
||||||
|
On fxcg50, the performance bottleneck is almost always the graphical
|
||||||
|
rendering (especially in games) because the high amount of data, 173 kB per
|
||||||
|
frame in full-resolution, makes graphics manipulation computationally
|
||||||
|
expensive. The transfer also takes about 10 ms in itself.
|
||||||
|
|
||||||
|
Since gint transfers data to the screen using the DMA, it is possible to run
|
||||||
|
the application while the finished frame is being transferred. However,
|
||||||
|
writing to the VRAM during this period it is still begin read by the DMA.
|
||||||
|
Changing the contents of the VRAM too soon would alter the frame being sent.
|
||||||
|
|
||||||
|
The solution to this is to use triple-buffering with the display and two
|
||||||
|
VRAMs that are alternately begin written to while the other is being
|
||||||
|
transferred. The VRAM switching is handled by dupdate() and is activated
|
||||||
|
whenever two VRAMs are configured.
|
||||||
|
|
||||||
|
By default gint uses triple buffering with one VRAM in the user stack and
|
||||||
|
a second one in the system stack.
|
||||||
|
|
||||||
|
VRAMs must be contiguous, 32-aligned, (2*396*224)-byte buffers.
|
||||||
|
|
||||||
|
@main Main VRAM area, used alone if [secondary] is NULL
|
||||||
|
@secondary Additional VRAM area, enables triple buffering if non-NULL */
|
||||||
|
void dvram(uint16_t *main, uint16_t *secondary);
|
||||||
|
|
||||||
|
/* dupdate() - push the video RAM to the display driver
|
||||||
|
This function makes the contents of the VRAM visible on the screen. It is
|
||||||
|
the direct equivalent of Bdisp_PutDisp_DD().
|
||||||
|
|
||||||
|
If triple buffering is enabled (this is the default, and disabled only if
|
||||||
|
dvram() is used to setup double buffering instead), it also swaps buffers.
|
||||||
|
Also waits for the previous dupdate() call to finish before executing. */
|
||||||
|
void dupdate(void);
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Area rendering functions
|
||||||
|
//---
|
||||||
|
|
||||||
|
/* dclear() - fill the screen with a single color
|
||||||
|
This function clears the screen by painting all the pixels in a single,
|
||||||
|
opaque color.
|
||||||
|
|
||||||
|
@color Any R5G6B5 color */
|
||||||
|
void dclear(uint16_t color);
|
||||||
|
|
||||||
|
/* drect() - fill a rectangle of the screen
|
||||||
|
This functions paints a rectangle in an opaque color. The endpoints (x1 y1)
|
||||||
|
and (x2 y2) are included in the rectangle.
|
||||||
|
|
||||||
|
@x1 @y1 @x2 @y2 Bounding rectangle (drawn area).
|
||||||
|
@color Any R5G6B5 color */
|
||||||
|
void drect(int x1, int y1, int x2, int y2, uint16_t color);
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Point drawing functions
|
||||||
|
//---
|
||||||
|
|
||||||
|
/* dpixel() - change a pixel's color
|
||||||
|
Paints the selected pixel with an opaque color. Setting pixels individually
|
||||||
|
is a slow method for rendering. Other functions that draw lines, rectangles,
|
||||||
|
images or text will take advantage of possible optimizations to make the
|
||||||
|
rendering faster: check them out first.
|
||||||
|
|
||||||
|
@x @y Coordinates of the pixel to repaint
|
||||||
|
@color Any R5G6B5 color */
|
||||||
|
void dpixel(int x, int y, uint16_t color);
|
||||||
|
|
||||||
|
/* dline() - render a straight line
|
||||||
|
This function draws a line using a Bresenham-style algorithm. Please note
|
||||||
|
that the affected pixels may not be exactly the same when using dline() and
|
||||||
|
Bdisp algorithms.
|
||||||
|
|
||||||
|
dline() has optimization facilities for horizontal and vertical lines. The
|
||||||
|
first kind is about twice as fast, while the second avoids some computation
|
||||||
|
(the optimization gain is not as significant as on fx9860g). dline() is not
|
||||||
|
able to clip the line without calculating all the pixels, so drawing a line
|
||||||
|
from (-1e6,0) to (1e6,395) will work, but will be veeery slow.
|
||||||
|
|
||||||
|
@x1 @y1 @x2 @y2 End points of the line (both included).
|
||||||
|
@color Any R5G6B5 color */
|
||||||
|
void dline(int x1, int y1, int x2, int y2, uint16_t color);
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Image rendering (bopti)
|
||||||
|
//---
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Text rendering (topti)
|
||||||
|
//---
|
||||||
|
|
||||||
typedef void font_t;
|
typedef void font_t;
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,15 @@
|
||||||
|
|
||||||
#include <gint/defs/types.h>
|
#include <gint/defs/types.h>
|
||||||
|
|
||||||
|
/* Expose the VRAM variable if GINT_NEED_VRAM is defined. It must always point
|
||||||
|
to a 4-aligned buffer of size 1024. Any function can use it freely to:
|
||||||
|
- Use another video ram area (triple buffering or more, gray engine);
|
||||||
|
- Implement additional drawing functions;
|
||||||
|
- Store data when not drawing. */
|
||||||
|
#ifdef GINT_NEED_VRAM
|
||||||
|
extern uint32_t *vram;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* color_t - colors available for drawing
|
/* color_t - colors available for drawing
|
||||||
The following colors are defined by the library:
|
The following colors are defined by the library:
|
||||||
|
|
||||||
|
@ -50,9 +59,9 @@ typedef enum
|
||||||
// Area drawing functions
|
// Area drawing functions
|
||||||
//---
|
//---
|
||||||
|
|
||||||
/* dupdate() - pushes the video RAM to the display driver
|
/* dupdate() - push the video RAM to the display driver
|
||||||
This function makes the contents of the VRAM visible on the screen. It is
|
This function makes the contents of the VRAM visible on the screen. It is
|
||||||
the direct equivalent of Bdisp_PutDisp_DD() */
|
the direct equivalent of Bdisp_PutDisp_DD(). */
|
||||||
void dupdate(void);
|
void dupdate(void);
|
||||||
|
|
||||||
/* dclear() - fill the screen with a single color
|
/* dclear() - fill the screen with a single color
|
||||||
|
@ -100,7 +109,7 @@ void dpixel(int x, int y, color_t color);
|
||||||
void dline(int x1, int y1, int x2, int y2, color_t color);
|
void dline(int x1, int y1, int x2, int y2, color_t color);
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Image rendering (bopti)
|
// Image rendering (bopti)
|
||||||
//---
|
//---
|
||||||
|
|
||||||
/* image_t - image files encoded for bopti
|
/* image_t - image files encoded for bopti
|
||||||
|
@ -126,7 +135,7 @@ typedef struct
|
||||||
} GPACKED(4) image_t;
|
} GPACKED(4) image_t;
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Text rendering (topti)
|
// Text rendering (topti)
|
||||||
//---
|
//---
|
||||||
|
|
||||||
/* font_t - font data encoded for topti */
|
/* font_t - font data encoded for topti */
|
||||||
|
|
|
@ -7,21 +7,6 @@
|
||||||
|
|
||||||
#include <gint/defs/types.h>
|
#include <gint/defs/types.h>
|
||||||
|
|
||||||
/* Expose the VRAM variable if GINT_NEED_VRAM is defined. This address is used
|
|
||||||
as the VRAM basis by all of gint's drawing functions, and must point to a
|
|
||||||
suitable buffer:
|
|
||||||
[fx9860g] A 4-aligned buffer of size 1024.
|
|
||||||
[fxcg50] A 4-aligned buffer of size 177408.
|
|
||||||
|
|
||||||
This variable is primarily meant to be exposed to gint functions, but
|
|
||||||
add-ins may use it or change it freely:
|
|
||||||
- To use another video ram area (triple buffering or more, gray engine);
|
|
||||||
- To implement additional drawing functions;
|
|
||||||
- When not drawing, as additional RAM (especially on fxcg50). */
|
|
||||||
#ifdef GINT_NEED_VRAM
|
|
||||||
extern uint32_t *vram;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* As you would expect, display on fx9860g and display on fxcg50 are completely
|
/* As you would expect, display on fx9860g and display on fxcg50 are completely
|
||||||
different worlds. As a consequence, so are the rendering functions ^^ */
|
different worlds. As a consequence, so are the rendering functions ^^ */
|
||||||
|
|
||||||
|
@ -33,10 +18,7 @@ extern uint32_t *vram;
|
||||||
#include <gint/display-cg.h>
|
#include <gint/display-cg.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//---
|
#if 0
|
||||||
// Parameter access
|
|
||||||
//---
|
|
||||||
|
|
||||||
/* dinfo_t - summary of information provided by this module */
|
/* dinfo_t - summary of information provided by this module */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -56,5 +38,6 @@ typedef struct
|
||||||
|
|
||||||
@info Pointer to allocated dinfo_t structure, will be filled. */
|
@info Pointer to allocated dinfo_t structure, will be filled. */
|
||||||
void dinfo(dinfo_t *info);
|
void dinfo(dinfo_t *info);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* GINT_DISPLAY */
|
#endif /* GINT_DISPLAY */
|
||||||
|
|
|
@ -121,7 +121,7 @@ void r61524_win_set(uint16_t HSA, uint16_t HEA, uint16_t VSA, uint16_t VEA)
|
||||||
// Driver functions
|
// Driver functions
|
||||||
//---
|
//---
|
||||||
|
|
||||||
void r61524_test(void)
|
/* void r61524_test(void)
|
||||||
{
|
{
|
||||||
uint16_t device_name;
|
uint16_t device_name;
|
||||||
uint16_t doc;
|
uint16_t doc;
|
||||||
|
@ -198,34 +198,15 @@ void r61524_test(void)
|
||||||
|
|
||||||
Bdisp_PutDisp_DD();
|
Bdisp_PutDisp_DD();
|
||||||
getkey();
|
getkey();
|
||||||
|
} */
|
||||||
|
|
||||||
/* Bdisp_AllClr_VRAM();
|
/* TODO: r61524: update, backlight, brightness, gamma */
|
||||||
print(1, 1, "MSTPCR0=????????");
|
|
||||||
print_hex(9, 1, POWER.MSTPCR0.lword, 8);
|
|
||||||
|
|
||||||
print(1, 2, "DMAOR=????");
|
void r61524_display(uint16_t *vram, int start, int height)
|
||||||
print_hex(7, 2, DMA.OR.word, 4);
|
|
||||||
|
|
||||||
print(1, 3, "SAR=????????");
|
|
||||||
print_hex(5, 3, DMA.DMA0.SAR, 8);
|
|
||||||
print(1, 4, "DAR=????????");
|
|
||||||
print_hex(5, 4, DMA.DMA0.DAR, 8);
|
|
||||||
print(1, 5, "TCR=????????");
|
|
||||||
print_hex(5, 5, DMA.DMA0.TCR, 8);
|
|
||||||
print(1, 6, "CHCR=????????");
|
|
||||||
print_hex(6, 6, DMA.DMA0.CHCR, 8);
|
|
||||||
|
|
||||||
Bdisp_PutDisp_DD();
|
|
||||||
getkey(); */
|
|
||||||
}
|
|
||||||
|
|
||||||
void r61524_dma_test(uint16_t *vram)
|
|
||||||
{
|
{
|
||||||
int y1 = 0;
|
|
||||||
int height = 224;
|
|
||||||
|
|
||||||
/* Move the window to the desired region, then select address 0 */
|
/* Move the window to the desired region, then select address 0 */
|
||||||
r61524_win_set(0, 395, y1, y1 + height - 1);
|
r61524_win_set(0, 395, start, start + height - 1);
|
||||||
select(ram_address_horizontal);
|
select(ram_address_horizontal);
|
||||||
write(0);
|
write(0);
|
||||||
select(ram_address_vertical);
|
select(ram_address_vertical);
|
||||||
|
@ -234,15 +215,17 @@ void r61524_dma_test(uint16_t *vram)
|
||||||
/* Bind address 0xb4000000 to the data write command */
|
/* Bind address 0xb4000000 to the data write command */
|
||||||
select(write_data);
|
select(write_data);
|
||||||
|
|
||||||
void *src = vram;
|
void *src = vram + 396 * start;
|
||||||
void *dst = (void *)0xb4000000;
|
void *dst = (void *)0xb4000000;
|
||||||
|
|
||||||
/* The thing is, 396 is not a multiple of 32.
|
/* The amount of data sent per row, 396*2, is not a multiple of 32. For
|
||||||
To make things simple, we can choose to always send a multiple of 8
|
now I assume [height] is a multiple of 4, which makes the factor 32
|
||||||
rows, which makes the 32 factor appear. */
|
appear. */
|
||||||
int blocks = 198 * (height >> 3);
|
int blocks = 99 * (height >> 2);
|
||||||
|
|
||||||
|
/* Now roll! */
|
||||||
dma_transfer(DMA_32B, blocks, src, DMA_INC, dst, DMA_FIXED);
|
dma_transfer(DMA_32B, blocks, src, DMA_INC, dst, DMA_FIXED);
|
||||||
|
/* Wait for any previous DMA transfer to finish */
|
||||||
dma_transfer_wait();
|
dma_transfer_wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +262,7 @@ static void ctx_restore(void *buf)
|
||||||
#ifdef GINT_BOOT_LOG
|
#ifdef GINT_BOOT_LOG
|
||||||
|
|
||||||
/* r6524_status() - status string */
|
/* r6524_status() - status string */
|
||||||
static const char *r6524_status(void)
|
static const char *r61524_status(void)
|
||||||
{
|
{
|
||||||
select(device_code_read);
|
select(device_code_read);
|
||||||
uint16_t dev = read();
|
uint16_t dev = read();
|
||||||
|
@ -298,7 +281,7 @@ static const char *r6524_status(void)
|
||||||
gint_driver_t drv_r61524 = {
|
gint_driver_t drv_r61524 = {
|
||||||
.name = "R61524",
|
.name = "R61524",
|
||||||
.init = NULL,
|
.init = NULL,
|
||||||
.status = GINT_DRIVER_STATUS(r6524_status),
|
.status = GINT_DRIVER_STATUS(r61524_status),
|
||||||
.ctx_size = sizeof(ctx_t),
|
.ctx_size = sizeof(ctx_t),
|
||||||
.sys_ctx = &sys_ctx,
|
.sys_ctx = &sys_ctx,
|
||||||
.ctx_save = ctx_save,
|
.ctx_save = ctx_save,
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
#define GINT_NEED_VRAM
|
||||||
|
#include <gint/display.h>
|
||||||
|
|
||||||
|
/* dclear() - fill the screen with a single color */
|
||||||
|
void dclear(uint16_t color)
|
||||||
|
{
|
||||||
|
/* TOOD: render-cg: dclear(): Consider using the DMA */
|
||||||
|
|
||||||
|
/* Operate in longwords to clear faster. Also start at the end of the
|
||||||
|
VRAM to take advantage of pre-decrement writes. */
|
||||||
|
uint32_t *v = (void *)(vram + 88704);
|
||||||
|
uint32_t op = (color << 16) | color;
|
||||||
|
|
||||||
|
/* Split the VRAM into 2772 blocks of 16 longwords to reduce the
|
||||||
|
overhead of the loop */
|
||||||
|
for(int blocks = 2772; blocks; blocks--)
|
||||||
|
{
|
||||||
|
*--v = op;
|
||||||
|
*--v = op;
|
||||||
|
*--v = op;
|
||||||
|
*--v = op;
|
||||||
|
|
||||||
|
*--v = op;
|
||||||
|
*--v = op;
|
||||||
|
*--v = op;
|
||||||
|
*--v = op;
|
||||||
|
|
||||||
|
*--v = op;
|
||||||
|
*--v = op;
|
||||||
|
*--v = op;
|
||||||
|
*--v = op;
|
||||||
|
|
||||||
|
*--v = op;
|
||||||
|
*--v = op;
|
||||||
|
*--v = op;
|
||||||
|
*--v = op;
|
||||||
|
}
|
||||||
|
}
|
107
src/render-cg/dline.c
Normal file
107
src/render-cg/dline.c
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
#define GINT_NEED_VRAM
|
||||||
|
#include <gint/defs/util.h>
|
||||||
|
#include <gint/display.h>
|
||||||
|
|
||||||
|
/* dhline() - optimized drawing of a horizontal line
|
||||||
|
@x1 @x2 @y Coordinates of endpoints of line (both included)
|
||||||
|
@color Any R5G6B5 color */
|
||||||
|
static void dhline(int x1, int x2, int y, uint16_t color)
|
||||||
|
{
|
||||||
|
/* Order and bounds */
|
||||||
|
if((uint)y >= 224) return;
|
||||||
|
if(x1 > x2) swap(x1, x2);
|
||||||
|
if(x1 < 0) x1 = 0;
|
||||||
|
if(x2 >= 396) x2 = 395;
|
||||||
|
|
||||||
|
int offset = 396 * y;
|
||||||
|
|
||||||
|
/* Use longwords to do the copy, but first paint the endpoints to heed
|
||||||
|
for odd x1 and x2. Checking the parity may be a waste of time. */
|
||||||
|
vram[offset + x1] = color;
|
||||||
|
vram[offset + x2] = color;
|
||||||
|
|
||||||
|
/* Now round to longword boundaries and copy everything in-between with
|
||||||
|
longwords */
|
||||||
|
x1 = x1 + (x1 & 1);
|
||||||
|
x2 = (x2 + 1) & ~1;
|
||||||
|
|
||||||
|
uint32_t *start = (void *)(vram + offset + x1);
|
||||||
|
uint32_t *end = (void *)(vram + offset + x2);
|
||||||
|
uint32_t op = (color << 16) | color;
|
||||||
|
|
||||||
|
while(end > start) *--end = op;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dvline() - optimized drawing of a vertical line
|
||||||
|
@y1 @y2 @x Coordinates of endpoints of line (both included)
|
||||||
|
@color Any R5G6B5 color */
|
||||||
|
static void dvline(int y1, int y2, int x, uint16_t color)
|
||||||
|
{
|
||||||
|
/* Order and bounds */
|
||||||
|
if((uint)x >= 395) return;
|
||||||
|
if(y1 > y2) swap(y1, y2);
|
||||||
|
if(y1 < 0) y1 = 0;
|
||||||
|
if(y2 >= 224) y2 = 223;
|
||||||
|
|
||||||
|
uint16_t *v = vram + 396 * y1 + x;
|
||||||
|
int height = y2 - y1 + 1;
|
||||||
|
|
||||||
|
while(height--) *v = color, v += 396;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dline() - Bresenham line drawing algorithm
|
||||||
|
Remotely adapted from MonochromeLib code by Pierre "PerriotLL" Le Gall.
|
||||||
|
Relies on dhline() and dvline() for optimized situations.
|
||||||
|
@x1 @y1 @x2 @y2 Coordinates of endpoints of line (included)
|
||||||
|
@color Any R5G6B5 color */
|
||||||
|
void dline(int x1, int y1, int x2, int y2, uint16_t color)
|
||||||
|
{
|
||||||
|
/* Possible optimizations */
|
||||||
|
if(y1 == y2)
|
||||||
|
{
|
||||||
|
dhline(x1, x2, y1, color);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(x1 == x2)
|
||||||
|
{
|
||||||
|
dvline(y1, y2, x1, color);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Brensenham line drawing algorithm */
|
||||||
|
|
||||||
|
int i, x = x1, y = y1, cumul;
|
||||||
|
int dx = x2 - x1, dy = y2 - y1;
|
||||||
|
int sx = sgn(dx), sy = sgn(dy);
|
||||||
|
|
||||||
|
dx = abs(dx), dy = abs(dy);
|
||||||
|
|
||||||
|
dpixel(x1, y1, color);
|
||||||
|
|
||||||
|
if(dx >= dy)
|
||||||
|
{
|
||||||
|
/* Start with a non-zero cumul to even the overdue between the
|
||||||
|
two ends of the line (for more regularity) */
|
||||||
|
cumul = dx >> 1;
|
||||||
|
for(i = 1; i < dx; i++)
|
||||||
|
{
|
||||||
|
x += sx;
|
||||||
|
cumul += dy;
|
||||||
|
if(cumul > dx) cumul -= dx, y += sy;
|
||||||
|
dpixel(x, y, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cumul = dy >> 1;
|
||||||
|
for(i = 1; i < dy; i++)
|
||||||
|
{
|
||||||
|
y += sy;
|
||||||
|
cumul += dx;
|
||||||
|
if(cumul > dy) cumul -= dy, x += sx;
|
||||||
|
dpixel(x, y, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dpixel(x2, y2, color);
|
||||||
|
}
|
11
src/render-cg/dpixel.c
Normal file
11
src/render-cg/dpixel.c
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#define GINT_NEED_VRAM
|
||||||
|
#include <gint/display.h>
|
||||||
|
|
||||||
|
/* dpixel() - change a pixel's color */
|
||||||
|
void dpixel(int x, int y, uint16_t color)
|
||||||
|
{
|
||||||
|
/* Coordinate checks */
|
||||||
|
if((uint)x >= 396 || (uint)y >= 224) return;
|
||||||
|
|
||||||
|
vram[396 * y + x] = color;
|
||||||
|
}
|
59
src/render-cg/drect.c
Normal file
59
src/render-cg/drect.c
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#define GINT_NEED_VRAM
|
||||||
|
#include <gint/defs/util.h>
|
||||||
|
#include <gint/display.h>
|
||||||
|
|
||||||
|
/* drect() - fill a rectangle of the screen */
|
||||||
|
void drect(int x1, int y1, int x2, int y2, uint16_t color)
|
||||||
|
{
|
||||||
|
if(x1 > x2) swap(x1, x2);
|
||||||
|
if(y1 > y2) swap(y1, y2);
|
||||||
|
|
||||||
|
/* Order and bounds */
|
||||||
|
if(x1 >= 396 || x2 < 0 || y1 >= 224 || y2 < 0) return;
|
||||||
|
if(x1 < 0) x1 = 0;
|
||||||
|
if(x2 >= 396) x2 = 395;
|
||||||
|
if(y1 < 0) y1 = 0;
|
||||||
|
if(y2 >= 224) y2 = 223;
|
||||||
|
|
||||||
|
/* The method is exactly like dhline(). I first handle odd endpoints,
|
||||||
|
then write longwords for the longest section */
|
||||||
|
|
||||||
|
uint16_t *base = vram + 396 * y1;
|
||||||
|
int height = y2 - y1 + 1;
|
||||||
|
|
||||||
|
/* Do borders first if there are at an odd position */
|
||||||
|
|
||||||
|
if(x1 & 1)
|
||||||
|
{
|
||||||
|
uint16_t *v = base;
|
||||||
|
for(int h = height; h; h--)
|
||||||
|
{
|
||||||
|
v[x1] = color;
|
||||||
|
v += 396;
|
||||||
|
}
|
||||||
|
x1++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(x2 & 1) x2++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint16_t *v = base;
|
||||||
|
for(int h = height; h; h--)
|
||||||
|
{
|
||||||
|
v[x2] = color;
|
||||||
|
v += 396;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now copy everything that's left as longwords */
|
||||||
|
|
||||||
|
uint32_t *v = (void *)(base + x1);
|
||||||
|
uint32_t op = (color << 16) | color;
|
||||||
|
int width = (x2 - x1) >> 1;
|
||||||
|
|
||||||
|
for(int h = height; h; h--)
|
||||||
|
{
|
||||||
|
for(int w = 0; w < width; w++) v[w] = op;
|
||||||
|
v += 198;
|
||||||
|
}
|
||||||
|
}
|
9
src/render-cg/dupdate.c
Normal file
9
src/render-cg/dupdate.c
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#define GINT_NEED_VRAM
|
||||||
|
#include <gint/display.h>
|
||||||
|
//#include <gint/drivers/r61524.h>
|
||||||
|
|
||||||
|
/* dupdate() - push the video RAM to the display driver */
|
||||||
|
void dupdate(void)
|
||||||
|
{
|
||||||
|
r61524_display(vram, 0, 224);
|
||||||
|
}
|
16
src/render-cg/dvram.c
Normal file
16
src/render-cg/dvram.c
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#define GINT_NEED_VRAM
|
||||||
|
#include <gint/display.h>
|
||||||
|
|
||||||
|
/* Put both VRAMs in the system stack! */
|
||||||
|
static uint16_t *main = (void *)0xac0f0000;
|
||||||
|
static uint16_t *scnd = (void *)0xac11b500;
|
||||||
|
|
||||||
|
/* Shared VRAM pointer, the one exposed by GINT_NEED_VRAM */
|
||||||
|
uint16_t *vram = (void *)0xac0f0000;
|
||||||
|
|
||||||
|
/* dvram() - Control video RAM address and triple buffering */
|
||||||
|
void dvram(uint16_t *new_main, uint16_t *new_secondary)
|
||||||
|
{
|
||||||
|
main = new_main;
|
||||||
|
scnd = new_secondary;
|
||||||
|
}
|
|
@ -6,42 +6,37 @@
|
||||||
/* dhline() - optimized drawing of a horizontal line using a rectangle mask
|
/* dhline() - optimized drawing of a horizontal line using a rectangle mask
|
||||||
@x1 @x2 @y Coordinates of endpoints of line (both included)
|
@x1 @x2 @y Coordinates of endpoints of line (both included)
|
||||||
@color Allowed colors: white, black, none, reverse */
|
@color Allowed colors: white, black, none, reverse */
|
||||||
static void dhline(int x1, int x2, int y, color_t color)
|
void dhline(int x1, int x2, int y, color_t color)
|
||||||
{
|
{
|
||||||
if((uint)y >= 64) return;
|
if((uint)y >= 64) return;
|
||||||
if(x1 > x2) swap(x1, x2);
|
if(x1 > x2) swap(x1, x2);
|
||||||
|
|
||||||
uint32_t *lword = vram + (y << 2) + 4;
|
|
||||||
uint32_t m[4];
|
|
||||||
|
|
||||||
/* Get the masks for the [x1, x2] range */
|
/* Get the masks for the [x1, x2] range */
|
||||||
|
uint32_t m[4];
|
||||||
masks(x1, x2, m);
|
masks(x1, x2, m);
|
||||||
|
|
||||||
switch(color)
|
uint32_t *data = vram + (y << 2);
|
||||||
|
|
||||||
|
if(color == color_white)
|
||||||
{
|
{
|
||||||
case color_white:
|
data[0] &= ~m[0];
|
||||||
*--lword &= ~m[3];
|
data[1] &= ~m[1];
|
||||||
*--lword &= ~m[2];
|
data[2] &= ~m[2];
|
||||||
*--lword &= ~m[1];
|
data[3] &= ~m[3];
|
||||||
*--lword &= ~m[0];
|
}
|
||||||
break;
|
else if(color == color_black)
|
||||||
|
{
|
||||||
case color_black:
|
data[0] |= m[0];
|
||||||
*--lword |= m[3];
|
data[1] |= m[1];
|
||||||
*--lword |= m[2];
|
data[2] |= m[2];
|
||||||
*--lword |= m[1];
|
data[3] |= m[3];
|
||||||
*--lword |= m[0];
|
}
|
||||||
break;
|
else if(color == color_reverse)
|
||||||
|
{
|
||||||
case color_reverse:
|
data[0] ^= m[0];
|
||||||
*--lword ^= m[3];
|
data[1] ^= m[1];
|
||||||
*--lword ^= m[2];
|
data[2] ^= m[2];
|
||||||
*--lword ^= m[1];
|
data[3] ^= m[3];
|
||||||
*--lword ^= m[0];
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +45,7 @@ static void dhline(int x1, int x2, int y, color_t color)
|
||||||
of the vram cannot be used here.
|
of the vram cannot be used here.
|
||||||
@y1 @y2 @x Coordinates of endpoints of line (both included)
|
@y1 @y2 @x Coordinates of endpoints of line (both included)
|
||||||
@color Allowed colors: black, white, none, reverse */
|
@color Allowed colors: black, white, none, reverse */
|
||||||
static void dvline(int y1, int y2, int x, color_t operator)
|
void dvline(int y1, int y2, int x, color_t operator)
|
||||||
{
|
{
|
||||||
if((uint)x >= 128) return;
|
if((uint)x >= 128) return;
|
||||||
if(y1 > y2) swap(y1, y2);
|
if(y1 > y2) swap(y1, y2);
|
||||||
|
|
|
@ -8,7 +8,7 @@ GSECTION(".bss") static uint32_t fx_vram[256];
|
||||||
/* Here is the definition of the VRAM pointer */
|
/* Here is the definition of the VRAM pointer */
|
||||||
GDATA uint32_t *vram = fx_vram;
|
GDATA uint32_t *vram = fx_vram;
|
||||||
|
|
||||||
/* dupdate() - pushes the video RAM to the display driver */
|
/* dupdate() - push the video RAM to the display driver */
|
||||||
void dupdate(void)
|
void dupdate(void)
|
||||||
{
|
{
|
||||||
t6k11_display(vram, 0, 64, 16);
|
t6k11_display(vram, 0, 64, 16);
|
||||||
|
|
Loading…
Reference in a new issue