} while(cfgst[x].ptr);
}
-void SaveFCEUConfig(char *filename, CFGSTRUCT *cfgst)
+int SaveFCEUConfig(char *filename, CFGSTRUCT *cfgst)
{
FILE *fp;
fp=fopen(filename,"wb");
- if(fp==NULL) return;
+ if(fp==NULL) return -1;
SaveParse(cfgst,fp);
#ifdef GP2X
sync();
#endif
+ return 0;
}
static void LoadParse(CFGSTRUCT *cfgst, FILE *fp)
} while(cfgst[x].ptr);
}
-void LoadFCEUConfig(char *filename, CFGSTRUCT *cfgst)
+int LoadFCEUConfig(char *filename, CFGSTRUCT *cfgst)
{
FILE *fp;
fp=fopen(filename,"rb");
- if(fp==NULL) return;
+ if(fp==NULL) return -1;
LoadParse(cfgst,fp);
fclose(fp);
+ return 0;
}
int len;
} CFGSTRUCT;
-void SaveFCEUConfig(char *filename, CFGSTRUCT *cfgst);
-void LoadFCEUConfig(char *filename, CFGSTRUCT *cfgst);
+int SaveFCEUConfig(char *filename, CFGSTRUCT *cfgst);
+int LoadFCEUConfig(char *filename, CFGSTRUCT *cfgst);
/* Macros for building CFGSTRUCT structures. */
#define ADDCFGSTRUCT(x) { 0,&x,0 }
/* Oops. The NAC* macros shouldn't have the # in front of the w, but
- fixing this would break configuration files of previous versions and it
+ fixing this would break configuration files of previous versions and it
isn't really hurting much.
*/
}
}
+ if (Settings.accurate_mode && Settings.scaling < 2)
+ {
+ int i, *p = (int *)gp2x_screen + 32/4;
+ if (srendline > 0)
+ for (i = srendline; i > 0; i--, p += 320/4)
+ memset32(p, 0, 256/4);
+ if (erendline < 239)
+ {
+ int *p = (int *)gp2x_screen + erendline*320/4 + 32/4;
+ for (i = 239-srendline; i > 0; i--, p += 320/4)
+ memset32(p, 0, 256/4);
+ }
+ }
+
printFps(gp2x_screen);
if (Settings.scaling == 3)
AC(Settings.mmuhack),
AC(Settings.ramtimings),
AC(Settings.gamma),
- // TODO
+ AC(Settings.perfect_vsync),
+ AC(Settings.accurate_mode),
ENDCFGSTRUCT
};
ENDCFGSTRUCT
};
-void SaveConfig(const char *name)
+static const char *skip_path(const char *path)
{
+ const char *p;
+ if (path == NULL) return NULL;
+ for (p = path+strlen(path)-1; p > path && *p != '/'; p--);
+ if (*p == '/') p++;
+ return p;
+}
+
+int SaveConfig(const char *llgn_path)
+{
+ const char *name = skip_path(llgn_path);
char tdir[2048];
+ int ret;
if (name)
sprintf(tdir,"%s"PSS"cfg"PSS"%s.cfg",BaseDirectory,name);
else sprintf(tdir,"%s"PSS"fceu2.cfg",BaseDirectory);
+ printf("saving cfg to %s ... ", tdir); fflush(stdout);
FCEUI_GetNTSCTH(&ntsctint, &ntschue);
- SaveFCEUConfig(tdir,fceuconfig);
+ ret=SaveFCEUConfig(tdir,fceuconfig);
+ printf(ret == 0 ? "done\n" : "failed\n");
+ return ret;
}
-static void LoadConfig(const char *name)
+static int LoadConfig(const char *llgn_path)
{
+ const char *name = skip_path(llgn_path);
char tdir[2048];
+ int ret;
if (name)
sprintf(tdir,"%s"PSS"cfg"PSS"%s.cfg",BaseDirectory,name);
else sprintf(tdir,"%s"PSS"fceu2.cfg",BaseDirectory);
+ printf("loading cfg from %s ... ", tdir); fflush(stdout);
FCEUI_GetNTSCTH(&ntsctint, &ntschue); /* Get default settings for if no config file exists. */
- LoadFCEUConfig(tdir,fceuconfig);
+ ret=LoadFCEUConfig(tdir,fceuconfig);
FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
+ printf(ret == 0 ? "done\n" : "failed\n");
+ return ret;
}
static void LoadLLGN(void)
int CLImain(int argc, char *argv[])
{
- int last_arg_parsed;
+ int last_arg_parsed, ret;
/* TODO if(argc<=1)
{
ShowUsage(argv[0]);
{
if (fceugi)
CloseGame();
- LoadConfig(lastLoadedGameName);
+ ret=LoadConfig(lastLoadedGameName);
+ if (ret != 0)
+ {
+ LoadConfig(NULL);
+ }
FCEUI_SetEmuMode(Settings.accurate_mode);
fceugi=FCEUI_LoadGame(lastLoadedGameName);
if (fceugi)
extern FCEUGI *fceugi;
-void SaveConfig(const char *name);
+int SaveConfig(const char *name);
gp2x_text_out15(x,y,buffer);\r
}\r
\r
-static void gp2x_smalltext16(int x, int y, const char *texto)\r
+static void gp2x_smalltext16(int x, int y, const char *texto, unsigned short color)\r
{\r
int i;\r
unsigned char *src;\r
int w = 0x20;\r
while (w)\r
{\r
- if( *src & w ) *dst = 0xffff;\r
+ if( *src & w ) *dst = color;\r
dst++;\r
w>>=1;\r
}\r
}\r
}\r
\r
-static void gp2x_smalltext16_lim(int x, int y, const char *texto, int max)\r
+static void gp2x_smalltext16_lim(int x, int y, const char *texto, unsigned short color, int max)\r
{\r
char buffer[320/6+1];\r
\r
if (max < 0) max = 0;\r
buffer[max] = 0;\r
\r
- gp2x_smalltext16(x, y, buffer);\r
+ gp2x_smalltext16(x, y, buffer, color);\r
}\r
\r
\r
\r
// -------------- ROM selector --------------\r
\r
+// rrrr rggg gggb bbbb\r
+static unsigned short file2color(const char *fname)\r
+{\r
+ const char *ext = fname + strlen(fname) - 3;\r
+ static const char *rom_exts[] = { "zip", "nes", "fds", "unf", "nez", "nif" }; // nif is for unif\r
+ static const char *other_exts[] = { "nsf", "ips", "fcm" };\r
+ int i;\r
+\r
+ if (ext < fname) ext = fname;\r
+ for (i = 0; i < sizeof(rom_exts)/sizeof(rom_exts[0]); i++)\r
+ if (strcasecmp(ext, rom_exts[i]) == 0) return 0xbdff;\r
+ for (i = 0; i < sizeof(other_exts)/sizeof(other_exts[0]); i++)\r
+ if (strcasecmp(ext, other_exts[i]) == 0) return 0xaff5;\r
+ return 0xffff;\r
+}\r
+\r
static void draw_dirlist(char *curdir, struct dirent **namelist, int n, int sel)\r
{\r
int start, i, pos;\r
gp2x_fceu_darken_all();\r
\r
if(start - 2 >= 0)\r
- gp2x_smalltext16_lim(14, (start - 2)*10, curdir, 53-2);\r
+ gp2x_smalltext16_lim(14, (start - 2)*10, curdir, 0xffff, 53-2);\r
for (i = 0; i < n; i++) {\r
pos = start + i;\r
if (pos < 0) continue;\r
if (pos > 23) break;\r
if (namelist[i+1]->d_type == DT_DIR) {\r
- gp2x_smalltext16_lim(14, pos*10, "/", 1);\r
- gp2x_smalltext16_lim(14+6, pos*10, namelist[i+1]->d_name, 53-3);\r
+ gp2x_smalltext16_lim(14, pos*10, "/", 0xfff6, 1);\r
+ gp2x_smalltext16_lim(14+6, pos*10, namelist[i+1]->d_name, 0xfff6, 53-3);\r
} else {\r
- gp2x_smalltext16_lim(14, pos*10, namelist[i+1]->d_name, 53-2);\r
+ unsigned short color = file2color(namelist[i+1]->d_name);\r
+ gp2x_smalltext16_lim(14, pos*10, namelist[i+1]->d_name, color, 53-2);\r
}\r
}\r
gp2x_text_out15(5, 120, ">");\r
if (pos < 0) return 1;\r
if (pos > 23) return 0;\r
\r
- gp2x_smalltext16_lim(14, pos*10, s ? "ON " : "OFF", 3);\r
- gp2x_smalltext16_lim(14+6*4, pos*10, type ? "S" : "R", 1);\r
- gp2x_smalltext16_lim(14+6*6, pos*10, name, 53-8);\r
+ gp2x_smalltext16_lim(14, pos*10, s ? "ON " : "OFF", 0xffff, 3);\r
+ gp2x_smalltext16_lim(14+6*4, pos*10, type ? "S" : "R", 0xffff, 1);\r
+ gp2x_smalltext16_lim(14+6*6, pos*10, name, 0xffff, 53-8);\r
\r
return 1;\r
}\r
FCEUI_ListCheats(clistcallb,0);\r
\r
pos = cheat_start + cheat_pos;\r
- if (pos < 24) gp2x_smalltext16_lim(14, pos*10, "done", 4);\r
+ if (pos < 24) gp2x_smalltext16_lim(14, pos*10, "done", 0xffff, 4);\r
\r
gp2x_text_out15(5, 120, ">");\r
menu_flip();\r
if(inp & GP2X_B) {\r
switch (menu_sel) {\r
case 0: key_config_loop(ctrl_actions, 10, 0); return;\r
- case 1: key_config_loop(ctrl_actions, 8, 1); return;\r
+ case 1: key_config_loop(ctrl_actions, 10, 1); return;\r
case 2: key_config_loop(emuctrl_actions,\r
sizeof(emuctrl_actions)/sizeof(emuctrl_actions[0]), -1); return;\r
case 3: if (!fceugi) SaveConfig(NULL); return;\r
static int menu_loop_options(void)\r
{\r
static int menu_sel = 0;\r
- int menu_sel_max = 16;\r
+ int ret, menu_sel_max = 16;\r
unsigned long inp = 0;\r
\r
if (fceugi) menu_sel_max++;\r
case 15: fcemenu_loop_options(); break;\r
case 16: // done (update and write)\r
config_commit();\r
- SaveConfig(NULL);\r
+ ret = SaveConfig(NULL);\r
+ strcpy(menuErrorMsg, ret == 0 ? "default config saved" : "config save failed");\r
return 1;\r
case 17: // done (update and write for current game)\r
- config_commit();\r
if (lastLoadedGameName[0])\r
- SaveConfig(lastLoadedGameName);\r
+ {\r
+ config_commit();\r
+ ret = SaveConfig(lastLoadedGameName);\r
+ strcpy(menuErrorMsg, ret == 0 ? "game config saved" : "config save failed");\r
+ }\r
return 1;\r
}\r
}\r
#include "file.h"
#include "crc32.h"
#include "ppu.h"
+#include "ppu098.h"
#include "palette.h"
#include "movie.h"
int use098code = 0;
void (*ResetNES)(void) = 0;
-void (*PowerNES)(void) = 0;
void (*FCEUI_Emulate)(void) = 0;
void FCEUI_SetEmuMode(int is_new)
if (is_new)
{
ResetNES=ResetNES098;
- PowerNES=PowerNES098;
FCEUI_Emulate=FCEUI_Emulate098;
}
else
{
ResetNES=ResetNES081;
- PowerNES=PowerNES081;
FCEUI_Emulate=EmLoop;
}
}
}
#endif
-void PowerNES081(void)
+void PowerNES(void)
{
if(!GameLoaded) return;
ResetMapping();
PowerSound();
PowerPPU();
+
+ if (use098code)
+ FCEUPPU_Power();
+
+ /* Have the external game hardware "powered" after the internal NES stuff.
+ Needed for the NSF code and VS System code.
+ */
GameInterface(GI_POWER, 0);
if(FCEUGameInfo.type==GIT_VSUNI)
FCEU_VSUniPower();
void ResetMapping(void);
extern void (*ResetNES)(void);
-extern void (*PowerNES)(void);
void ResetNES081(void);
-void PowerNES081(void);
+void PowerNES(void);
extern uint64 timestampbase;
void ResetNES098(void)
{
ResetNES081();
+ // it was decided not to use 098 sound because of problems it causes
//FCEUSND_Reset();
FCEUPPU_Reset();
}
-
-void PowerNES098(void)
-{
- PowerNES081();
- // it was decided not to use 098 sound because of problems it causes
- //FCEUSND_Power();
- FCEUPPU_Power();
-}
-
int FCEUI_Initialize098(void);
void FCEUI_Emulate098(void);
void ResetNES098(void);
-void PowerNES098(void);
BigBad.nes BigBad.pal\r
BigBad.zip BigBad.pal\r
BigBad.Better.nes BigBad.Better.pal\r
- \r
+\r
\r
With so many ways to choose a palette, figuring out which one will be active may be difficult. Here's a list of what palettes will be used, in order from highest priority to least priority(if a condition doesn't exist for a higher priority palette, the emulator will continue down its list of palettes).\r
\r
\r
\r
[FCM movies]\r
-Version 0.4 has partial FCM movie support. Most of the movies desync due to different timing, but some of them can be played. There is only playback support. Files should be placed in the ROMs directory along with the ROMs themselves. Naming is the same as for IPS patches (see previous section), buf use .fcm extension instead of .ips.\r
+Version 0.4 has partial FCM movie support. Most of the movies desync due to different timing, but some of them can be played. Note that 'accurate renderer' option solves some desync problems. There is only playback support. Files should be placed in the ROMs directory along with the ROMs themselves. Naming is the same as for IPS patches (see previous section), buf use .fcm extension instead of .ips.\r
\r
\r
[Credits/thanks]\r
BigBad.nes BigBad.pal\r
BigBad.zip BigBad.pal\r
BigBad.Better.nes BigBad.Better.pal\r
- \r
+\r
\r
With so many ways to choose a palette, figuring out which one will be active may\r
be difficult. Here's a list of what palettes will be used, in order from highest\r
------------------------------------------------------------------\r
\r
Version 0.4 has partial FCM movie support. Most of the movies desync due to\r
-different timing, but some of them can be played. There is only playback support.\r
+different timing, but some of them can be played. Note that 'accurate renderer'\r
+option solves some desync problems. There is only playback support.\r
Files should be placed in the ROMs directory along with the ROMs themselves.\r
Naming is the same as for IPS patches (see previous section), buf use .fcm\r
extension instead of .ips.\r
\r
\r
ver 0.4 (by notaz)\r
+ rev 171\r
+ - Added optional "Accurate renderer", which is the original FCE Ultra\r
+ 0.98.x renderer + PPU emulation code. It's much slower, but it can\r
+ handle games which need more precise PPU timing emulation (like\r
+ Marble Madness).\r
+ - Fixed saving and loading of game specific configs.\r
+ - Some other minor changes.\r
rev 163\r
- Added A r k's fast-direction-change fix for usbjoy lib.\r
- Fixed an issue of usbjoys stopping to work when "Perfect vsync"\r
Plinef=target;
Pline=target;
firsttile=0;
- linestartts=timestamp*48+X.count;
+ linestartts=timestamp*48+X6502_GetCycleCount();
tofix=0;
FCEUPPU_LineUpdate098();
tofix=1;
if(!ScreenON && !SpriteON)
{
uint32 tem;
+ int tiles;
tem=Pal[0]|(Pal[0]<<8)|(Pal[0]<<16)|(Pal[0]<<24);
tem|=0x40404040;
- FCEU_dwmemset(Pline,tem,numtiles*8);
+ tiles=numtiles;
+ if(firsttile+tiles > 256/8) tiles=256/8-firsttile;
+ if(tiles > 0)
+ FCEU_dwmemset(Pline,tem,tiles*8);
P+=numtiles*8;
Pline=P;