diff --git a/pico/cart.c b/pico/cart.c
index 26fb59bb..45f3866f 100644
--- a/pico/cart.c
+++ b/pico/cart.c
@@ -21,7 +21,7 @@ void (*PicoCartMemSetup)(void);
void (*PicoCartLoadProgressCB)(int percent) = NULL;
void (*PicoCDLoadProgressCB)(const char *fname, int percent) = NULL; // handled in Pico/cd/cd_file.c
-static void PicoCartDetect(void);
+static void PicoCartDetect(const char *carthw_cfg);
/* cso struct */
typedef struct _cso_struct
@@ -541,7 +541,7 @@ int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms)
}
// Insert a cartridge:
-int PicoCartInsert(unsigned char *rom,unsigned int romsize)
+int PicoCartInsert(unsigned char *rom, unsigned int romsize, const char *carthw_cfg)
{
// notaz: add a 68k "jump one op back" opcode to the end of ROM.
// This will hang the emu, but will prevent nasty crashes.
@@ -572,7 +572,7 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
carthw_chunks = NULL;
if (!(PicoAHW & (PAHW_MCD|PAHW_SMS)))
- PicoCartDetect();
+ PicoCartDetect(carthw_cfg);
// setup correct memory map for loaded ROM
switch (PicoAHW) {
@@ -695,16 +695,16 @@ static int is_expr(const char *expr, char **pr)
return 1;
}
-static void parse_carthw(int *fill_sram)
+static void parse_carthw(const char *carthw_cfg, int *fill_sram)
{
int line = 0, any_checks_passed = 0, skip_sect = 0;
int tmp, rom_crc = 0;
char buff[256], *p, *r;
FILE *f;
- f = fopen("carthw.cfg", "r");
+ f = fopen(carthw_cfg, "r");
if (f == NULL) {
- elprintf(EL_STATUS, "couldn't open carthw.txt!");
+ elprintf(EL_STATUS, "couldn't open carthw.cfg!");
return;
}
@@ -924,7 +924,7 @@ no_checks:
/*
* various cart-specific things, which can't be handled by generic code
*/
-static void PicoCartDetect(void)
+static void PicoCartDetect(const char *carthw_cfg)
{
int fill_sram = 0;
@@ -954,7 +954,8 @@ static void PicoCartDetect(void)
SRam.eeprom_bit_in = 0;
SRam.eeprom_bit_out= 0;
- parse_carthw(&fill_sram);
+ if (carthw_cfg != NULL)
+ parse_carthw(carthw_cfg, &fill_sram);
if (SRam.flags & SRF_ENABLED)
{
diff --git a/pico/draw.c b/pico/draw.c
index 180045d2..c432bd57 100644
--- a/pico/draw.c
+++ b/pico/draw.c
@@ -54,6 +54,7 @@ int HighPreSpr[80*2+1]; // slightly preprocessed sprites
unsigned char HighLnSpr[240][3 + MAX_LINE_SPRITES]; // sprite_count, ^flags, tile_count, [spritep]...
int rendstatus, rendstatus_old;
+int rendlines;
int DrawScanline;
int PicoDrawMask = -1;
@@ -1404,21 +1405,25 @@ static int DrawDisplay(int sh)
// MUST be called every frame
PICO_INTERNAL void PicoFrameStart(void)
{
+ int lines = 224;
+
// prepare to do this frame
rendstatus = 0;
- if ((Pico.video.reg[12]&6) == 6)
+ if ((Pico.video.reg[12] & 6) == 6)
rendstatus |= PDRAW_INTERLACE; // interlace mode
+ if (!(Pico.video.reg[12] & 1))
+ rendstatus |= PDRAW_32_COLS;
if (Pico.video.reg[1] & 8)
- rendstatus |= PDRAW_240LINES;
+ lines = 240;
DrawScanline = 0;
skip_next_line = 0;
- if (rendstatus != rendstatus_old) {
+ if (rendstatus != rendstatus_old || lines != rendlines) {
+ rendlines = lines;
rendstatus_old = rendstatus;
- emu_video_mode_change((rendstatus & PDRAW_240LINES) ? 0 : 8,
- (rendstatus & PDRAW_240LINES) ? 240 : 224,
- (Pico.video.reg[12] & 1) ? 0 : 1);
+ emu_video_mode_change((lines == 240) ? 0 : 8,
+ lines, (Pico.video.reg[12] & 1) ? 0 : 1);
}
if (PicoOpt & POPT_ALT_RENDERER)
@@ -1445,6 +1450,8 @@ static void DrawBlankedLine(int line, int offs, int sh, int bgc)
static void PicoLine(int line, int offs, int sh, int bgc)
{
+ int skip = 0;
+
if (skip_next_line > 0) {
skip_next_line--;
return;
@@ -1452,7 +1459,12 @@ static void PicoLine(int line, int offs, int sh, int bgc)
DrawScanline = line;
if (PicoScanBegin != NULL)
- skip_next_line = PicoScanBegin(line + offs);
+ skip = PicoScanBegin(line + offs);
+
+ if (skip) {
+ skip_next_line = skip - 1;
+ return;
+ }
// Draw screen:
BackFill(bgc, sh);
@@ -1472,7 +1484,7 @@ void PicoDrawSync(int to, int blank_last_line)
int sh = (Pico.video.reg[0xC] & 8) >> 3; // shadow/hilight?
int bgc = Pico.video.reg[7];
- if (!(rendstatus & PDRAW_240LINES))
+ if (rendlines != 240)
offs = 8;
// need to know which pixels are bg for 32x
diff --git a/pico/mode4.c b/pico/mode4.c
index 104cf498..1462dde5 100644
--- a/pico/mode4.c
+++ b/pico/mode4.c
@@ -193,11 +193,10 @@ void PicoFrameStartMode4(void)
int lines = 192;
skip_next_line = 0;
screen_offset = 24;
- rendstatus = 0;
+ rendstatus = PDRAW_32_COLS;
if ((Pico.video.reg[0] & 6) == 6 && (Pico.video.reg[1] & 0x18)) {
if (Pico.video.reg[1] & 0x08) {
- rendstatus |= PDRAW_240LINES;
screen_offset = 0;
lines = 240;
}
@@ -207,8 +206,9 @@ void PicoFrameStartMode4(void)
}
}
- if (rendstatus != rendstatus_old) {
+ if (rendstatus != rendstatus_old || lines != rendlines) {
rendstatus_old = rendstatus;
+ rendlines = lines;
emu_video_mode_change(screen_offset, lines, 1);
}
}
diff --git a/pico/pico.h b/pico/pico.h
index 05f9fab6..c274b806 100644
--- a/pico/pico.h
+++ b/pico/pico.h
@@ -34,7 +34,7 @@ extern void cache_flush_d_inval_i(const void *start_addr, const void *end_addr);
// this one should handle display mode changes
extern void emu_video_mode_change(int start_line, int line_count, int is_32cols);
-// this must switch to 32bpp mode
+// this must switch to 16bpp mode
extern void emu_32x_startup(void);
// optional 32X BIOS, should be left NULL if not used
@@ -149,7 +149,7 @@ size_t pm_read(void *ptr, size_t bytes, pm_file *stream);
int pm_seek(pm_file *stream, long offset, int whence);
int pm_close(pm_file *fp);
int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms);
-int PicoCartInsert(unsigned char *rom,unsigned int romsize);
+int PicoCartInsert(unsigned char *rom, unsigned int romsize, const char *carthw_cfg);
void PicoCartUnload(void);
extern void (*PicoCartLoadProgressCB)(int percent);
extern void (*PicoCDLoadProgressCB)(const char *fname, int percent);
@@ -184,8 +184,9 @@ extern int PicoDrawMask;
#define PDRAW_SONIC_MODE (1<<5) // mid-frame palette changes for 8bit renderer
#define PDRAW_PLANE_HI_PRIO (1<<6) // have layer with all hi prio tiles (mk3)
#define PDRAW_SHHI_DONE (1<<7) // layer sh/hi already processed
-#define PDRAW_240LINES (1<<8) // 240 line display (224 if not set)
+#define PDRAW_32_COLS (1<<8) // 32 column mode
extern int rendstatus, rendstatus_old;
+extern int rendlines;
extern unsigned short HighPal[0x100];
// Draw2.c
diff --git a/platform/common/emu.c b/platform/common/emu.c
index a8de9023..370242dc 100644
--- a/platform/common/emu.c
+++ b/platform/common/emu.c
@@ -41,9 +41,11 @@ int pico_pen_x = 320/2, pico_pen_y = 240/2;
int pico_inp_mode = 0;
int engineState = PGS_Menu;
+/* tmp buff to reduce stack usage for plats with small stack */
+static char static_buff[512];
/* TODO: len checking */
-char rom_fname_reload[512] = { 0, };
-char rom_fname_loaded[512] = { 0, };
+char rom_fname_reload[512];
+char rom_fname_loaded[512];
int rom_loaded = 0;
int reset_timing = 0;
static unsigned int notice_msg_time; /* when started showing */
@@ -113,7 +115,6 @@ static const char * const biosfiles_jp[] = { "jp_mcd1_9112", "jp_mcd1_9111" };
static int find_bios(int region, char **bios_file)
{
- static char bios_path[1024];
int i, count;
const char * const *files;
FILE *f = NULL;
@@ -133,26 +134,27 @@ static int find_bios(int region, char **bios_file)
for (i = 0; i < count; i++)
{
- emu_make_path(bios_path, files[i], sizeof(bios_path) - 4);
- strcat(bios_path, ".bin");
- f = fopen(bios_path, "rb");
+ emu_make_path(static_buff, files[i], sizeof(static_buff) - 4);
+ strcat(static_buff, ".bin");
+ f = fopen(static_buff, "rb");
if (f) break;
- bios_path[strlen(bios_path) - 4] = 0;
- strcat(bios_path, ".zip");
- f = fopen(bios_path, "rb");
+ static_buff[strlen(static_buff) - 4] = 0;
+ strcat(static_buff, ".zip");
+ f = fopen(static_buff, "rb");
if (f) break;
}
if (f) {
- lprintf("using bios: %s\n", bios_path);
+ lprintf("using bios: %s\n", static_buff);
fclose(f);
- if (bios_file) *bios_file = bios_path;
+ if (bios_file)
+ *bios_file = static_buff;
return 1;
} else {
- sprintf(bios_path, "no %s BIOS files found, read docs",
+ sprintf(static_buff, "no %s BIOS files found, read docs",
region != 4 ? (region == 8 ? "EU" : "JAP") : "USA");
- me_update_msg(bios_path);
+ me_update_msg(static_buff);
return 0;
}
}
@@ -560,6 +562,7 @@ int emu_reload_rom(char *rom_fname)
}
menu_romload_prepare(used_rom_name); // also CD load
+ used_rom_name = NULL; // uses static_buff
ret = PicoCartLoad(rom, &rom_data, &rom_size, (PicoAHW & PAHW_SMS) ? 1 : 0);
pm_close(rom);
@@ -594,7 +597,8 @@ int emu_reload_rom(char *rom_fname)
if (!ret) emu_read_config(0, 0);
}
- if (PicoCartInsert(rom_data, rom_size)) {
+ emu_make_path(static_buff, "carthw.cfg", sizeof(static_buff));
+ if (PicoCartInsert(rom_data, rom_size, static_buff)) {
me_update_msg("Failed to load ROM.");
goto fail;
}
@@ -700,6 +704,7 @@ static void romfname_ext(char *dst, const char *prefix, const char *ext)
if (ext) strcat(dst, ext);
}
+//
void emu_make_path(char *buff, const char *end, int size)
{
int pos, end_len;
@@ -907,7 +912,7 @@ static int try_ropen_file(const char *fname)
char *emu_get_save_fname(int load, int is_sram, int slot)
{
- static char saveFname[512];
+ char *saveFname = static_buff;
char ext[16];
if (is_sram)
@@ -1482,7 +1487,7 @@ void emu_loop(void)
pframes_done++; frames_done++;
diff_lim += target_frametime;
- if (!(currentConfig.EmuOpt & EOPT_NO_FRMLIMIT)) {
+ if (!(currentConfig.EmuOpt & (EOPT_NO_FRMLIMIT|EOPT_EXT_FRMLIMIT))) {
timestamp = get_ticks();
diff = timestamp - timestamp_base;
if (!reset_timing && diff < diff_lim) // we are too fast
@@ -1508,7 +1513,7 @@ void emu_loop(void)
PicoFrame();
/* frame limiter */
- if (!reset_timing && !(currentConfig.EmuOpt & EOPT_NO_FRMLIMIT))
+ if (!reset_timing && !(currentConfig.EmuOpt & (EOPT_NO_FRMLIMIT|EOPT_EXT_FRMLIMIT)))
{
timestamp = get_ticks();
diff = timestamp - timestamp_base;
diff --git a/platform/common/emu.h b/platform/common/emu.h
index 5b695ef9..b4984889 100644
--- a/platform/common/emu.h
+++ b/platform/common/emu.h
@@ -41,6 +41,7 @@ extern int g_screen_height;
#define EOPT_SHOW_RTC (1<<17)
#define EOPT_NO_FRMLIMIT (1<<18)
#define EOPT_WIZ_TEAR_FIX (1<<19)
+#define EOPT_EXT_FRMLIMIT (1<<20) // no internal frame limiter (limited by snd, etc)
enum {
EOPT_SCALE_NONE = 0,