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 endif
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------

View File

@ -26,7 +26,7 @@ INCLUDES := source source/m68k source/z80 source/sound source/cart_hw\
# options for code generation # 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) CXXFLAGS = $(CFLAGS)
LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map
@ -138,4 +138,3 @@ $(OUTPUT).elf: $(OFILES)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
endif endif
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------

View File

@ -3,33 +3,45 @@ Genesis Plus for Gamecube
CURRENT: CURRENT:
--------- ---------
[Genesis] [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):
- YM2612(MAME): modified SSG-EG Decay End Level, fix some sound effects (ChainSaw, Zap...) in "Beavis & Butthead" .fixed EG Decay->Substain transition when SL & DR are minimals: fix tracks #3 and #9 in "Mega Turrican"
- YM2612(MAME): improved Detune overflow accuracy, fix very high frequency sounds in many games .fixed a bug in SSG-EG emulation code: fix Level 1 music in "Alisia Dragoon"
- YM2612(MAME): fixed registers 0x20-0x26 Reset state, fix intro music in "B.O.B" .modified SSG-EG Decay End Level: fix some sound effects (ChainSaw, Zap...) in "Beavis & Butthead"
- YM2612(MAME): removed previous fix with KEY ON, fix "Flamethrower" sound effect in "Alien 3" .improved Detune overflow accuracy: fix very high frequency sounds in many games
- adjusted HCounter values, fixes line flickering in "Sonic 3D" bonus stage .fixed registers 0x20-0x26 Reset state: fix intro music in "B.O.B"
- adjusted VINT timing, fixes hang-up in "V.R Troopers" .reverted incorrect fix with KEY ON: fix "Flamethrower" sound effect in "Alien 3" and many other games
- improved HBLANK flag accuracy, fixes line flickering in "Gouketsuji Ichizoku"
- re-enabled Z80 banked access to WRAM, fixes hang-up in "Mamono Hunter Youko" - adjusted HCounter values: fixes line flickering in "Sonic 3D" bonus stage
- modified JCART emulation, fixes corrupted tracks logo in "Micro Machines 2" - adjusted VINT timing: fixes hang-up in "V.R Troopers"
- added Blargg's NTSC Filters support (NTSC composite video artifacts emulation) - 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] [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 - remove slowest libsamplerate settings under "HQ YM2612" option, only keeps SRC_LINEAR (faster) and SRC_SINC_FAST (better)
- fixed config file incompatibilities when switching between Gamecube and Wii versions - implemented fast scrolling in menu using Wiimote D-PAD
- added an option to enable/disable bilinear filtering - added an option to enable/disable bilinear filtering
- rewrote video scaling code - rewrote video renderer: improved horizontal scaling (VI+GX), faster rendering (direct texture mapping)...
- removed embedded font, back to internal IPL font: it should still works for Qoob users (fix from emukiddid) - removed embedded font, (re)enabled IPL font support: now should works for Qoob users too (thanks to emukiddid)
- improved SDCARD access speed (svpe's libogc patch) - fixed "Reset" button behavior, now acts more like Genesis Reset button ;-)
- added SDHC support (marcan's libogc patch) - added SDCARD read-ahead cache support (svpe's libogc patches)
- minor bugfixes and menu tweaks
[NGC]
- added proper 480p menu detection for NTSC Gamecube users [NGC only]
- added 480p support in menu
[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. * 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 loading from history then we need to setup a few more things. */
if(UseHistory) if(UseHistory)
@ -197,8 +197,14 @@ static void FileSelected()
rootdirlength = filelist[selection].length; rootdirlength = filelist[selection].length;
memfile_autosave(); memfile_autosave();
genromsize = LoadFile(cart_rom); genromsize = LoadFile(cart_rom);
if (genromsize)
{
reloadrom(); reloadrom();
memfile_autoload(); memfile_autoload();
return 1;
}
return 0;
} }
/**************************************************************************** /****************************************************************************
@ -206,15 +212,14 @@ static void FileSelected()
* *
* Let user select a file from the File listing * Let user select a file from the File listing
****************************************************************************/ ****************************************************************************/
static void FileSelector () static int FileSelector ()
{ {
short p; short p;
int haverom = 0;
int redraw = 1; int redraw = 1;
int go_up = 0; int go_up = 0;
int i,size; int i,size;
while (haverom == 0) while (1)
{ {
if (redraw) ShowFiles (offset, selection); if (redraw) ShowFiles (offset, selection);
redraw = 0; redraw = 0;
@ -298,11 +303,11 @@ static void FileSelector ()
filelist[selection].filename_offset = 0; filelist[selection].filename_offset = 0;
if (UseSDCARD) if (UseSDCARD)
{ {
if (strcmp(filelist[0].filename,"..") != 0) return; if (strcmp(filelist[0].filename,"..") != 0) return 0;
} }
else else
{ {
if (basedir == rootdir) return; if (basedir == rootdir) return 0;
} }
go_up = 1; go_up = 1;
} }
@ -311,7 +316,7 @@ static void FileSelector ()
if (p & PAD_TRIGGER_Z) if (p & PAD_TRIGGER_Z)
{ {
filelist[selection].filename_offset = 0; filelist[selection].filename_offset = 0;
return; return 0;
} }
/* open selected file or directory */ /* open selected file or directory */
@ -357,8 +362,8 @@ static void FileSelector ()
{ {
/* quit */ /* quit */
WaitPrompt ("No files found !"); WaitPrompt ("No files found !");
haverom = 1;
haveSDdir = 0; haveSDdir = 0;
return 0;
} }
} }
} }
@ -395,8 +400,7 @@ static void FileSelector ()
} }
else /*** This is a file ***/ else /*** This is a file ***/
{ {
FileSelected(); return FileSelected();
haverom = 1;
} }
redraw = 1; redraw = 1;
} }
@ -410,6 +414,8 @@ static void FileSelector ()
****************************************************************************/ ****************************************************************************/
int OpenDVD () int OpenDVD ()
{ {
int ret = 0;
UseSDCARD = 0; UseSDCARD = 0;
UseHistory = 0; UseHistory = 0;
@ -459,13 +465,13 @@ int OpenDVD ()
if ((maxfiles = parseDVDdirectory ())) if ((maxfiles = parseDVDdirectory ()))
{ {
FileSelector (); ret = FileSelector ();
haveDVDdir = 1; haveDVDdir = 1;
} }
} }
else FileSelector (); else ret = FileSelector ();
return 1; return ret;
} }
/**************************************************************************** /****************************************************************************
@ -475,6 +481,8 @@ int OpenDVD ()
****************************************************************************/ ****************************************************************************/
int OpenSD () int OpenSD ()
{ {
int ret = 0;
UseSDCARD = 1; UseSDCARD = 1;
UseHistory = 0; UseHistory = 0;
@ -500,7 +508,7 @@ int OpenSD ()
if ((maxfiles = parseSDdirectory ())) if ((maxfiles = parseSDdirectory ()))
{ {
/* Select an entry */ /* Select an entry */
FileSelector (); ret = FileSelector ();
/* memorize last entries list, actual root directory and selection for next access */ /* memorize last entries list, actual root directory and selection for next access */
haveSDdir = 1; haveSDdir = 1;
@ -513,7 +521,7 @@ int OpenSD ()
return 0; return 0;
} }
return 1; return ret;
} }
/**************************************************************************** /****************************************************************************
@ -566,8 +574,7 @@ int OpenHistory()
return 0; return 0;
} }
FileSelector(); return FileSelector();
return 1;
} }

View File

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

View File

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

View File

@ -31,9 +31,6 @@ md_ntsc_t md_ntsc;
sms_ntsc_setup_t sms_setup; sms_ntsc_setup_t sms_setup;
sms_ntsc_t sms_ntsc; sms_ntsc_t sms_ntsc;
/* Aspect Ratio */
int xscale, yscale, xshift, yshift;
/*** PAL 50hz flag ***/ /*** PAL 50hz flag ***/
int gc_pal = 0; int gc_pal = 0;
@ -41,6 +38,7 @@ int gc_pal = 0;
unsigned int *xfb[2]; /*** Double buffered ***/ unsigned int *xfb[2]; /*** Double buffered ***/
int whichfb = 0; /*** External framebuffer index ***/ int whichfb = 0; /*** External framebuffer index ***/
GXRModeObj *vmode; /*** Menu video mode ***/ GXRModeObj *vmode; /*** Menu video mode ***/
u8 *texturemem; /*** Texture Data ***/
/*** GX ***/ /*** GX ***/
#define TEX_WIDTH 360 * 2 #define TEX_WIDTH 360 * 2
@ -50,11 +48,10 @@ GXRModeObj *vmode; /*** Menu video mode ***/
#define VASPECT 240 #define VASPECT 240
static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32); 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 GXTexObj texobj;
static Mtx view; static Mtx view;
static int vwidth, vheight; static u32 vwidth, vheight;
static long long int stride; static u32 stride;
/*** custom Video modes (used to emulate original console video modes) ***/ /*** custom Video modes (used to emulate original console video modes) ***/
/* 288 lines progressive (PAL 50Hz) */ /* 288 lines progressive (PAL 50Hz) */
@ -65,7 +62,7 @@ GXRModeObj TV50hz_288p =
286, // efbHeight 286, // efbHeight
286, // xfbHeight 286, // xfbHeight
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin (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 720, // viWidth
572, // viHeight 572, // viHeight
VI_XFBMODE_SF, // xFBmode VI_XFBMODE_SF, // xFBmode
@ -100,7 +97,7 @@ GXRModeObj TV50hz_288i =
286, // efbHeight 286, // efbHeight
286, // xfbHeight 286, // xfbHeight
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin (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 720, // viWidth
572, // viHeight 572, // viHeight
VI_XFBMODE_SF, // xFBmode VI_XFBMODE_SF, // xFBmode
@ -205,7 +202,7 @@ GXRModeObj TV60hz_240i =
240, // efbHeight 240, // efbHeight
240, // xfbHeight 240, // xfbHeight
(VI_MAX_WIDTH_NTSC - 720)/2, // viXOrigin (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 720, // viWidth
480, // viHeight 480, // viHeight
VI_XFBMODE_SF, // xFBmode VI_XFBMODE_SF, // xFBmode
@ -326,19 +323,17 @@ static void draw_init(void)
memset (&view, 0, sizeof (Mtx)); memset (&view, 0, sizeof (Mtx));
guLookAt(view, &cam.pos, &cam.up, &cam.view); guLookAt(view, &cam.pos, &cam.up, &cam.view);
GX_LoadPosMtxImm (view, GX_PNMTX0); GX_LoadPosMtxImm (view, GX_PNMTX0);
GX_InvVtxCache ();
} }
/* vertex rendering */ /* 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_Position1x8 (pos);
GX_TexCoord2f32 (s, t); GX_TexCoord2f32 (s, t);
} }
/* textured quad rendering */ /* textured quad rendering */
static void draw_square (void) static inline void draw_square (void)
{ {
GX_Begin (GX_QUADS, GX_VTXFMT0, 4); GX_Begin (GX_QUADS, GX_VTXFMT0, 4);
draw_vert (3, 0.0, 0.0); draw_vert (3, 0.0, 0.0);
@ -384,67 +379,24 @@ static void gxStart(void)
guOrtho(p, vmode->efbHeight/2, -(vmode->efbHeight/2), -(vmode->fbWidth/2), vmode->fbWidth/2, 100, 1000); guOrtho(p, vmode->efbHeight/2, -(vmode->efbHeight/2), -(vmode->fbWidth/2), vmode->fbWidth/2, 100, 1000);
GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC); GX_LoadProjectionMtx (p, GX_ORTHOGRAPHIC);
/*** reset XFB ***/ /*** Reset XFB ***/
GX_CopyDisp (xfb[whichfb ^ 1], GX_TRUE); GX_CopyDisp (xfb[whichfb ^ 1], GX_TRUE);
/*** Initialize texture data ***/ /*** Initialize texture data ***/
texturemem = memalign(32, TEX_WIDTH * TEX_HEIGHT * 2);
memset (texturemem, 0, TEX_WIDTH * TEX_HEIGHT * 2); memset (texturemem, 0, TEX_WIDTH * TEX_HEIGHT * 2);
/*** Initialize renderer */
draw_init();
} }
/* Reset GX/VI scaler */ /* Reset GX/VI scaler */
static void gxScale(GXRModeObj *rmode) static void gxScale(GXRModeObj *rmode)
{ {
int scale = 0; int temp = 0;
int xscale, yscale, xshift, yshift;
/* GX Scaler (by default, use EFB maximal width) */ /* Aspect Ratio (depending on current configuration) */
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))
{
/* 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) if (config.aspect)
{ {
/* original aspect ratio */ /* original aspect ratio */
@ -452,21 +404,20 @@ void ogc_video__aspect()
if (config.overscan) if (config.overscan)
{ {
/* borders are emulated */ /* borders are emulated */
xscale = (reg[12] & 1) ? 360 : 358; xscale = 358 + ((reg[12] & 1)*2) - gc_pal;
if (gc_pal) xscale -= 1; yscale = vdp_pal + ((gc_pal && !config.render) ? 143 : 120);
yscale = (gc_pal && !config.render) ? (vdp_pal ? 144:143) : (vdp_pal ? 121:120);
} }
else else
{ {
/* borders are simulated (black) */ /* borders are simulated (black) */
xscale = 327; xscale = 325 + ((reg[12] & 1)*2) - gc_pal;
yscale = bitmap.viewport.h / 2; yscale = bitmap.viewport.h / 2;
if (vdp_pal && (!gc_pal || config.render)) yscale = yscale * 243 / 288; if (vdp_pal && (!gc_pal || config.render)) yscale = yscale * 240 / 288;
else if (!vdp_pal && gc_pal && !config.render) yscale = yscale * 288 / 243; else if (!vdp_pal && gc_pal && !config.render) yscale = yscale * 288 / 240;
} }
xshift = 8 + config.xshift; /* default RGB offset, composite might be shifted less */ xshift = config.xshift;
yshift = (vdp_pal ? 1 : 3) - (config.overscan ? 0 : 1) + config.yshift; yshift = 2 - vdp_pal + 2*(gc_pal & !config.render) + config.yshift;
} }
else else
{ {
@ -479,6 +430,7 @@ void ogc_video__aspect()
} }
else else
{ {
/* borders are simulated (black) */
xscale = 320; xscale = 320;
yscale = (gc_pal && !config.render) ? 134 : 112; yscale = (gc_pal && !config.render) ? 134 : 112;
} }
@ -497,6 +449,51 @@ void ogc_video__aspect()
yscale *= 2; yscale *= 2;
yshift *= 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 */ /* Reinitialize Video */
@ -505,32 +502,31 @@ void ogc_video__reset()
Mtx p; Mtx p;
GXRModeObj *rmode; GXRModeObj *rmode;
/* Set 50Hz/60Hz mode */ /* 50Hz/60Hz mode */
if ((config.tv_mode == 1) || ((config.tv_mode == 2) && vdp_pal)) gc_pal = 1; if ((config.tv_mode == 1) || ((config.tv_mode == 2) && vdp_pal)) gc_pal = 1;
else gc_pal = 0; 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 */ /* Set current TV mode */
if (config.render) rmode = tvmodes[gc_pal*3 + 2]; if (config.render) rmode = tvmodes[gc_pal*3 + 2];
else rmode = tvmodes[gc_pal*3 + interlaced]; else rmode = tvmodes[gc_pal*3 + interlaced];
/* Aspect ratio */ /* Aspect ratio */
ogc_video__aspect();
gxScale(rmode); 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 */ /* Configure VI */
VIDEO_Configure (rmode); VIDEO_Configure (rmode);
VIDEO_ClearFrameBuffer(rmode, xfb[whichfb], COLOR_BLACK); VIDEO_ClearFrameBuffer(rmode, xfb[whichfb], COLOR_BLACK);
@ -579,15 +575,6 @@ void ogc_video__reset()
/* GX render update */ /* GX render update */
void ogc_video__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 */ /* check if viewport has changed */
if (bitmap.viewport.changed) if (bitmap.viewport.changed)
{ {
@ -598,36 +585,49 @@ void ogc_video__update()
vheight = bitmap.viewport.h + 2 * bitmap.viewport.y; vheight = bitmap.viewport.h + 2 * bitmap.viewport.y;
/* special cases */ /* 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); if (config.ntsc) vwidth = (reg[12]&1) ? MD_NTSC_OUT_WIDTH(vwidth) : SMS_NTSC_OUT_WIDTH(vwidth);
/* texels size must be multiple of 4 */ /* texels size must be multiple of 4 */
vwidth = (vwidth / 4) * 4; vwidth = vwidth >> 2;
vheight = (vheight / 4) * 4; vheight = vheight >> 2;
/* final offset */ /* final offset */
stride = bitmap.width - (vwidth >> 2); stride = bitmap.width - vwidth;
/* image size has changed, reset GX */ /* image size has changed, reset GX */
ogc_video__reset(); ogc_video__reset();
/* reinitialize texture */ /* reinitialize texture */
GX_InvalidateTexAll (); GX_InitTexObj (&texobj, texturemem, vwidth << 2, vheight << 2, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObj (&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
/* enable/disable bilinear filtering */ /* enable/disable bilinear filtering */
if (!config.bilinear) 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); 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 */ /* texture map is now directly done by the line renderer */
for (h = 0; h < vheight; h += 4) 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++)
{
for (w = 0; w < vwidth; w++)
{ {
*dst++ = *src1++; *dst++ = *src1++;
*dst++ = *src2++; *dst++ = *src2++;
@ -641,10 +641,11 @@ void ogc_video__update()
src3 += stride; src3 += stride;
src4 += stride; src4 += stride;
} }
}
/* load texture into GX */ /* update texture cache */
DCFlushRange (texturemem, vwidth * vheight * 2); DCFlushRange (texturemem, TEX_WIDTH * TEX_HEIGHT * 2);
GX_LoadTexObj (&texobj, GX_TEXMAP0); GX_InvalidateTexAll ();
/* render textured quad */ /* render textured quad */
draw_square (); draw_square ();

View File

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

View File

@ -97,108 +97,66 @@ 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++] ),
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)]); md_ntsc_out_t* restrict line_out = (md_ntsc_out_t*)(&bitmap.data[(vline * bitmap.pitch)]);
#endif
int n;
int n;
for ( n = chunk_count; n; --n )
{ 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++] ) ); /* order of input and output pixels must not be altered */
MD_NTSC_RGB_OUT( 0, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_COLOR_IN( 0, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
MD_NTSC_RGB_OUT( 1, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_RGB_OUT( 0, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_RGB_OUT( 1, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_COLOR_IN( 1, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
MD_NTSC_RGB_OUT( 2, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_COLOR_IN( 1, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
MD_NTSC_RGB_OUT( 3, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_RGB_OUT( 2, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_RGB_OUT( 3, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_COLOR_IN( 2, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
MD_NTSC_RGB_OUT( 4, *line_out++, MD_NTSC_OUT_DEPTH ); #ifdef NGC
MD_NTSC_RGB_OUT( 5, *line_out++, MD_NTSC_OUT_DEPTH ); line_out += 12;
#endif
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_COLOR_IN( 2, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
MD_NTSC_RGB_OUT( 7, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_RGB_OUT( 4, *line_out++, MD_NTSC_OUT_DEPTH );
} MD_NTSC_RGB_OUT( 5, *line_out++, MD_NTSC_OUT_DEPTH );
/* finish final pixels */ MD_NTSC_COLOR_IN( 3, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
MD_NTSC_COLOR_IN( 0, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) ); MD_NTSC_RGB_OUT( 6, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_RGB_OUT( 0, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_RGB_OUT( 7, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_RGB_OUT( 1, *line_out++, MD_NTSC_OUT_DEPTH );
#ifdef NGC
MD_NTSC_COLOR_IN( 1, ntsc, md_ntsc_black ); line_out += 12;
MD_NTSC_RGB_OUT( 2, *line_out++, MD_NTSC_OUT_DEPTH ); #endif
MD_NTSC_RGB_OUT( 3, *line_out++, MD_NTSC_OUT_DEPTH ); }
MD_NTSC_COLOR_IN( 2, ntsc, md_ntsc_black ); /* finish final pixels */
MD_NTSC_RGB_OUT( 4, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_COLOR_IN( 0, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
MD_NTSC_RGB_OUT( 5, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_RGB_OUT( 0, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_RGB_OUT( 1, *line_out++, MD_NTSC_OUT_DEPTH );
MD_NTSC_COLOR_IN( 3, ntsc, md_ntsc_black );
MD_NTSC_RGB_OUT( 6, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_COLOR_IN( 1, ntsc, md_ntsc_black );
MD_NTSC_RGB_OUT( 7, *line_out++, MD_NTSC_OUT_DEPTH ); MD_NTSC_RGB_OUT( 2, *line_out++, MD_NTSC_OUT_DEPTH );
} MD_NTSC_RGB_OUT( 3, *line_out++, MD_NTSC_OUT_DEPTH );
/* draw the pixel along with darkened pixel*/ #ifdef NGC
#define PIXEL_OUT_DOUBLE( x )\ line_out += 12;
{\ #endif
MD_NTSC_RGB_OUT( x, pixel, MD_NTSC_OUT_DEPTH );\
*line_out++ = pixel;\ MD_NTSC_COLOR_IN( 2, ntsc, md_ntsc_black );
*line_out2++ = pixel - (pixel >> 2 & 0x18E3);\ MD_NTSC_RGB_OUT( 4, *line_out++, MD_NTSC_OUT_DEPTH );
} MD_NTSC_RGB_OUT( 5, *line_out++, MD_NTSC_OUT_DEPTH );
void md_ntsc_blit_double( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned char* input, MD_NTSC_COLOR_IN( 3, ntsc, md_ntsc_black );
int in_width, int vline) MD_NTSC_RGB_OUT( 6, *line_out++, MD_NTSC_OUT_DEPTH );
{ MD_NTSC_RGB_OUT( 7, *line_out++, MD_NTSC_OUT_DEPTH );
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 #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, void md_ntsc_blit( md_ntsc_t const* ntsc, MD_NTSC_IN_T const* table, unsigned char* input,
int in_width, int vline); 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. */ /* Number of output pixels written by blitter for given input width. */
#define MD_NTSC_OUT_WIDTH( in_width ) \ #define MD_NTSC_OUT_WIDTH( in_width ) \
(((in_width) - 3) / md_ntsc_in_chunk * md_ntsc_out_chunk + md_ntsc_out_chunk) (((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( 5, *line_out++, SMS_NTSC_OUT_DEPTH );
SMS_NTSC_RGB_OUT( 6, *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 #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. */ 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, void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* table, unsigned char* input,
int in_width, int vline); 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. */ /* Number of output pixels written by blitter for given input width. */
#define SMS_NTSC_OUT_WIDTH( in_width ) \ #define SMS_NTSC_OUT_WIDTH( in_width ) \

View File

@ -586,33 +586,52 @@ 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) void remap_buffer(int line, int width)
{ {
/* get line offset from framebuffer */ /* get line offset from framebuffer */
int vline = (line + bitmap.viewport.y) % lines_per_frame; int vline = (line + bitmap.viewport.y) % lines_per_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);
}
return;
}
/* double resolution mode */ /* double resolution mode */
if (config.render && interlaced) vline = (vline * 2) + odd_frame; if (config.render && interlaced) vline = (vline * 2) + odd_frame;
void *out =((void *)&bitmap.data[(vline * bitmap.pitch)]); /* NTSC Filter */
if (config.ntsc)
{
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;
}
#ifndef NGC #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);
#else
void *out =((void *)&bitmap.data[(vline * bitmap.pitch)]);
switch(bitmap.depth) switch(bitmap.depth)
{ {
case 8: 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); remap_32(tmp_buf+0x20-bitmap.viewport.x, (uint32 *)out, pixel_32, width);
break; break;
} }
#else
remap_16(tmp_buf+0x20-bitmap.viewport.x, (uint16 *)out, pixel_16, width);
#endif #endif
} }
void render_line(int line, uint8 odd_frame) void render_line(int line, uint8 odd_frame)
{ {
/* check if we are inside display area (including vertical borders) */ /* 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; aim_m68k += m68cycles_per_line;
/* Check "soft reset" */ /* 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 */ /* Horizontal Interrupt */
if (line <= bitmap.viewport.h) if (line <= bitmap.viewport.h)