mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-24 18:21:50 +01:00
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:
parent
0bc38ba32c
commit
1a730e7183
@ -123,4 +123,3 @@ $(OUTPUT).elf: $(OFILES)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
|
@ -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
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
|
54
history.txt
54
history.txt
@ -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]
|
||||
- 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)
|
||||
|
||||
|
||||
|
||||
|
@ -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)
|
||||
@ -197,8 +197,14 @@ static void FileSelected()
|
||||
rootdirlength = filelist[selection].length;
|
||||
memfile_autosave();
|
||||
genromsize = LoadFile(cart_rom);
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -274,7 +274,12 @@ void miscmenu ()
|
||||
|
||||
case 2: /*** BIOS support ***/
|
||||
config.bios_enabled ^= 1;
|
||||
if (genromsize || (config.bios_enabled == 3))
|
||||
{
|
||||
system_init ();
|
||||
audio_init(48000);
|
||||
system_reset ();
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: /*** SVP emulation ***/
|
||||
@ -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 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();
|
||||
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;
|
||||
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();
|
||||
|
||||
/* 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 ***/
|
||||
|
@ -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)
|
||||
{
|
||||
@ -225,6 +241,20 @@ 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;
|
||||
|
@ -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,67 +379,24 @@ 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))
|
||||
{
|
||||
/* 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()
|
||||
{
|
||||
/* Aspect Ratio (depending on current configuration) */
|
||||
if (config.aspect)
|
||||
{
|
||||
/* original aspect ratio */
|
||||
@ -452,21 +404,20 @@ void ogc_video__aspect()
|
||||
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
|
||||
{
|
||||
@ -479,6 +430,7 @@ void ogc_video__aspect()
|
||||
}
|
||||
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,36 +585,49 @@ 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++)
|
||||
{
|
||||
for (w = 0; w < vwidth; w++)
|
||||
{
|
||||
*dst++ = *src1++;
|
||||
*dst++ = *src2++;
|
||||
@ -641,10 +641,11 @@ void ogc_video__update()
|
||||
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 ();
|
||||
|
@ -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
|
||||
|
@ -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++] ) );
|
||||
|
||||
#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)]);
|
||||
|
||||
int 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++] ) );
|
||||
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_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 );
|
||||
MD_NTSC_RGB_OUT( 5, *line_out++, MD_NTSC_OUT_DEPTH );
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
/* finish final pixels */
|
||||
MD_NTSC_COLOR_IN( 0, ntsc, MD_NTSC_ADJ_IN( table[*input++] ) );
|
||||
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_black );
|
||||
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_black );
|
||||
MD_NTSC_RGB_OUT( 4, *line_out++, MD_NTSC_OUT_DEPTH );
|
||||
MD_NTSC_RGB_OUT( 5, *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_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
|
||||
|
||||
int 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++] ) );
|
||||
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_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 );
|
||||
|
||||
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++] ) );
|
||||
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_black );
|
||||
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 );
|
||||
|
||||
MD_NTSC_COLOR_IN( 3, ntsc, md_ntsc_black );
|
||||
MD_NTSC_RGB_OUT( 6, *line_out++, MD_NTSC_OUT_DEPTH );
|
||||
MD_NTSC_RGB_OUT( 7, *line_out++, MD_NTSC_OUT_DEPTH );
|
||||
}
|
||||
#endif
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 ) \
|
||||
|
@ -586,33 +586,52 @@ void render_shutdown(void)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* 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;
|
||||
|
||||
/* 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 */
|
||||
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)
|
||||
{
|
||||
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) */
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user