Added Dendy mode for Windows.

http://wiki.nesdev.com/w/index.php/Clock_rate
This commit is contained in:
feos-tas 2015-04-26 10:12:15 +00:00
parent bceb7966bc
commit 36e1b07c19
13 changed files with 694 additions and 634 deletions

View File

@ -120,6 +120,10 @@ void FCEUI_SetGameGenie(bool a);
//Set video system a=0 NTSC, a=1 PAL
void FCEUI_SetVidSystem(int a);
//Set variables for NTSC(0) / PAL(1) / Dendy(2)
//Dendy has PAL framerate and resolution, but ~NTSC timings, and has 50 dummy scanlines to force 50 fps
void FCEUI_SetRegion(int region);
//Convenience function; returns currently emulated video system(0=NTSC, 1=PAL).
int FCEUI_GetCurrentVidSystem(int *slstart, int *slend);

View File

@ -41,6 +41,7 @@ char *ParseArgies(int argc, char *argv[])
{
static ARGPSTRUCT FCEUArgs[]={
{"-pal",&pal_setting_specified,&pal_emulation,0},
{"-dendy",0,&dendy,0},
{"-noicon",0,&status_icon,0},
{"-gg",0,&genie,0},
{"-no8lim",0,&eoptions,0x8000|EO_NOSPRLIM},

View File

@ -183,6 +183,7 @@ static CFGSTRUCT fceuconfig[] =
AC(gNoBGFillColor),
AC(ntsccol),AC(ntsctint),AC(ntschue),
AC(force_grayscale),
AC(dendy),
NAC("palyo",pal_emulation),
NAC("genie",genie),

View File

@ -146,6 +146,7 @@ double tvAspectX = TV_ASPECT_DEFAULT_X, tvAspectY = TV_ASPECT_DEFAULT_Y;
int genie = 0;
int pal_emulation = 0;
int pal_setting_specified = 0;
int dendy = 0;
int ntsccol = 0, ntsctint, ntschue;
std::string BaseDirectory;
int PauseAfterLoad;
@ -656,6 +657,7 @@ int main(int argc,char *argv[])
pauseAfterPlayback = !!pauseAfterPlayback;
closeFinishedMovie = !!closeFinishedMovie;
EnableBackgroundInput = !!EnableBackgroundInput;
dendy = !!dendy;
KeyboardSetBackgroundAccess(EnableBackgroundInput!=0);
JoystickSetBackgroundAccess(EnableBackgroundInput!=0);
@ -754,9 +756,9 @@ int main(int argc,char *argv[])
LoadNewGamey(hAppWnd, 0);
}
if (pal_setting_specified)
if (pal_setting_specified && !dendy)
{
// Force the PAL setting specified in the command line
// Force the PAL setting specified in the command line, unless Dendy
pal_emulation = saved_pal_setting;
FCEUI_SetVidSystem(pal_emulation);
}

View File

@ -42,6 +42,9 @@ extern int genie;
// Flag that indicates whether PAL Emulation is enabled or not.
extern int pal_emulation;
extern int pal_setting_specified;
// dendy and pal should have been designed alongside, using enum or alike
// now it's not possible to do it easily, so we'll just use the flag here and there, not to touch PAL logics
extern int dendy;
extern int status_icon;
extern int frame_display;
extern int rerecord_display;

File diff suppressed because it is too large Load Diff

View File

@ -416,7 +416,6 @@
#define IDC_DEBUGGER_VAL_PPU 310
#define IDC_LABEL_PALUSED2 310
#define IDC_LABEL_NEWPPUUSED 310
#define MENU_PAL 311
#define IDC_DEBUGGER_VAL_SPR 311
#define IDC_LABEL_TWEAKCOUNT 311
#define IDC_BTN_CHEAT_ADDFROMFILE 311
@ -426,6 +425,9 @@
#define MENU_DIRECTORIES 320
#define MENU_INPUT 321
#define MENU_GUI_OPTIONS 327
#define MENU_NTSC 330
#define MENU_PAL 331
#define MENU_DENDY 332
#define CHECK_DISABLE_FOURSCORE 400
#define MENU_MV_BOOKMARKS_RM_ALL 400
#define IDC_WINSIZE_MUL_X 400
@ -1203,6 +1205,7 @@
#define ID_HIGHLIGHTING_HIGHLIGHT_ACTIVITY 40588
#define ID_DUMPTOFILE_CPUBUS 40589
#define MENU_MV_FILE_DUMP_64K 40590
#define ID_CONFIG_REGION 40591
#define IDC_DEBUGGER_ICONTRAY 55535
#define MW_ValueLabel2 65423
#define MW_ValueLabel1 65426
@ -1215,7 +1218,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 291
#define _APS_NEXT_COMMAND_VALUE 40591
#define _APS_NEXT_COMMAND_VALUE 40596
#define _APS_NEXT_CONTROL_VALUE 1290
#define _APS_NEXT_SYMED_VALUE 101
#endif

View File

@ -881,6 +881,8 @@ void applyMovieInputConfig()
FCEUD_SetInput(currMovieData.fourscore, currMovieData.microphone, (ESI)currMovieData.ports[0], (ESI)currMovieData.ports[1], (ESIFC)currMovieData.ports[2]);
// update PAL flag
pal_emulation = currMovieData.palFlag;
if (pal_emulation)
dendy = 0;
FCEUI_SetVidSystem(pal_emulation);
RefreshThrottleFPS();
PushCurrentVideoSettings();

View File

@ -400,8 +400,8 @@ void UpdateCheckedMenuItems()
bool spr, bg;
FCEUI_GetRenderPlanes(spr,bg);
static int *polo[] = { &genie, &pal_emulation, &status_icon};
static int polo2[]={ MENU_GAME_GENIE, MENU_PAL, MENU_SHOW_STATUS_ICON };
static int *polo[] = { &genie, &status_icon};
static int polo2[]={ MENU_GAME_GENIE, MENU_SHOW_STATUS_ICON };
int x;
// Check or uncheck the necessary menu items
@ -439,6 +439,14 @@ void UpdateCheckedMenuItems()
CheckMenuItem(fceumenu, MENU_DISPLAY_OBJ, spr?MF_CHECKED:MF_UNCHECKED);
CheckMenuItem(fceumenu, ID_INPUTDISPLAY_OLDSTYLEDISP, oldInputDisplay?MF_CHECKED:MF_UNCHECKED);
//Config - Region SubMenu
if (pal_emulation)
CheckMenuRadioItem(fceumenu, MENU_NTSC, MENU_DENDY, MENU_PAL, MF_BYCOMMAND);
else if (dendy)
CheckMenuRadioItem(fceumenu, MENU_NTSC, MENU_DENDY, MENU_DENDY, MF_BYCOMMAND);
else
CheckMenuRadioItem(fceumenu, MENU_NTSC, MENU_DENDY, MENU_NTSC, MF_BYCOMMAND);
// Tools Menu
CheckMenuItem(fceumenu, MENU_ALTERNATE_AB, GetAutoFireDesynch() ? MF_CHECKED : MF_UNCHECKED);
CheckedAutoFirePattern = GetCheckedAutoFirePattern();
@ -1965,12 +1973,14 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
FCEUI_SetGameGenie(genie!=0);
UpdateCheckedMenuItems();
break;
case MENU_NTSC:
FCEUI_SetRegion(0);
break;
case MENU_PAL:
pal_emulation ^= 1;
FCEUI_SetVidSystem(pal_emulation);
RefreshThrottleFPS();
UpdateCheckedMenuItems();
PushCurrentVideoSettings();
FCEUI_SetRegion(1);
break;
case MENU_DENDY:
FCEUI_SetRegion(2);
break;
case MENU_DIRECTORIES:
ConfigDirectories();

View File

@ -848,14 +848,15 @@ void FCEU_ResetVidSys(void) {
if (GameInfo->vidsys == GIV_NTSC)
w = 0;
else if (GameInfo->vidsys == GIV_PAL)
else if (GameInfo->vidsys == GIV_PAL) {
w = 1;
else
dendy = 0;
} else
w = FSettings.PAL;
PAL = w ? 1 : 0;
FCEUPPU_SetVideoSystem(w);
FCEUPPU_SetVideoSystem(w || dendy);
SetSoundVariables();
}
@ -890,7 +891,7 @@ void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall) {
FSettings.UsrLastSLine[0] = ntscl;
FSettings.UsrFirstSLine[1] = palf;
FSettings.UsrLastSLine[1] = pall;
if (PAL) {
if (PAL || dendy) {
FSettings.FirstSLine = FSettings.UsrFirstSLine[1];
FSettings.LastSLine = FSettings.UsrLastSLine[1];
} else {
@ -916,6 +917,30 @@ int FCEUI_GetCurrentVidSystem(int *slstart, int *slend) {
return(PAL);
}
// TODO: make use on SDL
void FCEUI_SetRegion(int region) {
switch (region) {
case 0: // NTSC
pal_emulation = 0;
dendy = 0;
break;
case 1: // PAL
pal_emulation = 1;
dendy = 0;
break;
case 2: // Dendy
pal_emulation = 0;
dendy = 1;
break;
}
FCEUI_SetVidSystem(pal_emulation);
RefreshThrottleFPS();
#ifdef WIN32
UpdateCheckedMenuItems();
PushCurrentVideoSettings();
#endif
}
//Enable or disable Game Genie option.
void FCEUI_SetGameGenie(bool a) {
FSettings.GameGenie = a;
@ -928,7 +953,7 @@ void FCEUI_SetGameGenie(bool a) {
//}
int32 FCEUI_GetDesiredFPS(void) {
if (PAL)
if (PAL || dendy)
return(838977920); // ~50.007
else
return(1008307711); // ~60.1

View File

@ -74,6 +74,7 @@ extern FCEUGI *GameInfo;
extern int GameAttributes;
extern uint8 PAL;
extern int dendy;
//#include "driver.h"
@ -127,6 +128,11 @@ void FCEU_PutImage(void);
void FCEU_PutImageDummy(void);
#endif
#ifdef WIN32
extern void UpdateCheckedMenuItems();
extern void PushCurrentVideoSettings();
#endif
extern uint8 Exit;
extern uint8 pale;
extern uint8 vsdip;

View File

@ -1219,7 +1219,10 @@ static void Fixit1(void) {
void MMC5_hb(int); //Ugh ugh ugh.
static void DoLine(void) {
int x;
uint8 *target = XBuf + (scanline << 8);
// scanlines after 239 are dummy for dendy, and Xbuf is capped at 0xffff bytes, don't let it overflow
// send all future writes to the invisible sanline. the easiest way to "skip" them altogether in old ppu
// todo: figure out what exactly should be skipped. it's known that there's no activity on PPU bus
uint8 *target = XBuf + ((scanline < 240 ? scanline : 240) << 8);
if (MMC5Hack) MMC5_hb(scanline);
@ -1634,7 +1637,7 @@ static void CopySprites(uint8 *target) {
void FCEUPPU_SetVideoSystem(int w) {
if (w) {
scanlines_per_frame = 312;
scanlines_per_frame = dendy ? 262: 312;
FSettings.FirstSLine = FSettings.UsrFirstSLine[1];
FSettings.LastSLine = FSettings.UsrLastSLine[1];
} else {
@ -1785,8 +1788,9 @@ int FCEUPPU_Loop(int skip) {
int x, max, maxref;
deemp = PPU[1] >> 5;
for (scanline = 0; scanline < 240; ) { //scanline is incremented in DoLine. Evil. :/
for (scanline = 0; scanline < (dendy ? 290 : 240); ) { //scanline is incremented in DoLine. Evil. :/
deempcnt[deemp]++;
if (scanline < 240)
DEBUG(FCEUD_UpdatePPUView(scanline, 1));
DoLine();
}
@ -2027,8 +2031,8 @@ int FCEUX_PPU_Loop(int skip) {
//capture the initial xscroll
//int xscroll = ppur.fh;
//render 241 scanlines (including 1 dummy at beginning)
for (int sl = 0; sl < 241; sl++) {
//render 241/291 scanlines (1 dummy at beginning, dendy's 50 at the end)
for (int sl = 0; sl < (dendy ? 291 : 241); sl++) {
spr_read.start_scanline();
g_rasterpos = 0;
@ -2039,7 +2043,7 @@ int FCEUX_PPU_Loop(int skip) {
const int yp = sl - 1;
ppuphase = PPUPHASE_BG;
if (sl != 0) {
if (sl != 0 && sl < 241) { // ignore the invisible
DEBUG(FCEUD_UpdatePPUView(scanline = yp, 1));
DEBUG(FCEUD_UpdateNTView(scanline = yp, 1));
}
@ -2062,7 +2066,7 @@ int FCEUX_PPU_Loop(int skip) {
//ok, we're also going to draw here.
//unless we're on the first dummy scanline
if (sl != 0) {
if (sl != 0 && sl < 241) { // cape at 240 for dendy, its PPU does nothing afterwards
int xstart = xt << 3;
oamcount = oamcounts[renderslot];
uint8 * const target = XBuf + (yp << 8) + xstart;
@ -2233,7 +2237,7 @@ int FCEUX_PPU_Loop(int skip) {
runppu(1);
garbage_todo = 0;
}
if ((sl != 0) && ppur.status.cycle == 256)
if ((sl != 0 && sl < 241) && ppur.status.cycle == 256)
{
runppu(1);
//at 257: 3d world runner is ugly if we do this at 256

View File

@ -61,7 +61,7 @@ extern uint32 timestamp;
extern void (*MapIRQHook)(int a);
#define NTSC_CPU 1789772.7272727272727272
#define NTSC_CPU (dendy ? 1773447.467 : 1789772.7272727272727272)
#define PAL_CPU 1662607.125
#define FCEU_IQEXT 0x001