modified SRAM autosave, directly run the game after the ROM has been loaded, wii shutdown support, improved soft reset support, faster (direct) texture mapping , faster NTSC filters

This commit is contained in:
ekeeke31 2008-11-13 07:24:30 +00:00
parent 0bc38ba32c
commit 1a730e7183
14 changed files with 329 additions and 389 deletions

View File

@ -123,4 +123,3 @@ $(OUTPUT).elf: $(OFILES)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

View File

@ -26,7 +26,7 @@ INCLUDES := source source/m68k source/z80 source/sound source/cart_hw\
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -O3 -mrvl -Wall $(MACHDEP) -fno-strict-aliasing $(INCLUDE) -DWORDS_BIGENDIAN -DNGC="1" -DHW_RVL
CFLAGS = -O3 -mrvl -Wall $(MACHDEP) -Wno-strict-aliasing $(INCLUDE) -DWORDS_BIGENDIAN -DNGC="1" -DHW_RVL
CXXFLAGS = $(CFLAGS)
LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map
@ -138,4 +138,3 @@ $(OUTPUT).elf: $(OFILES)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

View File

@ -3,33 +3,45 @@ Genesis Plus for Gamecube
CURRENT:
---------
[Genesis]
- YM2612(MAME): fixed EG Decay->Substain transition when SL & DR are minimals, fix tracks #3 and #9 in "Mega Turrican"
- YM2612(MAME): fixed a bug in SSG-EG emulation code, fix Level 1 music in "Alisia Dragoon"
- YM2612(MAME): modified SSG-EG Decay End Level, fix some sound effects (ChainSaw, Zap...) in "Beavis & Butthead"
- YM2612(MAME): improved Detune overflow accuracy, fix very high frequency sounds in many games
- YM2612(MAME): fixed registers 0x20-0x26 Reset state, fix intro music in "B.O.B"
- YM2612(MAME): removed previous fix with KEY ON, fix "Flamethrower" sound effect in "Alien 3"
- adjusted HCounter values, fixes line flickering in "Sonic 3D" bonus stage
- adjusted VINT timing, fixes hang-up in "V.R Troopers"
- improved HBLANK flag accuracy, fixes line flickering in "Gouketsuji Ichizoku"
- re-enabled Z80 banked access to WRAM, fixes hang-up in "Mamono Hunter Youko"
- modified JCART emulation, fixes corrupted tracks logo in "Micro Machines 2"
- added Blargg's NTSC Filters support (NTSC composite video artifacts emulation)
- YM2612(MAME):
.fixed EG Decay->Substain transition when SL & DR are minimals: fix tracks #3 and #9 in "Mega Turrican"
.fixed a bug in SSG-EG emulation code: fix Level 1 music in "Alisia Dragoon"
.modified SSG-EG Decay End Level: fix some sound effects (ChainSaw, Zap...) in "Beavis & Butthead"
.improved Detune overflow accuracy: fix very high frequency sounds in many games
.fixed registers 0x20-0x26 Reset state: fix intro music in "B.O.B"
.reverted incorrect fix with KEY ON: fix "Flamethrower" sound effect in "Alien 3" and many other games
- adjusted HCounter values: fixes line flickering in "Sonic 3D" bonus stage
- adjusted VINT timing: fixes hang-up in "V.R Troopers"
- improved HBLANK flag accuracy: fixes line flickering in "Gouketsuji Ichizoku"
- fixed broken Z80 access to WRAM: fixes hang-up in "Mamono Hunter Youko"
- modified JCART emulation: fixes corrupted tracks logo in "Micro Machines 2"
- added Blargg's NTSC Filters support (NTSC video artifacts emulation)
[NGC/Wii]
- remove useless libsamplerate settings in "HQ YM2612" mode, only keeps SRC_LINEAR (faster) and SRC_SINC_FAST (better)
- implemented fast scrolling in menus using Wiimote D-PAD
- fixed config file incompatibilities when switching between Gamecube and Wii versions
- remove slowest libsamplerate settings under "HQ YM2612" option, only keeps SRC_LINEAR (faster) and SRC_SINC_FAST (better)
- implemented fast scrolling in menu using Wiimote D-PAD
- added an option to enable/disable bilinear filtering
- rewrote video scaling code
- removed embedded font, back to internal IPL font: it should still works for Qoob users (fix from emukiddid)
- improved SDCARD access speed (svpe's libogc patch)
- added SDHC support (marcan's libogc patch)
- rewrote video renderer: improved horizontal scaling (VI+GX), faster rendering (direct texture mapping)...
- removed embedded font, (re)enabled IPL font support: now should works for Qoob users too (thanks to emukiddid)
- fixed "Reset" button behavior, now acts more like Genesis Reset button ;-)
- added SDCARD read-ahead cache support (svpe's libogc patches)
- minor bugfixes and menu tweaks
[NGC only]
- added 480p support in menu
[NGC]
- added proper 480p menu detection for NTSC Gamecube users
[Wii only]
- added "Power" button support, including shutdown from the wiimote (libogc CVS)
- added SDHC support (libogc CVS)

View File

@ -169,7 +169,7 @@ static int parseSDdirectory()
*
* Called when a file is selected by the user inside the FileSelector loop.
****************************************************************************/
static void FileSelected()
static int FileSelected()
{
/* If loading from history then we need to setup a few more things. */
if(UseHistory)
@ -195,10 +195,16 @@ static void FileSelected()
rootdir = filelist[selection].offset;
rootdirlength = filelist[selection].length;
memfile_autosave();
memfile_autosave();
genromsize = LoadFile(cart_rom);
reloadrom();
memfile_autoload();
if (genromsize)
{
reloadrom();
memfile_autoload();
return 1;
}
return 0;
}
/****************************************************************************
@ -206,15 +212,14 @@ static void FileSelected()
*
* Let user select a file from the File listing
****************************************************************************/
static void FileSelector ()
static int FileSelector ()
{
short p;
int haverom = 0;
int redraw = 1;
int go_up = 0;
int i,size;
while (haverom == 0)
while (1)
{
if (redraw) ShowFiles (offset, selection);
redraw = 0;
@ -298,11 +303,11 @@ static void FileSelector ()
filelist[selection].filename_offset = 0;
if (UseSDCARD)
{
if (strcmp(filelist[0].filename,"..") != 0) return;
if (strcmp(filelist[0].filename,"..") != 0) return 0;
}
else
{
if (basedir == rootdir) return;
if (basedir == rootdir) return 0;
}
go_up = 1;
}
@ -311,7 +316,7 @@ static void FileSelector ()
if (p & PAD_TRIGGER_Z)
{
filelist[selection].filename_offset = 0;
return;
return 0;
}
/* open selected file or directory */
@ -357,8 +362,8 @@ static void FileSelector ()
{
/* quit */
WaitPrompt ("No files found !");
haverom = 1;
haveSDdir = 0;
return 0;
}
}
}
@ -395,8 +400,7 @@ static void FileSelector ()
}
else /*** This is a file ***/
{
FileSelected();
haverom = 1;
return FileSelected();
}
redraw = 1;
}
@ -410,6 +414,8 @@ static void FileSelector ()
****************************************************************************/
int OpenDVD ()
{
int ret = 0;
UseSDCARD = 0;
UseHistory = 0;
@ -459,13 +465,13 @@ int OpenDVD ()
if ((maxfiles = parseDVDdirectory ()))
{
FileSelector ();
ret = FileSelector ();
haveDVDdir = 1;
}
}
else FileSelector ();
else ret = FileSelector ();
return 1;
return ret;
}
/****************************************************************************
@ -475,6 +481,8 @@ int OpenDVD ()
****************************************************************************/
int OpenSD ()
{
int ret = 0;
UseSDCARD = 1;
UseHistory = 0;
@ -500,7 +508,7 @@ int OpenSD ()
if ((maxfiles = parseSDdirectory ()))
{
/* Select an entry */
FileSelector ();
ret = FileSelector ();
/* memorize last entries list, actual root directory and selection for next access */
haveSDdir = 1;
@ -513,7 +521,7 @@ int OpenSD ()
return 0;
}
return 1;
return ret;
}
/****************************************************************************
@ -566,8 +574,7 @@ int OpenHistory()
return 0;
}
FileSelector();
return 1;
return FileSelector();
}

View File

@ -274,8 +274,13 @@ void miscmenu ()
case 2: /*** BIOS support ***/
config.bios_enabled ^= 1;
system_reset ();
break;
if (genromsize || (config.bios_enabled == 3))
{
system_init ();
audio_init(48000);
system_reset ();
}
break;
case 3: /*** SVP emulation ***/
case -5:
@ -314,7 +319,7 @@ void dispmenu ()
int ret;
int quit = 0;
int prevmenu = menu;
int count = 10;
int count = config.aspect ? 8 : 10;
char items[10][25];
strcpy (menutitle, "Press B to return");
@ -322,9 +327,7 @@ void dispmenu ()
while (quit == 0)
{
ogc_video__aspect();
sprintf (items[0], "Aspect: %s", config.aspect ? "ORIGINAL" : "STRETCH");
sprintf (items[0], "Aspect: %s", config.aspect ? "ORIGINAL" : "STRETCHED");
if (config.render == 1) sprintf (items[1], "Render: INTERLACED");
else if (config.render == 2) sprintf (items[1], "Render: PROGRESSIVE");
else sprintf (items[1], "Render: ORIGINAL");
@ -339,8 +342,8 @@ void dispmenu ()
sprintf (items[5], "Borders: %s", config.overscan ? " ON" : "OFF");
sprintf (items[6], "Center X: %s%02d", config.xshift < 0 ? "-":"+", abs(config.xshift));
sprintf (items[7], "Center Y: %s%02d", config.yshift < 0 ? "-":"+", abs(config.yshift));
sprintf (items[8], "Scale X: %02d", xscale*2);
sprintf (items[9], "Scale Y: %02d", yscale*4);
sprintf (items[8], "Scale X: %s%02d", config.xscale < 0 ? "-":"+", abs(config.xscale));
sprintf (items[9], "Scale Y: %s%02d", config.yscale < 0 ? "-":"+", abs(config.yscale));
ret = domenu (&items[0], count, 1);
@ -348,7 +351,7 @@ void dispmenu ()
{
case 0: /*** config.aspect ratio ***/
config.aspect ^= 1;
bitmap.viewport.changed = 1;
count = config.aspect ? 8 : 10;
break;
case 1: /*** rendering ***/
@ -832,9 +835,6 @@ 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)
@ -844,23 +844,11 @@ int loadsavemenu (int which)
break;
case 0:
#ifdef HW_RVL
device = (device + 1)%4;
#else
device = (device + 1)%3;
#endif
break;
case 1:
case 2:
#ifdef HW_RVL
if ((device == 0) || (device == 3))
{
PARTITION_INTERFACE dev = device ? PI_USBSTORAGE : PI_INTERNAL_SD;
fatSetDefaultInterface(dev);
fatEnableReadAhead (dev, 6, 64);
}
#endif
if (which == 1) quit = ManageState(ret-1,device);
else if (which == 0) quit = ManageSRAM(ret-1,device);
if (quit) return 1;
@ -917,23 +905,17 @@ int filemenu ()
*
****************************************************************************/
static u8 load_menu = 0;
static u8 dvd_on = 0;
void loadmenu ()
int loadmenu ()
{
int ret;
int prevmenu = menu;
int ret;
int quit = 0;
#ifdef HW_RVL
int count = 5;
char item[5][25] = {
#else
int count = 5;
char item[5][25] = {
#endif
int count = 3 + dvd_on;
char item[4][25] = {
{"Load Recent"},
{"Load from SDCARD"},
#ifdef HW_RVL
{"Load from USB"},
#endif
{"Load from DVD"},
{"Stop DVD Motor"}
};
@ -951,40 +933,34 @@ void loadmenu ()
break;
case 0: /*** Load Recent ***/
quit = OpenHistory();
load_menu = menu;
if (OpenHistory()) return 1;
break;
case 1: /*** Load from SCDARD ***/
#ifdef HW_RVL
case 2:
{
PARTITION_INTERFACE dev = (ret&2) ? PI_USBSTORAGE : PI_INTERNAL_SD;
fatSetDefaultInterface(dev);
fatEnableReadAhead (dev, 6, 64);
}
#endif
quit = OpenSD();
load_menu = menu;
if (OpenSD()) return 1;
break;
#ifdef HW_RVL
case 3: /*** Load from DVD ***/
#else
case 2:
#endif
quit = OpenDVD();
load_menu = menu;
if (OpenDVD())
{
dvd_on = 1;
return 1;
}
break;
#ifdef HW_RVL
case 4: /*** Stop DVD Disc ***/
#else
case 3:
#endif
case 3: /*** Stop DVD Disc ***/
dvd_motor_off();
dvd_on = 0;
count = 3 + dvd_on;
break;
}
}
load_menu = menu;
menu = prevmenu;
return 0;
}
/***************************************************************************
@ -1139,6 +1115,12 @@ void MainMenu ()
VIDEO_WaitVSync();
VIDEO_WaitVSync();
/* autosave SRAM (Freeze States should be saved on exit only) */
int temp = config.freeze_auto;
config.freeze_auto = -1;
memfile_autosave();
config.freeze_auto = temp;
while (quit == 0)
{
crccheck = crc32 (0, &sram.sram[0], 0x10000);
@ -1163,16 +1145,13 @@ void MainMenu ()
case 2: /*** Emulator Reset ***/
if (genromsize || (config.bios_enabled == 3))
{
system_init ();
audio_init(48000);
system_reset ();
quit = 1;
}
break;
case 3: /*** Load ROM Menu ***/
loadmenu();
menu = 0;
quit = loadmenu();
break;
case 4: /*** Memory Manager ***/

View File

@ -21,12 +21,23 @@
#include "gcaram.h"
#include "font.h"
#include "history.h"
#ifndef HW_RVL
#ifdef HW_DOL
#include "dvd.h"
#else
#include "di/di.h"
#endif
#ifdef HW_RVL
/* Power Button callback */
static int Shutdown;
void Power_Off(void)
{
Shutdown = 1;
ConfigRequested = 1;
}
#endif
/***************************************************************************
* Genesis Virtual Machine
*
@ -58,7 +69,7 @@ static void load_bios()
static void init_machine()
{
/* Allocate cart_rom here */
cart_rom = memalign(32, 0xA00000);
cart_rom = memalign(32, 10 * 1024 * 1024);
/* allocate global work bitmap */
memset (&bitmap, 0, sizeof (bitmap));
@ -72,7 +83,7 @@ static void init_machine()
bitmap.viewport.x = 0;
bitmap.viewport.y = 0;
bitmap.remap = 1;
bitmap.data = malloc (bitmap.width * bitmap.height * bitmap.granularity);
bitmap.data = memalign (32, bitmap.width * bitmap.height * bitmap.granularity);
/* default system */
input.system[0] = SYSTEM_GAMEPAD;
@ -119,12 +130,17 @@ int main (int argc, char *argv[])
ogc_input__init();
ogc_audio__init();
#ifndef HW_RVL
#ifdef HW_DOL
/* Initialize GC DVD interface */
DVD_Init ();
dvd_drive_detect();
#endif
#ifdef HW_RVL
/* Power Button callback */
SYS_SetPowerCallback(Power_Off);
#endif
/* Initialize SDCARD Interface (LibFAT) */
if (fatInitDefault() == true)
{
@ -224,7 +240,21 @@ int main (int argc, char *argv[])
{
/* reset AUDIO */
ogc_audio__reset();
#ifdef HW_RVL
/* wii shutdown */
if (Shutdown)
{
/* autosave SRAM/State */
memfile_autosave();
/* shutdown Wii */
Shutdown = 0;
DI_Close();
SYS_ResetSystem(SYS_POWEROFF, 0, 0);
}
#endif
/* go to menu */
MainMenu ();
ConfigRequested = 0;

View File

@ -31,9 +31,6 @@ 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;
@ -41,6 +38,7 @@ int gc_pal = 0;
unsigned int *xfb[2]; /*** Double buffered ***/
int whichfb = 0; /*** External framebuffer index ***/
GXRModeObj *vmode; /*** Menu video mode ***/
u8 *texturemem; /*** Texture Data ***/
/*** GX ***/
#define TEX_WIDTH 360 * 2
@ -50,11 +48,10 @@ GXRModeObj *vmode; /*** Menu video mode ***/
#define VASPECT 240
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32);
static u8 texturemem[TEX_WIDTH * (TEX_HEIGHT + 8) * 2] ATTRIBUTE_ALIGN (32);
static GXTexObj texobj;
static Mtx view;
static int vwidth, vheight;
static long long int stride;
static u32 vwidth, vheight;
static u32 stride;
/*** custom Video modes (used to emulate original console video modes) ***/
/* 288 lines progressive (PAL 50Hz) */
@ -65,7 +62,7 @@ GXRModeObj TV50hz_288p =
286, // efbHeight
286, // xfbHeight
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin
(VI_MAX_HEIGHT_PAL - 572)/2, // viYOrigin
(VI_MAX_HEIGHT_PAL/2 - 572/2)/2, // viYOrigin
720, // viWidth
572, // viHeight
VI_XFBMODE_SF, // xFBmode
@ -100,7 +97,7 @@ GXRModeObj TV50hz_288i =
286, // efbHeight
286, // xfbHeight
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin
(VI_MAX_HEIGHT_PAL - 572)/2, // viYOrigin
(VI_MAX_HEIGHT_PAL/2 - 572/2)/2, // viYOrigin
720, // viWidth
572, // viHeight
VI_XFBMODE_SF, // xFBmode
@ -205,7 +202,7 @@ GXRModeObj TV60hz_240i =
240, // efbHeight
240, // xfbHeight
(VI_MAX_WIDTH_NTSC - 720)/2, // viXOrigin
(VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
(VI_MAX_HEIGHT_NTSC/2 - 480/2)/2, // viYOrigin
720, // viWidth
480, // viHeight
VI_XFBMODE_SF, // xFBmode
@ -326,19 +323,17 @@ static void draw_init(void)
memset (&view, 0, sizeof (Mtx));
guLookAt(view, &cam.pos, &cam.up, &cam.view);
GX_LoadPosMtxImm (view, GX_PNMTX0);
GX_InvVtxCache ();
}
/* vertex rendering */
static void draw_vert(u8 pos, f32 s, f32 t)
static inline void draw_vert(u8 pos, f32 s, f32 t)
{
GX_Position1x8 (pos);
GX_TexCoord2f32 (s, t);
}
/* textured quad rendering */
static void draw_square (void)
static inline void draw_square (void)
{
GX_Begin (GX_QUADS, GX_VTXFMT0, 4);
draw_vert (3, 0.0, 0.0);
@ -384,89 +379,45 @@ static void gxStart(void)
guOrtho(p, vmode->efbHeight/2, -(vmode->efbHeight/2), -(vmode->fbWidth/2), vmode->fbWidth/2, 100, 1000);
GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC);
/*** reset XFB ***/
/*** Reset XFB ***/
GX_CopyDisp (xfb[whichfb ^ 1], GX_TRUE);
/*** Initialize texture data ***/
texturemem = memalign(32, TEX_WIDTH * TEX_HEIGHT * 2);
memset (texturemem, 0, TEX_WIDTH * TEX_HEIGHT * 2);
/*** Initialize renderer */
draw_init();
}
/* Reset GX/VI scaler */
static void gxScale(GXRModeObj *rmode)
{
int scale = 0;
int temp = 0;
int xscale, yscale, xshift, yshift;
/* GX Scaler (by default, use EFB maximal width) */
rmode->fbWidth = 640;
if (!config.bilinear)
{
/* try to prevent GX bilinear filtering */
/* if possible, let GX simply doubles the width, otherwise disable GX stretching completely */
if ((vwidth * 2) <= 640) rmode->fbWidth = vwidth * 2;
else if (vwidth <= 640) rmode->fbWidth = vwidth;
}
/* Horizontal Scaling (GX/VI) */
if (xscale > (rmode->fbWidth/2))
/* Aspect Ratio (depending on current configuration) */
if (config.aspect)
{
/* check max upscaling */
if (xscale > 360)
{
/* save offset for later */
scale = xscale - 360;
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);
xscale = 358 + ((reg[12] & 1)*2) - gc_pal;
yscale = vdp_pal + ((gc_pal && !config.render) ? 143 : 120);
}
else
{
/* borders are simulated (black) */
xscale = 327;
xscale = 325 + ((reg[12] & 1)*2) - gc_pal;
yscale = bitmap.viewport.h / 2;
if (vdp_pal && (!gc_pal || config.render)) yscale = yscale * 243 / 288;
else if (!vdp_pal && gc_pal && !config.render) yscale = yscale * 288 / 243;
if (vdp_pal && (!gc_pal || config.render)) yscale = yscale * 240 / 288;
else if (!vdp_pal && gc_pal && !config.render) yscale = yscale * 288 / 240;
}
xshift = 8 + config.xshift; /* default RGB offset, composite might be shifted less */
yshift = (vdp_pal ? 1 : 3) - (config.overscan ? 0 : 1) + config.yshift;
xshift = config.xshift;
yshift = 2 - vdp_pal + 2*(gc_pal & !config.render) + config.yshift;
}
else
{
@ -476,9 +427,10 @@ void ogc_video__aspect()
/* 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
{
}
else
{
/* borders are simulated (black) */
xscale = 320;
yscale = (gc_pal && !config.render) ? 134 : 112;
}
@ -497,6 +449,51 @@ void ogc_video__aspect()
yscale *= 2;
yshift *= 2;
}
/* GX Scaler (by default, use EFB maximal width) */
rmode->fbWidth = 640;
if (!config.bilinear)
{
/* try to prevent GX bilinear filtering */
/* if possible, let GX simply doubles the width, otherwise disable GX stretching completely */
int width = vwidth * 4;
if ((width * 2) <= 640) rmode->fbWidth = width * 2;
else if (width <= 640) rmode->fbWidth = width;
}
/* Horizontal Scaling (GX/VI) */
if (xscale > (rmode->fbWidth/2))
{
/* max width = 720 pixels */
if (xscale > 360)
{
/* save offset for later */
temp = xscale - 360;
xscale = 360;
}
/* enable VI scaler */
rmode->viWidth = xscale * 2;
rmode->viXOrigin = (720 - (xscale * 2)) / 2;
/* set GX scaling to max EFB width */
xscale = temp + (rmode->fbWidth/2);
}
else
{
/* disable VI scaler */
rmode->viWidth = rmode->fbWidth;
rmode->viXOrigin = (720 - rmode->fbWidth) / 2;
}
/* update GX scaler (Vertex Position Matrix) */
square[6] = square[3] = xscale + xshift;
square[0] = square[9] = -xscale + xshift;
square[4] = square[1] = yscale + yshift;
square[7] = square[10] = -yscale + yshift;
DCFlushRange (square, 32);
GX_InvVtxCache ();
}
/* Reinitialize Video */
@ -505,32 +502,31 @@ void ogc_video__reset()
Mtx p;
GXRModeObj *rmode;
/* Set 50Hz/60Hz mode */
/* 50Hz/60Hz mode */
if ((config.tv_mode == 1) || ((config.tv_mode == 2) && vdp_pal)) gc_pal = 1;
else gc_pal = 0;
/* progressive mode */
if (config.render == 2)
{
/* 480p */
tvmodes[2]->viTVMode = VI_TVMODE_NTSC_PROG;
tvmodes[2]->xfbMode = VI_XFBMODE_SF;
}
else if (config.render == 1)
{
/* 480i */
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];
/* Aspect ratio */
ogc_video__aspect();
gxScale(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);
@ -579,15 +575,6 @@ void ogc_video__reset()
/* GX render update */
void ogc_video__update()
{
int h, w;
/* 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 */
long long int *src3 = src2 + 180; /* line n+2 */
long long int *src4 = src3 + 180; /* line n+3 */
/* check if viewport has changed */
if (bitmap.viewport.changed)
{
@ -598,53 +585,67 @@ void ogc_video__update()
vheight = bitmap.viewport.h + 2 * bitmap.viewport.y;
/* special cases */
if (config.render && (interlaced || config.ntsc)) vheight *= 2;
if (config.render && interlaced) vheight *= 2;
if (config.ntsc) vwidth = (reg[12]&1) ? MD_NTSC_OUT_WIDTH(vwidth) : SMS_NTSC_OUT_WIDTH(vwidth);
/* texels size must be multiple of 4 */
vwidth = (vwidth / 4) * 4;
vheight = (vheight / 4) * 4;
vwidth = vwidth >> 2;
vheight = vheight >> 2;
/* final offset */
stride = bitmap.width - (vwidth >> 2);
stride = bitmap.width - vwidth;
/* 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);
GX_InitTexObj (&texobj, texturemem, vwidth << 2, vheight << 2, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
/* 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);
}
/* load texture */
GX_LoadTexObj (&texobj, GX_TEXMAP0);
}
GX_InvalidateTexAll ();
/* update texture data */
for (h = 0; h < vheight; h += 4)
/* texture map is now directly done by the line renderer */
if (config.ntsc && !(reg[12]&1))
{
for (w = 0; w < (vwidth >> 2); w++)
int h, w;
/* texture and bitmap buffers (buffers pitch is fixed to 720*2 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 */
long long int *src3 = src2 + 180; /* line n+2 */
long long int *src4 = src3 + 180; /* line n+3 */
/* update texture texels */
for (h = 0; h < vheight; h++)
{
*dst++ = *src1++;
*dst++ = *src2++;
*dst++ = *src3++;
*dst++ = *src4++;
}
for (w = 0; w < vwidth; w++)
{
*dst++ = *src1++;
*dst++ = *src2++;
*dst++ = *src3++;
*dst++ = *src4++;
}
/* jump to next four lines */
src1 += stride;
src2 += stride;
src3 += stride;
src4 += stride;
/* jump to next four lines */
src1 += stride;
src2 += stride;
src3 += stride;
src4 += stride;
}
}
/* load texture into GX */
DCFlushRange (texturemem, vwidth * vheight * 2);
GX_LoadTexObj (&texobj, GX_TEXMAP0);
/* update texture cache */
DCFlushRange (texturemem, TEX_WIDTH * TEX_HEIGHT * 2);
GX_InvalidateTexAll ();
/* render textured quad */
draw_square ();

View File

@ -24,12 +24,11 @@
extern void ogc_video__init(void);
extern void ogc_video__update(void);
extern void ogc_video__reset(void);
extern void ogc_video__aspect(void);
extern int gc_pal;
extern unsigned int *xfb[2];
extern int whichfb, xscale, yscale;
extern int whichfb;
extern GXRModeObj *tvmodes[6];
extern GXRModeObj *vmode;
extern u8 *texturemem;
#endif

View File

@ -97,7 +97,16 @@ void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned ch
MD_NTSC_ADJ_IN( table[*input++] ),
MD_NTSC_ADJ_IN( table[*input++] ) );
#ifdef NGC
/* directly fill the RGB565 texture */
/* one tile is 32 byte = 4x4 pixels */
/* tiles are stored continuously in texture memory */
in_width = MD_NTSC_OUT_WIDTH(in_width) >> 2;
int offset = ((in_width << 5) * (vline >> 2)) + ((vline & 3) * 8);
md_ntsc_out_t* restrict line_out = (md_ntsc_out_t*)(texturemem + offset);
#else
md_ntsc_out_t* restrict line_out = (md_ntsc_out_t*)(&bitmap.data[(vline * bitmap.pitch)]);
#endif
int n;
@ -112,6 +121,10 @@ void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned ch
MD_NTSC_RGB_OUT( 2, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_RGB_OUT( 3, *line_out++, MD_NTSC_OUT_DEPTH );
#ifdef NGC
line_out += 12;
#endif
MD_NTSC_COLOR_IN( 2, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
MD_NTSC_RGB_OUT( 4, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_RGB_OUT( 5, *line_out++, MD_NTSC_OUT_DEPTH );
@ -119,7 +132,11 @@ void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned ch
MD_NTSC_COLOR_IN( 3, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
MD_NTSC_RGB_OUT( 6, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_RGB_OUT( 7, *line_out++, MD_NTSC_OUT_DEPTH );
}
#ifdef NGC
line_out += 12;
#endif
}
/* finish final pixels */
MD_NTSC_COLOR_IN( 0, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
@ -130,6 +147,10 @@ void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned ch
MD_NTSC_RGB_OUT( 2, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_RGB_OUT( 3, *line_out++, MD_NTSC_OUT_DEPTH );
#ifdef NGC
line_out += 12;
#endif
MD_NTSC_COLOR_IN( 2, ntsc, md_ntsc_black );
MD_NTSC_RGB_OUT( 4, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_RGB_OUT( 5, *line_out++, MD_NTSC_OUT_DEPTH );
@ -138,67 +159,4 @@ void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned ch
MD_NTSC_RGB_OUT( 6, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_RGB_OUT( 7, *line_out++, MD_NTSC_OUT_DEPTH );
}
/* draw the pixel along with darkened pixel*/
#define PIXEL_OUT_DOUBLE( x )\
{\
MD_NTSC_RGB_OUT( x, pixel, MD_NTSC_OUT_DEPTH );\
*line_out++ = pixel;\
*line_out2++ = pixel - (pixel >> 2 & 0x18E3);\
}
void md_ntsc_blit_double( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned char* input,
int in_width, int vline)
{
int const chunk_count = in_width / md_ntsc_in_chunk - 1;
MD_NTSC_BEGIN_ROW( ntsc, md_ntsc_black,
MD_NTSC_ADJ_IN( table[*input++] ),
MD_NTSC_ADJ_IN( table[*input++] ),
MD_NTSC_ADJ_IN( table[*input++] ) );
md_ntsc_out_t* restrict line_out = (md_ntsc_out_t*)(&bitmap.data[(vline * bitmap.pitch)]);
md_ntsc_out_t* restrict line_out2 = (md_ntsc_out_t*)(&bitmap.data[((vline^1) * bitmap.pitch)]);
int n;
unsigned pixel;
for ( n = chunk_count; n; --n )
{
/* order of input and output pixels must not be altered */
MD_NTSC_COLOR_IN( 0, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
PIXEL_OUT_DOUBLE(0);
PIXEL_OUT_DOUBLE(1);
MD_NTSC_COLOR_IN( 1, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
PIXEL_OUT_DOUBLE(2);
PIXEL_OUT_DOUBLE(3);
MD_NTSC_COLOR_IN( 2, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
PIXEL_OUT_DOUBLE(4);
PIXEL_OUT_DOUBLE(5);
MD_NTSC_COLOR_IN( 3, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
PIXEL_OUT_DOUBLE(6);
PIXEL_OUT_DOUBLE(7);
}
/* finish final pixels */
MD_NTSC_COLOR_IN( 0, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
PIXEL_OUT_DOUBLE(0);
PIXEL_OUT_DOUBLE(1);
MD_NTSC_COLOR_IN( 1, ntsc, md_ntsc_black );
PIXEL_OUT_DOUBLE(2);
PIXEL_OUT_DOUBLE(3);
MD_NTSC_COLOR_IN( 2, ntsc, md_ntsc_black );
PIXEL_OUT_DOUBLE(4);
PIXEL_OUT_DOUBLE(5);
MD_NTSC_COLOR_IN( 3, ntsc, md_ntsc_black );
PIXEL_OUT_DOUBLE(6);
PIXEL_OUT_DOUBLE(7);
}
#endif

View File

@ -52,10 +52,6 @@ is the number of *bytes* to get to the next output row. */
void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned char* input,
int in_width, int vline);
/* Same as above but doubles the height */
void md_ntsc_blit_double( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned char* input,
int in_width, int vline);
/* Number of output pixels written by blitter for given input width. */
#define MD_NTSC_OUT_WIDTH( in_width ) \
(((in_width) - 3) / md_ntsc_in_chunk * md_ntsc_out_chunk + md_ntsc_out_chunk)

View File

@ -134,65 +134,4 @@ void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned
SMS_NTSC_RGB_OUT( 5, *line_out++, SMS_NTSC_OUT_DEPTH );
SMS_NTSC_RGB_OUT( 6, *line_out++, SMS_NTSC_OUT_DEPTH );
}
/* draw the pixel along with darkened pixel*/
#define PIXEL_OUT_DOUBLE( x )\
{\
SMS_NTSC_RGB_OUT( x, pixel, SMS_NTSC_OUT_DEPTH );\
*line_out++ = pixel;\
*line_out2++ = pixel - (pixel >> 2 & 0x18E3);\
}
void sms_ntsc_blit_double( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned char* input,
int in_width, int vline)
{
int const chunk_count = in_width / sms_ntsc_in_chunk;
/* handle extra 0, 1, or 2 pixels by placing them at beginning of row */
int const in_extra = in_width - chunk_count * sms_ntsc_in_chunk;
unsigned const extra2 = (unsigned) -(in_extra >> 1 & 1); /* (unsigned) -1 = ~0 */
unsigned const extra1 = (unsigned) -(in_extra & 1) | extra2;
SMS_NTSC_BEGIN_ROW( ntsc, sms_ntsc_black,
(SMS_NTSC_ADJ_IN( table[input[0]] )) & extra2,
(SMS_NTSC_ADJ_IN( table[input[extra2 & 1]] )) & extra1 );
sms_ntsc_out_t* restrict line_out = (sms_ntsc_out_t*)(&bitmap.data[(vline * bitmap.pitch)]);
sms_ntsc_out_t* restrict line_out2 = (sms_ntsc_out_t*)(&bitmap.data[((vline^1) * bitmap.pitch)]);
int n;
unsigned pixel;
input += in_extra;
for ( n = chunk_count; n; --n )
{
/* order of input and output pixels must not be altered */
SMS_NTSC_COLOR_IN( 0, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) );
PIXEL_OUT_DOUBLE(0);
PIXEL_OUT_DOUBLE(1);
SMS_NTSC_COLOR_IN( 1, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) );
PIXEL_OUT_DOUBLE(2);
PIXEL_OUT_DOUBLE(3);
SMS_NTSC_COLOR_IN( 2, ntsc, SMS_NTSC_ADJ_IN( table[*input++] ) );
PIXEL_OUT_DOUBLE(4);
PIXEL_OUT_DOUBLE(5);
PIXEL_OUT_DOUBLE(6);
}
/* finish final pixels */
SMS_NTSC_COLOR_IN( 0, ntsc, sms_ntsc_black );
PIXEL_OUT_DOUBLE(0);
PIXEL_OUT_DOUBLE(1);
SMS_NTSC_COLOR_IN( 1, ntsc, sms_ntsc_black );
PIXEL_OUT_DOUBLE(2);
PIXEL_OUT_DOUBLE(3);
SMS_NTSC_COLOR_IN( 2, ntsc, sms_ntsc_black );
PIXEL_OUT_DOUBLE(4);
PIXEL_OUT_DOUBLE(5);
PIXEL_OUT_DOUBLE(6);
}
#endif

View File

@ -51,8 +51,6 @@ In_row_width is the number of pixels to get to the next input row. Out_pitch
is the number of *bytes* to get to the next output row. */
void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned char* input,
int in_width, int vline);
void sms_ntsc_blit_double( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned char* input,
int in_width, int vline);
/* Number of output pixels written by blitter for given input width. */
#define SMS_NTSC_OUT_WIDTH( in_width ) \

View File

@ -584,35 +584,54 @@ void render_shutdown(void)
}
/*--------------------------------------------------------------------------*/
/* Line render function */
/* Line render function */
/*--------------------------------------------------------------------------*/
#ifdef NGC
static inline void remap_texture(uint8 *src, uint16 *dst, int tile_cnt)
{
int count;
uint16 *table = pixel_16;
for(count = 0; count < tile_cnt; count ++)
{
/* one tile is 4 pixels wide */
*dst++ = table[*src++];
*dst++ = table[*src++];
*dst++ = table[*src++];
*dst++ = table[*src++];
/* skip next three 4-pixels lines */
dst += 12;
}
}
#endif
void remap_buffer(int line, int width)
{
/* get line offset from framebuffer */
int vline = (line + bitmap.viewport.y) % lines_per_frame;
/* double resolution mode */
if (config.render && interlaced) vline = (vline * 2) + odd_frame;
/* NTSC Filter */
if (config.ntsc)
{
if (reg[12]&1)
{
if (config.render) md_ntsc_blit_double(&md_ntsc, ( MD_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, (vline * 2) + (interlaced ? odd_frame:0));
else md_ntsc_blit(&md_ntsc, ( MD_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, vline);
}
else
{
if (config.render) sms_ntsc_blit_double(&sms_ntsc, ( SMS_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, (vline * 2) + (interlaced ? odd_frame:0));
else sms_ntsc_blit(&sms_ntsc, ( SMS_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, vline);
}
if (reg[12]&1) md_ntsc_blit(&md_ntsc, ( MD_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, vline);
else sms_ntsc_blit(&sms_ntsc, ( SMS_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, vline);
return;
}
/* double resolution mode */
if (config.render && interlaced) vline = (vline * 2) + odd_frame;
void *out =((void *)&bitmap.data[(vline * bitmap.pitch)]);
#ifdef NGC
/* directly fill the RGB565 texture */
/* one tile is 32 byte = 4x4 pixels */
/* tiles are stored continuously in texture memory */
width = width >> 2;
int offset = ((width << 5) * (vline >> 2)) + ((vline & 3) * 8);
remap_texture(tmp_buf+0x20-bitmap.viewport.x, (uint16 *)(texturemem + offset), width);
#ifndef NGC
#else
void *out =((void *)&bitmap.data[(vline * bitmap.pitch)]);
switch(bitmap.depth)
{
case 8:
@ -628,12 +647,9 @@ void remap_buffer(int line, int width)
remap_32(tmp_buf+0x20-bitmap.viewport.x, (uint32 *)out, pixel_32, width);
break;
}
#else
remap_16(tmp_buf+0x20-bitmap.viewport.x, (uint16 *)out, pixel_16, width);
#endif
}
void render_line(int line, uint8 odd_frame)
{
/* check if we are inside display area (including vertical borders) */

View File

@ -221,7 +221,14 @@ int system_frame (int do_skip)
aim_m68k += m68cycles_per_line;
/* Check "soft reset" */
if (line == resetline) gen_reset(0);
if (line == resetline)
{
#ifdef NGC
/* wait for RESET button to be released */
if (!SYS_ResetButtonDown())
#endif
gen_reset(0);
}
/* Horizontal Interrupt */
if (line <= bitmap.viewport.h)