forked from Lephenixnoir/gint
[WIP] - conversion of the gray scale engine to the CG for fx_as_cg build target - compiling - linking _ but ony B&W yet
This commit is contained in:
parent
469be10609
commit
a41c44988b
|
@ -243,7 +243,7 @@ set(SOURCES_CG
|
|||
|
||||
set(SOURCES_FXASCG
|
||||
# Gray engine
|
||||
src/gray/engine.c
|
||||
src/gray/engine_fxascg.c
|
||||
src/gray/gclear.c
|
||||
src/gray/ggetpixel.c
|
||||
src/gray/gint_gline.c
|
||||
|
|
|
@ -0,0 +1,353 @@
|
|||
//---
|
||||
// gint:gray:engine - Core gray engine
|
||||
//---
|
||||
|
||||
#include <gint/defs/types.h>
|
||||
#include <gint/drivers/r61524.h>
|
||||
#include <gint/gray.h>
|
||||
#include <gint/display.h>
|
||||
#include <gint/timer.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../render-fx/render-fx.h"
|
||||
|
||||
/* Three additional video RAMS, allocated statically if --static-gray was set
|
||||
at configure time, or with malloc() otherwise. */
|
||||
#ifdef GINT_STATIC_GRAY
|
||||
GBSS static uint32_t gvrams[3][256];
|
||||
#endif
|
||||
|
||||
uint16_t *cg_vram_gray;
|
||||
|
||||
/* Four VRAMs: two to draw and two to display */
|
||||
static uint32_t *vrams[4] = { NULL, NULL, NULL, NULL };
|
||||
|
||||
/* Current VRAM pair used for drawing; the value can either be 0 (draws to
|
||||
VRAMs 0 and 1) or 2 (draws to VRAMs 2 and 3). */
|
||||
static int volatile st = 0;
|
||||
/* Timer ID, always equal to GRAY_TIMER except if initialization fails */
|
||||
static int timer = -1;
|
||||
/* Whether the engine is scheduled to run at the next frame */
|
||||
static int runs = 0;
|
||||
|
||||
/* Underlying timer, set to count at P_phi/64 */
|
||||
#define GRAY_TIMER 0
|
||||
#define GRAY_CLOCK TIMER_Pphi_64
|
||||
/* Delays of the light and dark frames for the above setting */
|
||||
GBSS static int delays[2];
|
||||
|
||||
/* The alternate rendering mode structure used to override d*() */
|
||||
static struct rendering_mode const gray_mode = {
|
||||
.dupdate = gupdate,
|
||||
.dclear = gclear,
|
||||
.drect = grect,
|
||||
.dpixel = gpixel,
|
||||
.dgetpixel = ggetpixel,
|
||||
.gint_dhline = gint_ghline,
|
||||
.gint_dvline = gint_gvline,
|
||||
.dtext_opt = gtext_opt,
|
||||
.dsubimage = gsubimage,
|
||||
};
|
||||
static struct rendering_mode const gray_exit_mode = {
|
||||
.dupdate = gupdate,
|
||||
.dclear = NULL,
|
||||
.drect = NULL,
|
||||
.dpixel = NULL,
|
||||
.dgetpixel = NULL,
|
||||
.gint_dhline = NULL,
|
||||
.gint_dvline = NULL,
|
||||
.dtext_opt = NULL,
|
||||
.dsubimage = NULL,
|
||||
};
|
||||
|
||||
//---
|
||||
// Engine control (init/quit and start/stop)
|
||||
//---
|
||||
|
||||
static int gray_int(void);
|
||||
static void gray_quit(void);
|
||||
|
||||
/* gray_isinit(): Check whether the engine is initialized and ready to run */
|
||||
static int gray_isinit(void)
|
||||
{
|
||||
return (vrams[0] && vrams[1] && vrams[2] && vrams[3] && timer >= 0);
|
||||
}
|
||||
|
||||
|
||||
bool dvram_init_gray( void )
|
||||
{
|
||||
int const MARGIN = 32;
|
||||
|
||||
/* Leave MARGIN bytes on each side of the region; this enables some
|
||||
important optimizations in the image renderer. We also add another
|
||||
32 bytes so we can manually 32-align the region */
|
||||
uint32_t region = (uint32_t)kmalloc(DWIDTH*DHEIGHT*2 + MARGIN*2 + 32,
|
||||
#if !defined(GINT_NO_OS_STACK)
|
||||
"_ostk"
|
||||
#else
|
||||
NULL
|
||||
#endif
|
||||
);
|
||||
if(region == 0)
|
||||
return false;
|
||||
|
||||
/* 32-align the region */
|
||||
region = (region + 31) & -32;
|
||||
/* Skip a MARGIN */
|
||||
region += MARGIN;
|
||||
/* Use an uncached address */
|
||||
region = (region & 0x1fffffff) | 0xa0000000;
|
||||
|
||||
/* Don't enable triple buffering by default */
|
||||
cg_vram_gray = (void *)region;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* gray_init(): Initialize the engine
|
||||
This is done at startup so that memory can be reserved very early from the
|
||||
heap (because not having enough memory is unrecoverable for the engine). */
|
||||
GCONSTRUCTOR static void gray_init(void)
|
||||
{
|
||||
/* We need four VRAMs. First use the standard monochrome one */
|
||||
vrams[0] = gint_vram;
|
||||
|
||||
#ifdef GINT_STATIC_GRAY
|
||||
vrams[1] = gvrams[0];
|
||||
vrams[2] = gvrams[1];
|
||||
vrams[3] = gvrams[2];
|
||||
#else
|
||||
vrams[1] = malloc(1024);
|
||||
vrams[2] = malloc(1024);
|
||||
vrams[3] = malloc(1024);
|
||||
#endif /* GINT_STATIC_GRAY */
|
||||
|
||||
/* Default delays from Graph 35+E II are different from other models */
|
||||
if(gint[HWCALC] == HWCALC_G35PE2)
|
||||
{
|
||||
delays[0] = 762;
|
||||
delays[1] = 1311;
|
||||
}
|
||||
else
|
||||
{
|
||||
delays[0] = 923;
|
||||
delays[1] = 1742;
|
||||
}
|
||||
|
||||
dvram_init_gray();
|
||||
|
||||
/* Try to obtain the timer right away */
|
||||
timer = timer_configure(GRAY_TIMER | GRAY_CLOCK, 1000,
|
||||
GINT_CALL(gray_int));
|
||||
|
||||
/* On failure, release the resources that we obtained */
|
||||
if(!gray_isinit()) gray_quit();
|
||||
}
|
||||
|
||||
/* gray_quit(): Free engine resources */
|
||||
GDESTRUCTOR static void gray_quit(void)
|
||||
{
|
||||
#ifndef GINT_STATIC_GRAY
|
||||
if(vrams[1]) free(vrams[1]);
|
||||
if(vrams[2]) free(vrams[2]);
|
||||
if(vrams[3]) free(vrams[3]);
|
||||
|
||||
vrams[1] = NULL;
|
||||
vrams[2] = NULL;
|
||||
vrams[3] = NULL;
|
||||
#endif /* GINT_STATIC_GRAY */
|
||||
|
||||
if(timer >= 0) timer_stop(timer);
|
||||
timer = -1;
|
||||
}
|
||||
|
||||
/* gray_start(): Start the gray engine */
|
||||
static void gray_start(void)
|
||||
{
|
||||
st = 2;
|
||||
timer_reload(GRAY_TIMER, delays[0]);
|
||||
timer_start(GRAY_TIMER);
|
||||
runs = 1;
|
||||
}
|
||||
|
||||
/* gray_stop(): Stop the gray engine */
|
||||
static void gray_stop(void)
|
||||
{
|
||||
timer_pause(GRAY_TIMER);
|
||||
runs = 0;
|
||||
st = 0;
|
||||
}
|
||||
|
||||
//---
|
||||
// Dynamic udpate and rendering mode
|
||||
//---
|
||||
|
||||
/* dgray(): Start or stop the gray engine at the next dupdate() */
|
||||
int dgray(int mode)
|
||||
{
|
||||
/* Stack of states for the push modes */
|
||||
static uint8_t states[32] = { 0 };
|
||||
static uint8_t current = 0;
|
||||
|
||||
if(mode == DGRAY_ON)
|
||||
{
|
||||
if(!gray_isinit()) return 1;
|
||||
|
||||
/* Set the display module's alternate rendering mode to
|
||||
override rendering functions to use their g*() variant */
|
||||
if(!dgray_enabled()) dmode = &gray_mode;
|
||||
}
|
||||
else if(mode == DGRAY_OFF)
|
||||
{
|
||||
/* Set the mode to a temporary one that only overrides
|
||||
dupdate() so that we can stop the engine next frame */
|
||||
if(dgray_enabled()) dmode = &gray_exit_mode;
|
||||
}
|
||||
else if(mode == DGRAY_PUSH_ON)
|
||||
{
|
||||
if(current >= 32) return 1;
|
||||
states[current++] = dgray_enabled() ? DGRAY_ON : DGRAY_OFF;
|
||||
|
||||
return dgray(DGRAY_ON);
|
||||
}
|
||||
else if(mode == DGRAY_PUSH_OFF)
|
||||
{
|
||||
if(current >= 32) return 1;
|
||||
states[current++] = dgray_enabled() ? DGRAY_ON : DGRAY_OFF;
|
||||
|
||||
return dgray(DGRAY_OFF);
|
||||
}
|
||||
else if(mode == DGRAY_POP)
|
||||
{
|
||||
/* Stay at 0 if the user's push/pop logic is broken */
|
||||
if(current > 0) current--;
|
||||
|
||||
/* Switch to previous state */
|
||||
return dgray(states[current]);
|
||||
}
|
||||
else return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define C_RGB(r,g,b) (((r) << 11) | ((g) << 6) | (b))
|
||||
|
||||
|
||||
inline gdrawupscale( int x, int y, int color )
|
||||
{
|
||||
int u=y*396*3;
|
||||
int v=x*3;
|
||||
|
||||
uint16_t colorcg;
|
||||
|
||||
if (color==C_WHITE) colorcg=0xFFFF;
|
||||
else if (color==C_LIGHT) colorcg=C_RGB(20,20,20);
|
||||
else if (color==C_DARK) colorcg=C_RGB(10,10,10);
|
||||
else colorcg=0x0000;
|
||||
|
||||
int baseindex = (396*16+6+v+u); // 16 lines on top/bottom remain black and 6 columns on left/right remain black
|
||||
cg_vram_gray[baseindex] = colorcg;
|
||||
cg_vram_gray[baseindex+1] = colorcg;
|
||||
cg_vram_gray[baseindex+2] = colorcg;
|
||||
|
||||
baseindex+=396;
|
||||
cg_vram_gray[baseindex] = colorcg;
|
||||
cg_vram_gray[baseindex+1] = colorcg;
|
||||
cg_vram_gray[baseindex+2] = colorcg;
|
||||
|
||||
baseindex+=396;
|
||||
cg_vram_gray[baseindex] = colorcg;
|
||||
cg_vram_gray[baseindex+1] = colorcg;
|
||||
cg_vram_gray[baseindex+2] = colorcg;
|
||||
}
|
||||
|
||||
|
||||
/* gray_int(): Interrupt handler */
|
||||
int gray_int(void)
|
||||
{
|
||||
//t6k11_display(vrams[st ^ 2], 0, 64, 16);
|
||||
timer_reload(GRAY_TIMER, delays[(st ^ 3) & 1]);
|
||||
|
||||
st ^= 1;
|
||||
|
||||
return TIMER_CONTINUE;
|
||||
}
|
||||
|
||||
/* gupdate(): Push the current VRAMs to the screen */
|
||||
int gupdate(void)
|
||||
{
|
||||
/* At the first gupdate(), start the engine */
|
||||
if(dmode == &gray_mode && !runs)
|
||||
{
|
||||
gray_start();
|
||||
return 0;
|
||||
}
|
||||
/* At the last gupdate(), stop the engine */
|
||||
if(dmode == &gray_exit_mode)
|
||||
{
|
||||
gray_stop();
|
||||
dmode = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for( int j=0; j<DHEIGHT; j++ ) // 64 lines
|
||||
{
|
||||
for( int i=0; i<DWIDTH; i++ ) // 128 column
|
||||
{
|
||||
gdrawupscale( i, j, ggetpixel(i,j) ); // really not optimised; just to check if OK
|
||||
}
|
||||
}
|
||||
|
||||
r61524_display(cg_vram_gray, 0, 224, R61524_DMA_WAIT );
|
||||
|
||||
/* When the engine is running, swap frames */
|
||||
st ^= 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---
|
||||
// Query and configuration functions
|
||||
//---
|
||||
|
||||
/* dgray_enabled(): Check whether gray mode is enabled */
|
||||
int dgray_enabled(void)
|
||||
{
|
||||
return (dmode == &gray_mode);
|
||||
}
|
||||
|
||||
/* dgray_setdelays(): Set the gray engine delays */
|
||||
void dgray_setdelays(uint32_t light, uint32_t dark)
|
||||
{
|
||||
delays[0] = light;
|
||||
delays[1] = dark;
|
||||
}
|
||||
|
||||
/* dgray_getdelays(): Get the gray engine delays */
|
||||
void dgray_getdelays(uint32_t *light, uint32_t *dark)
|
||||
{
|
||||
if(light) *light = delays[0];
|
||||
if(dark) *dark = delays[1];
|
||||
}
|
||||
|
||||
/* dgray_getvram(): Get the current VRAM pointers */
|
||||
void dgray_getvram(uint32_t **light, uint32_t **dark)
|
||||
{
|
||||
int base = st;
|
||||
|
||||
if(light) *light = vrams[base & 2];
|
||||
if(dark) *dark = vrams[base | 1];
|
||||
}
|
||||
|
||||
/* dgray_getscreen(): Get the current screen pointers */
|
||||
void dgray_getscreen(uint32_t **light, uint32_t **dark)
|
||||
{
|
||||
int base = st ^ 2;
|
||||
|
||||
if(light) *light = vrams[base & 2];
|
||||
if(dark) *dark = vrams[base | 1];
|
||||
}
|
Loading…
Reference in New Issue