mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2025-01-11 10:49:07 +01:00
removed antialiasing (not working), rewrote video code
This commit is contained in:
parent
ef3f88e060
commit
fa769d6c0f
@ -4,7 +4,7 @@
|
||||
#include <fat.h>
|
||||
#include <sys/dir.h>
|
||||
|
||||
#define CONFIG_VERSION "GENPLUS 1.2.7 "
|
||||
#define CONFIG_VERSION "GENPLUS 1.2.8 "
|
||||
|
||||
t_config config;
|
||||
bool use_FAT;
|
||||
@ -87,10 +87,10 @@ void set_config_defaults(void)
|
||||
config.yscale = 0;
|
||||
config.aspect = 1;
|
||||
config.overscan = 1;
|
||||
config.render = (vmode->viTVMode == VI_TVMODE_NTSC_PROG) ? 2 : 0;
|
||||
config.render = VIDEO_HaveComponentCable() ? 2 : 0;
|
||||
config.ntsc = 0;
|
||||
config.filtering = 1;
|
||||
config.aa = 0;
|
||||
config.bilinear = 1;
|
||||
config.gxscaler = 2;
|
||||
|
||||
/* controllers options */
|
||||
ogc_input__set_defaults();
|
||||
|
@ -29,8 +29,8 @@ typedef struct
|
||||
uint8 overscan;
|
||||
uint8 render;
|
||||
uint8 ntsc;
|
||||
uint8 filtering;
|
||||
uint8 aa;
|
||||
uint8 gxscaler;
|
||||
uint8 bilinear;
|
||||
uint16 pad_keymap[4][MAX_KEYS];
|
||||
uint32 wpad_keymap[4*3][MAX_KEYS];
|
||||
t_input_config input[MAX_DEVICES];
|
||||
|
@ -322,7 +322,7 @@ void dispmenu ()
|
||||
|
||||
while (quit == 0)
|
||||
{
|
||||
ogc_video__scale();
|
||||
ogc_video__aspect();
|
||||
|
||||
sprintf (items[0], "Aspect: %s", config.aspect ? "ORIGINAL" : "STRETCH");
|
||||
if (config.render == 1) sprintf (items[1], "Render: INTERLACED");
|
||||
@ -331,9 +331,11 @@ void dispmenu ()
|
||||
if (config.tv_mode == 0) sprintf (items[2], "TV Mode: 60HZ");
|
||||
else if (config.tv_mode == 1) sprintf (items[2], "TV Mode: 50HZ");
|
||||
else sprintf (items[2], "TV Mode: 50/60HZ");
|
||||
sprintf (items[3], "Anti Aliasing: %s", config.aa ? " ON" : "OFF");
|
||||
sprintf (items[4], "GX Filter: %s", config.filtering ? " ON" : "OFF");
|
||||
if (config.ntsc == 1) sprintf (items[5], "NTSC Filter: COMPOSITE");
|
||||
sprintf (items[3], "GX Filter: %s", config.bilinear ? " ON" : "OFF");
|
||||
if (config.gxscaler == 1) sprintf (items[4], "GX Scaler: 2X");
|
||||
else if (config.gxscaler == 2)sprintf (items[4], "GX Scaler: FULL");
|
||||
else sprintf (items[4], "GX Scaler: OFF");
|
||||
if (config.ntsc == 1) sprintf (items[5], "NTSC Filter: COMPOSITE");
|
||||
else if (config.ntsc == 2) sprintf (items[5], "NTSC Filter: S-VIDEO");
|
||||
else if (config.ntsc == 3) sprintf (items[5], "NTSC Filter: RGB");
|
||||
else sprintf (items[5], "NTSC Filter: OFF");
|
||||
@ -341,7 +343,7 @@ void dispmenu ()
|
||||
sprintf (items[7], "Center X: %s%02d", config.xshift < 0 ? "-":"+", abs(config.xshift));
|
||||
sprintf (items[8], "Center Y: %s%02d", config.yshift < 0 ? "-":"+", abs(config.yshift));
|
||||
sprintf (items[9], "Scale X: %02d", xscale*2);
|
||||
sprintf (items[10], "Scale Y: %02d", yscale*2);
|
||||
sprintf (items[10], "Scale Y: %02d", yscale*4);
|
||||
|
||||
ret = domenu (&items[0], count, 1);
|
||||
|
||||
@ -375,16 +377,16 @@ void dispmenu ()
|
||||
config.tv_mode = (config.tv_mode + 1) % 3;
|
||||
break;
|
||||
|
||||
case 3: /*** antialiasing ***/
|
||||
config.aa ^= 1;
|
||||
break;
|
||||
|
||||
case 4: /*** bilinear filtering ***/
|
||||
config.filtering ^= 1;
|
||||
case 3: /*** bilinear filtering ***/
|
||||
config.bilinear ^= 1;
|
||||
bitmap.viewport.changed = 1;
|
||||
break;
|
||||
|
||||
case 5: /*** NTSC filter ***/
|
||||
case 4: /*** GX scaler ***/
|
||||
config.gxscaler = (config.gxscaler + 1) % 3;
|
||||
break;
|
||||
|
||||
case 5: /*** NTSC filter ***/
|
||||
config.ntsc ++;
|
||||
if (config.ntsc > 3) config.ntsc = 0;
|
||||
bitmap.viewport.changed = 1;
|
||||
@ -793,6 +795,22 @@ void optionmenu ()
|
||||
****************************************************************************/
|
||||
static u8 device = 0;
|
||||
|
||||
/****************************************************************************
|
||||
* fat_is_mounted
|
||||
* to check whether FAT media are detected.
|
||||
***************************************************************************/
|
||||
|
||||
bool FatIsMounted(PARTITION_INTERFACE partition) {
|
||||
char prefix[] = "fatX:/";
|
||||
prefix[3] = partition + '0';
|
||||
DIR_ITER *dir = diropen(prefix);
|
||||
if (dir) {
|
||||
dirclose(dir);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int loadsavemenu (int which)
|
||||
{
|
||||
int prevmenu = menu;
|
||||
@ -821,6 +839,9 @@ int loadsavemenu (int which)
|
||||
if (device == 0) sprintf(items[0], "Device: SDCARD");
|
||||
else if (device == 1) sprintf(items[0], "Device: MCARD A");
|
||||
else if (device == 2) sprintf(items[0], "Device: MCARD B");
|
||||
#ifdef HW_RVL
|
||||
else if (device == 3) sprintf(items[0], "Device: USB");
|
||||
#endif
|
||||
|
||||
ret = domenu (&items[0], count, 0);
|
||||
switch (ret)
|
||||
@ -830,11 +851,27 @@ int loadsavemenu (int which)
|
||||
break;
|
||||
|
||||
case 0:
|
||||
#ifdef HW_RVL
|
||||
device = (device + 1)%4;
|
||||
#else
|
||||
device = (device + 1)%3;
|
||||
break;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case 2:
|
||||
#ifdef HW_RVL
|
||||
if ((device == 0) || (device == 3))
|
||||
{
|
||||
PARTITION_INTERFACE dev = device ? PI_USBSTORAGE : PI_INTERNAL_SD;
|
||||
if (FatIsMounted(dev)) fatSetDefaultInterface(dev);
|
||||
else
|
||||
{
|
||||
WaitPrompt ("Device not found!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (which == 1) quit = ManageState(ret-1,device);
|
||||
else if (which == 0) quit = ManageSRAM(ret-1,device);
|
||||
if (quit) return 1;
|
||||
@ -896,11 +933,19 @@ void loadmenu ()
|
||||
{
|
||||
int ret;
|
||||
int quit = 0;
|
||||
int count = 4;
|
||||
char item[4][25] = {
|
||||
{"Load Recent"},
|
||||
#ifdef HW_RVL
|
||||
int count = 5;
|
||||
char item[5][25] = {
|
||||
#else
|
||||
int count = 5;
|
||||
char item[5][25] = {
|
||||
#endif
|
||||
{"Load Recent"},
|
||||
{"Load from SDCARD"},
|
||||
{"Load from DVD"},
|
||||
#ifdef HW_RVL
|
||||
{"Load from USB"},
|
||||
#endif
|
||||
{"Load from DVD"},
|
||||
{"Stop DVD Motor"}
|
||||
};
|
||||
|
||||
@ -921,14 +966,34 @@ void loadmenu ()
|
||||
break;
|
||||
|
||||
case 1: /*** Load from SCDARD ***/
|
||||
#ifdef HW_RVL
|
||||
case 2:
|
||||
{
|
||||
PARTITION_INTERFACE dev = (ret&2) ? PI_USBSTORAGE : PI_INTERNAL_SD;
|
||||
if (FatIsMounted(dev)) fatSetDefaultInterface(dev);
|
||||
else
|
||||
{
|
||||
WaitPrompt ("Device not found!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
quit = OpenSD();
|
||||
break;
|
||||
|
||||
case 2: /*** Load from DVD ***/
|
||||
quit = OpenDVD();
|
||||
#ifdef HW_RVL
|
||||
case 3: /*** Load from DVD ***/
|
||||
#else
|
||||
case 2:
|
||||
#endif
|
||||
quit = OpenDVD();
|
||||
break;
|
||||
|
||||
case 3: /*** Stop DVD Disc ***/
|
||||
#ifdef HW_RVL
|
||||
case 4: /*** Stop DVD Disc ***/
|
||||
#else
|
||||
case 3:
|
||||
#endif
|
||||
dvd_motor_off();
|
||||
break;
|
||||
}
|
||||
|
@ -31,6 +31,8 @@ md_ntsc_t md_ntsc;
|
||||
sms_ntsc_setup_t sms_setup;
|
||||
sms_ntsc_t sms_ntsc;
|
||||
|
||||
/* Aspect Ratio */
|
||||
int xscale, yscale, xshift, yshift;
|
||||
|
||||
/*** PAL 50hz flag ***/
|
||||
int gc_pal = 0;
|
||||
@ -353,6 +355,7 @@ static void framestart(u32 retraceCnt)
|
||||
frameticker++;
|
||||
}
|
||||
|
||||
/* Initialize GX */
|
||||
static void gxStart(void)
|
||||
{
|
||||
Mtx p;
|
||||
@ -388,34 +391,77 @@ static void gxStart(void)
|
||||
memset (texturemem, 0, TEX_WIDTH * TEX_HEIGHT * 2);
|
||||
}
|
||||
|
||||
/* set GX scaler */
|
||||
int xscale, yscale;
|
||||
void ogc_video__scale(void)
|
||||
/* Reset GX/VI scaler */
|
||||
static void gxScale(GXRModeObj *rmode)
|
||||
{
|
||||
int scale, xshift, yshift, i;
|
||||
int scale = 0;
|
||||
|
||||
/* borders are emulated */
|
||||
if (config.overscan)
|
||||
{
|
||||
if (config.aspect)
|
||||
/* First configure EFB width */
|
||||
switch (config.gxscaler)
|
||||
{
|
||||
case 0: /* let VI handles upscaling completely */
|
||||
rmode->fbWidth = (vwidth <= 640) ? vwidth : 640;
|
||||
break;
|
||||
|
||||
case 1: /* GX only doubles original width */
|
||||
rmode->fbWidth = (vwidth*2 <= 640) ? (vwidth*2) : ((vwidth <= 640) ? vwidth : 640);
|
||||
break;
|
||||
|
||||
case 2: /* GX upscale up to max EFB width (640 pixels) */
|
||||
rmode->fbWidth = 640;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Configure GX scaler and VI width */
|
||||
if (xscale > (rmode->fbWidth/2))
|
||||
{
|
||||
/* check max upscaling */
|
||||
if (xscale > 360)
|
||||
{
|
||||
scale = xscale - 360; /* save offset for later */
|
||||
xscale = 360;
|
||||
}
|
||||
|
||||
/* VI handles the remaining upscaling */
|
||||
rmode->viWidth = xscale * 2;
|
||||
rmode->viXOrigin = (720 - (xscale * 2)) / 2;
|
||||
|
||||
/* set GX scaling to max EFB width */
|
||||
scale += (rmode->fbWidth/2);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* VI should not upscale anything */
|
||||
rmode->viWidth = rmode->fbWidth;
|
||||
rmode->viXOrigin = (720 - rmode->fbWidth) / 2;
|
||||
|
||||
/* set GX scaling to max EFB width */
|
||||
scale = xscale;
|
||||
}
|
||||
|
||||
/* update GX scaler (Vertex Position Matrix) */
|
||||
square[6] = square[3] = scale + xshift;
|
||||
square[0] = square[9] = -scale + xshift;
|
||||
square[4] = square[1] = yscale + yshift;
|
||||
square[7] = square[10] = -yscale + yshift;
|
||||
draw_init();
|
||||
}
|
||||
|
||||
/* Set Aspect Ratio (depending on current configuration) */
|
||||
void ogc_video__aspect()
|
||||
{
|
||||
if (config.aspect)
|
||||
{
|
||||
/* original aspect ratio */
|
||||
/* the following values have been detected from comparison with a real 50/60hz Mega Drive */
|
||||
if (config.overscan)
|
||||
{
|
||||
/* borders are emulated */
|
||||
xscale = (reg[12] & 1) ? 360 : 358;
|
||||
if (gc_pal) xscale -= 1;
|
||||
yscale = (gc_pal && !config.render) ? (vdp_pal ? 144:143) : (vdp_pal ? 121:120);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fullscreen stretch */
|
||||
xscale = 352;
|
||||
yscale = (gc_pal && !config.render) ? (vdp_pal ? (268*144 / bitmap.viewport.h):143) : (vdp_pal ? (224*144 / bitmap.viewport.h):120);
|
||||
}
|
||||
|
||||
xshift = (config.aspect || !gc_pal) ? 8 : 4;
|
||||
yshift = vdp_pal ? 1 : 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (config.aspect)
|
||||
{
|
||||
/* borders are simulated (black) */
|
||||
xscale = 327;
|
||||
@ -423,98 +469,75 @@ void ogc_video__scale(void)
|
||||
if (vdp_pal && (!gc_pal || config.render)) yscale = yscale * 243 / 288;
|
||||
else if (!vdp_pal && gc_pal && !config.render) yscale = yscale * 288 / 243;
|
||||
}
|
||||
|
||||
xshift = 8 + config.xshift; /* default RGB offset, composite might be shifted less */
|
||||
yshift = (vdp_pal ? 1 : 3) - (config.overscan ? 0 : 1) + config.yshift;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* manual aspect ratio (default is fullscreen) */
|
||||
if (config.overscan)
|
||||
{
|
||||
/* borders are emulated */
|
||||
xscale = 352;
|
||||
yscale = (gc_pal && !config.render) ? (vdp_pal ? (268*144 / bitmap.viewport.h):143) : (vdp_pal ? (224*144 / bitmap.viewport.h):120);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fit screen */
|
||||
xscale = 320;
|
||||
yscale = (gc_pal && !config.render) ? 134 : 112;
|
||||
}
|
||||
|
||||
xshift = config.aspect ? 8 : 0;
|
||||
yshift = vdp_pal ? 0 : 2;
|
||||
}
|
||||
|
||||
if (!config.aspect)
|
||||
{
|
||||
|
||||
/* user scaling */
|
||||
xscale += config.xscale;
|
||||
yscale += config.yscale;
|
||||
}
|
||||
|
||||
xshift += config.xshift;
|
||||
yshift += config.yshift;
|
||||
|
||||
/* horizontal scaling */
|
||||
scale = (xscale > 360) ? 360 : xscale;
|
||||
if (scale > 320)
|
||||
{
|
||||
/* let VI do horizontal scaling */
|
||||
for (i=0; i<6; i++)
|
||||
{
|
||||
tvmodes[i]->viXOrigin = (720 - (scale * 2)) / 2;
|
||||
tvmodes[i]->viWidth = scale * 2;
|
||||
}
|
||||
scale = 320;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* let GX do horizontal downscaling */
|
||||
for (i=0; i<6; i++)
|
||||
{
|
||||
tvmodes[i]->viXOrigin = 40;
|
||||
tvmodes[i]->viWidth = 640;
|
||||
}
|
||||
}
|
||||
|
||||
square[6] = square[3] = scale + xshift;
|
||||
square[0] = square[9] = -scale + xshift;
|
||||
|
||||
/* vertical scaling */
|
||||
scale = yscale + yshift;
|
||||
if (config.render && !config.aa)
|
||||
{
|
||||
scale *= 2;
|
||||
yshift *= 2;
|
||||
xshift = config.xshift;
|
||||
yshift = config.yshift;
|
||||
}
|
||||
square[4] = square[1] = scale + yshift;
|
||||
square[7] = square[10] = yshift - scale;
|
||||
|
||||
/* update position matrix */
|
||||
draw_init();
|
||||
}
|
||||
/* Double resolution modes */
|
||||
if (config.render)
|
||||
{
|
||||
yscale *= 2;
|
||||
yshift *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reinitialize GX */
|
||||
/* Reinitialize Video */
|
||||
void ogc_video__reset()
|
||||
{
|
||||
GXRModeObj *rmode;
|
||||
Mtx p;
|
||||
GXRModeObj *rmode;
|
||||
|
||||
/* reset TV type (50Hz/60Hz) */
|
||||
/* Set 50Hz/60Hz mode */
|
||||
if ((config.tv_mode == 1) || ((config.tv_mode == 2) && vdp_pal)) gc_pal = 1;
|
||||
else gc_pal = 0;
|
||||
|
||||
/* reset scaler (aspect ratio) */
|
||||
ogc_video__scale();
|
||||
|
||||
/* reset TV mode */
|
||||
if (config.render == 2)
|
||||
{
|
||||
tvmodes[2]->viTVMode = VI_TVMODE_NTSC_PROG;
|
||||
tvmodes[2]->xfbMode = VI_XFBMODE_SF;
|
||||
}
|
||||
else
|
||||
{
|
||||
tvmodes[2]->viTVMode = tvmodes[0]->viTVMode & ~3;
|
||||
tvmodes[2]->xfbMode = VI_XFBMODE_DF;
|
||||
}
|
||||
/* Set current TV mode */
|
||||
if (config.render) rmode = tvmodes[gc_pal*3 + 2];
|
||||
else rmode = tvmodes[gc_pal*3 + interlaced];
|
||||
|
||||
/* anti-aliasing */
|
||||
rmode->aa = config.aa;
|
||||
if (config.render) rmode->efbHeight = config.aa ? 242 : 480;
|
||||
else if (gc_pal) rmode->efbHeight = config.aa ? 264 : 286;
|
||||
/* Aspect ratio */
|
||||
ogc_video__aspect();
|
||||
gxScale(rmode);
|
||||
|
||||
VIDEO_Configure (rmode);
|
||||
/* Progressive mode support */
|
||||
if (config.render == 2)
|
||||
{
|
||||
/* 480p */
|
||||
rmode->viTVMode = VI_TVMODE_NTSC_PROG;
|
||||
rmode->xfbMode = VI_XFBMODE_SF;
|
||||
}
|
||||
else if (config.render == 1)
|
||||
{
|
||||
/* 480i */
|
||||
rmode->viTVMode = tvmodes[0]->viTVMode & ~3;
|
||||
rmode->xfbMode = VI_XFBMODE_DF;
|
||||
}
|
||||
|
||||
/* Configure VI */
|
||||
VIDEO_Configure (rmode);
|
||||
VIDEO_ClearFrameBuffer(rmode, xfb[whichfb], COLOR_BLACK);
|
||||
VIDEO_Flush();
|
||||
VIDEO_WaitVSync();
|
||||
@ -522,7 +545,7 @@ void ogc_video__reset()
|
||||
else while (VIDEO_GetNextField()) VIDEO_WaitVSync();
|
||||
odd_frame = 1;
|
||||
|
||||
/* reset rendering mode */
|
||||
/* Configure GX */
|
||||
GX_SetViewport (0.0F, 0.0F, rmode->fbWidth, rmode->efbHeight, 0.0F, 1.0F);
|
||||
GX_SetScissor (0, 0, rmode->fbWidth, rmode->efbHeight);
|
||||
f32 yScale = GX_GetYScaleFactor(rmode->efbHeight, rmode->xfbHeight);
|
||||
@ -535,7 +558,7 @@ void ogc_video__reset()
|
||||
guOrtho(p, rmode->efbHeight/2, -(rmode->efbHeight/2), -(rmode->fbWidth/2), rmode->fbWidth/2, 100, 1000);
|
||||
GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC);
|
||||
|
||||
/* reset NTSC filter */
|
||||
/* Software NTSC filter */
|
||||
if (config.ntsc == 1)
|
||||
{
|
||||
sms_setup = sms_ntsc_composite;
|
||||
@ -564,7 +587,7 @@ void ogc_video__update()
|
||||
{
|
||||
int h, w;
|
||||
|
||||
/* texture and bitmap buffers (buffers width is fixed to 360 pixels) */
|
||||
/* texture and bitmap buffers (buffers width is fixed to 720 pixels) */
|
||||
long long int *dst = (long long int *)texturemem;
|
||||
long long int *src1 = (long long int *)(bitmap.data); /* line n */
|
||||
long long int *src2 = src1 + 180; /* line n+1 */
|
||||
@ -574,18 +597,6 @@ void ogc_video__update()
|
||||
/* check if viewport has changed */
|
||||
if (bitmap.viewport.changed)
|
||||
{
|
||||
/* Check interlaced mode changes */
|
||||
if ((bitmap.viewport.changed & 2) && (!config.render))
|
||||
{
|
||||
GXRModeObj *rmode;
|
||||
rmode = tvmodes[gc_pal*3 + interlaced];
|
||||
VIDEO_Configure (rmode);
|
||||
GX_SetFieldMode (rmode->field_rendering, ((rmode->viHeight == 2 * rmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
|
||||
VIDEO_WaitVSync();
|
||||
if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
|
||||
else while (VIDEO_GetNextField()) VIDEO_WaitVSync();
|
||||
}
|
||||
|
||||
bitmap.viewport.changed = 0;
|
||||
|
||||
/* update texture size */
|
||||
@ -602,16 +613,16 @@ void ogc_video__update()
|
||||
|
||||
/* final offset */
|
||||
stride = bitmap.width - (vwidth >> 2);
|
||||
|
||||
/* reset GX scaler */
|
||||
ogc_video__scale();
|
||||
|
||||
|
||||
/* image size has changed, reset GX */
|
||||
ogc_video__reset();
|
||||
|
||||
/* reinitialize texture */
|
||||
GX_InvalidateTexAll ();
|
||||
GX_InitTexObj (&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
|
||||
/* original H40 mode: force filtering OFF */
|
||||
if (!config.filtering)
|
||||
/* enable/disable bilinear filtering */
|
||||
if (!config.bilinear)
|
||||
{
|
||||
GX_InitTexObjLOD(&texobj,GX_NEAR,GX_NEAR_MIP_NEAR,2.5,9.0,0.0,GX_FALSE,GX_FALSE,GX_ANISO_1);
|
||||
}
|
||||
@ -710,7 +721,7 @@ void ogc_video__init(void)
|
||||
gc_pal = 0;
|
||||
|
||||
#ifndef HW_RVL
|
||||
/* force 480p when Component cable is detected */
|
||||
/* force 480p on GameCube if the Component Cable is present */
|
||||
if (VIDEO_HaveComponentCable()) vmode = &TVNtsc480Prog;
|
||||
#endif
|
||||
break;
|
||||
|
@ -24,7 +24,7 @@
|
||||
extern void ogc_video__init(void);
|
||||
extern void ogc_video__update(void);
|
||||
extern void ogc_video__reset(void);
|
||||
extern void ogc_video__scale(void);
|
||||
extern void ogc_video__aspect(void);
|
||||
|
||||
extern int gc_pal;
|
||||
extern unsigned int *xfb[2];
|
||||
|
Loading…
x
Reference in New Issue
Block a user