if (f == NULL)\r
goto cso_failed;\r
\r
+#ifndef __EPOC32__\r
/* we use our own buffering */\r
setvbuf(f, NULL, _IONBF, 0);\r
+#endif\r
\r
cso = malloc(sizeof(*cso));\r
if (cso == NULL)\r
f = fopen(path, "rb");\r
if (f == NULL) return NULL;\r
\r
- /* we use our own buffering */\r
- setvbuf(f, NULL, _IONBF, 0);\r
-\r
file = malloc(sizeof(*file));\r
if (file == NULL) {\r
fclose(f);\r
file->type = PMT_UNCOMPRESSED;\r
fseek(f, 0, SEEK_SET);\r
\r
+#ifndef __EPOC32__ // makes things worse on Symbian\r
+ if (file->size > 0x400000)\r
+ /* we use our own buffering */\r
+ setvbuf(f, NULL, _IONBF, 0);\r
+#endif\r
+\r
return file;\r
}\r
\r
rom=PicoCartAlloc(size);\r
if (rom==NULL) {\r
elprintf(EL_STATUS, "out of memory (wanted %i)", size);\r
- return 1;\r
+ return 2;\r
}\r
\r
if (PicoCartLoadProgressCB != NULL)\r
if (bytes_read <= 0) {\r
elprintf(EL_STATUS, "read failed");\r
free(rom);\r
- return 1;\r
+ return 3;\r
}\r
\r
// maybe we are loading MegaCD BIOS?\r
sprintf(dstrp, "z80Run: %i, z80_reset: %i, z80_bnk: %06x\n", Pico.m.z80Run, Pico.m.z80_reset, Pico.m.z80_bank68k<<15); MVP;
z80_debug(dstrp); MVP;
if (strlen(dstr) > sizeof(dstr))
- printf("warning: debug buffer overflow (%i/%i)\n", strlen(dstr), sizeof(dstr));
+ elprintf(EL_STATUS, "warning: debug buffer overflow (%i/%i)\n", strlen(dstr), sizeof(dstr));
return dstr;
}
}\r
}\r
}\r
-#endif\r
+#endif // !_ASM_DRAW_C\r
\r
static void DrawSpritesHiAS(unsigned char *sprited, int sh)\r
{\r
cnt = sprited[0] & 0x7f;\r
if (cnt == 0) return;\r
\r
+ rendstatus |= PDRAW_SPR_LO_ON_HI;\r
+\r
p = &sprited[3];\r
\r
// Go through sprites:\r
}\r
}\r
\r
- if (!sh && (rendstatus & PDRAW_ACC_SPRITES))\r
+ if (!sh && (rendstatus & PDRAW_SPR_LO_ON_HI))\r
mask=0x3f; // accurate sprites\r
\r
for(i = 0; i < len; i++)\r
{\r
#ifndef PSP\r
int i, mask=0xff;\r
- if (!sh && (rendstatus & PDRAW_ACC_SPRITES))\r
+ if (!sh && (rendstatus & PDRAW_SPR_LO_ON_HI))\r
mask=0x3f; // accurate sprites, upper bits are priority stuff\r
\r
for (i = 0; i < len; i++)\r
#else\r
extern void amips_clut(unsigned short *dst, unsigned char *src, unsigned short *pal, int count);\r
extern void amips_clut_6bit(unsigned short *dst, unsigned char *src, unsigned short *pal, int count);\r
- if (!sh && (rendstatus & PDRAW_ACC_SPRITES))\r
+ if (!sh && (rendstatus & PDRAW_SPR_LO_ON_HI))\r
amips_clut_6bit(pd, ps, pal, len);\r
else amips_clut(pd, ps, pal, len);\r
#endif\r
int len, rs = rendstatus;\r
static int dirty_count;\r
\r
- if (!sh && !(rs & PDRAW_ACC_SPRITES) && Pico.m.dirtyPal == 1 && DrawScanline < 222)\r
+ if (!sh && Pico.m.dirtyPal == 1 && DrawScanline < 222)\r
{\r
// a hack for mid-frame palette changes\r
if (!(rs & PDRAW_SONIC_MODE))\r
if (!(PicoDrawMask & PDRAW_SPRITES_HI_ON));\r
else if (rendstatus & PDRAW_INTERLACE)\r
DrawAllSpritesInterlace(1, sh);\r
- // AS on and have both lo/hi sprites and lo before hi sprites?\r
- else if ((sprited[1] & 0xd0) == 0xd0 && (rendstatus & PDRAW_ACC_SPRITES))\r
+ // have sprites without layer pri bit ontop of sprites with that bit\r
+ else if ((sprited[1] & 0xd0) == 0xd0 && (PicoOpt & POPT_ACC_SPRITES))\r
DrawSpritesHiAS(sprited, sh);\r
else if (sh && (sprited[1] & SPRL_MAY_HAVE_OP))\r
DrawSpritesSHi(sprited);\r
return 0;\r
}\r
\r
-\r
+// MUST be called every frame\r
PICO_INTERNAL void PicoFrameStart(void)\r
{\r
// prepare to do this frame\r
rendstatus = 0;\r
- if (PicoOpt & POPT_ACC_SPRITES)\r
- rendstatus |= PDRAW_ACC_SPRITES;\r
if ((Pico.video.reg[12]&6) == 6)\r
rendstatus |= PDRAW_INTERLACE; // interlace mode\r
\r
pc&=~1;\r
if ((pc<<8) == 0)\r
{\r
- printf("%i:%03i: game crash detected @ %06x\n", Pico.m.frame_count, Pico.m.scanline, SekPc);\r
- return (int)Pico.rom + Pico.romsize; // common crash condition, can happen if acc timing is off\r
+ elprintf(EL_STATUS|EL_ANOMALY, "%i:%03i: game crash detected @ %06x\n",\r
+ Pico.m.frame_count, Pico.m.scanline, SekPc);\r
+ return (int)Pico.rom + Pico.romsize; // common crash condition, may happen with bad ROMs\r
}\r
\r
PicoCpuCM68k.membase=PicoMemBase(pc&0x00ffffff);\r
// internals\r
#define PDRAW_SPRITES_MOVED (1<<0) // (asm)\r
#define PDRAW_WND_DIFF_PRIO (1<<1) // not all window tiles use same priority\r
-#define PDRAW_ACC_SPRITES (1<<2) // accurate sprites (copied from PicoOpt)\r
+#define PDRAW_SPR_LO_ON_HI (1<<2) // seen sprites without layer pri bit ontop spr. with that bit\r
#define PDRAW_INTERLACE (1<<3)\r
#define PDRAW_DIRTY_SPRITES (1<<4) // (asm)\r
#define PDRAW_SONIC_MODE (1<<5) // mid-frame palette changes for 8bit renderer\r
PICO_INTERNAL void z80_exit(void);\r
extern int PsndDacLine;\r
\r
-#ifdef __cplusplus\r
-} // End of extern "C"\r
-#endif\r
-\r
// emulation event logging\r
#ifndef EL_LOGMASK\r
#define EL_LOGMASK 0\r
#define cdprintf(x...)\r
#endif\r
\r
+#ifdef __cplusplus\r
+} // End of extern "C"\r
+#endif\r
+\r
#endif // PICO_INTERNAL_INCLUDED\r
\r
// check if there are enough cycles..
// note: r0 must contain PC of current block
EOP_CMP_IMM(11,0,0); // cmp r11, #0
- emit_call(A_COND_LE, ssp_drc_end);
+ emit_jump(A_COND_LE, ssp_drc_end);
}
/* cond:
if (target != NULL)
emit_jump(A_COND_AL, target);
else {
- emit_jump(A_COND_AL, ssp_drc_next);
- // cause the next block to be emitted over jump instrction
- tcache_ptr--;
+ int ops = emit_jump(A_COND_AL, ssp_drc_next);
+ // cause the next block to be emitted over jump instruction
+ tcache_ptr -= ops;
}
}
else {
- u32 *target1 = (pc < 0x400) ? ssp_block_table_iram[ssp->drc.iram_context][pc] : ssp_block_table[pc];
+ u32 *target1 = (pc < 0x400) ? ssp_block_table_iram[ssp->drc.iram_context][pc] : ssp_block_table[pc];
u32 *target2 = (end_pc < 0x400) ? ssp_block_table_iram[ssp->drc.iram_context][end_pc] : ssp_block_table[end_pc];
if (target1 != NULL)
emit_jump(cond, target1);
- else emit_call(cond, ssp_drc_next_patch);
if (target2 != NULL)
emit_jump(tr_neg_cond(cond), target2); // neg_cond, to be able to swap jumps if needed
- else emit_call(tr_neg_cond(cond), ssp_drc_next_patch);
+#ifndef __EPOC32__
+ // emit patchable branches
+ if (target1 == NULL)
+ emit_call(cond, ssp_drc_next_patch);
+ if (target2 == NULL)
+ emit_call(tr_neg_cond(cond), ssp_drc_next_patch);
+#else
+ // won't patch indirect jumps
+ if (target1 == NULL || target2 == NULL)
+ emit_jump(A_COND_AL, ssp_drc_next);
+#endif
}
}
int ret, end_cond = A_COND_AL, jump_pc = -1;
//printf("translate %04x -> %04x\n", pc<<1, (tcache_ptr-tcache)<<2);
+
block_start = tcache_ptr;
known_regb = 0;
dirty_regb = KRREG_P;
emit_block_epilogue(ccount, end_cond, jump_pc, pc);
if (tcache_ptr - tcache > SSP_TCACHE_SIZE/4) {
- elprintf(EL_ANOMALY, "tcache overflow!\n");
+ elprintf(EL_ANOMALY|EL_STATUS|EL_SVP, "tcache overflow!\n");
fflush(stdout);
exit(1);
}
memset(svp->iram_rom, 0, 0x800);
}
+
void ssp1601_dyn_run(int cycles)
{
if (ssp->emu_status & SSP_WAIT_MASK) return;
EOP_C_DOP_IMM(cond, need_or ? A_OP_ORR : A_OP_MOV, 0, need_or ? d : 0, d, 0, val&0xff);
}
-static void check_offset_24(int val)
+static int is_offset_24(int val)
{
- if (val >= (int)0xff000000 && val <= 0x00ffffff) return;
- printf("offset_24 overflow %08x\n", val);
- exit(1);
+ if (val >= (int)0xff000000 && val <= 0x00ffffff) return 1;
+ return 0;
}
-static void emit_call(int cond, void *target)
+static int emit_xbranch(int cond, void *target, int is_call)
{
int val = (unsigned int *)target - tcache_ptr - 2;
- check_offset_24(val);
+ int direct = is_offset_24(val);
+ u32 *start_ptr = tcache_ptr;
- EOP_C_B(cond,1,val & 0xffffff); // bl target
+ if (direct)
+ {
+ EOP_C_B(cond,is_call,val & 0xffffff); // b, bl target
+ }
+ else
+ {
+#ifdef __EPOC32__
+// elprintf(EL_SVP, "emitting indirect jmp %08x->%08x", tcache_ptr, target);
+ if (is_call)
+ EOP_ADD_IMM(14,15,0,8); // add lr,pc,#8
+ EOP_C_AM2_IMM(cond,1,0,1,15,15,0); // ldrcc pc,[pc]
+ EOP_MOV_REG_SIMPLE(15,15); // mov pc, pc
+ EMIT((u32)target);
+#else
+ // should never happen
+ elprintf(EL_STATUS|EL_SVP|EL_ANOMALY, "indirect jmp %08x->%08x", target, tcache_ptr);
+ exit(1);
+#endif
+ }
+
+ return tcache_ptr - start_ptr;
}
-static void emit_jump(int cond, void *target)
+static int emit_call(int cond, void *target)
{
- int val = (unsigned int *)target - tcache_ptr - 2;
- check_offset_24(val);
+ return emit_xbranch(cond, target, 1);
+}
- EOP_C_B(cond,0,val & 0xffffff); // b target
+static int emit_jump(int cond, void *target)
+{
+ return emit_xbranch(cond, target, 0);
}
static void handle_caches(void)
.space SSP_BLOCKTAB_IRAM_SIZE
.space SSP_BLOCKTAB_ALIGN_SIZE
-
.text
.align 2
@ r9: r4-r6 (.654)
@ r10: P
@ r11: cycles
+@ r12: tmp
#define SSP_OFFS_GR 0x400
bic r3, r3, #1 @ L bit
orr r3, r3, r12,lsl #6
mov r3, r3, ror #8 @ patched branch instruction
- str r3, [r1, #-4]
+ str r3, [r1, #-4] @ patch the bl/b to jump directly to another handler
ssp_drc_dp_end:
str r2, [r7, #SSP_OFFS_TMP1]
#ifdef _MSC_VER
#define snprintf _snprintf
#endif
-#ifdef UIQ3
+#ifdef __EPOC32__
#define snprintf(b,s,...) sprintf(b,##__VA_ARGS__)
#endif
The Sega/Mega CD unit had two blinking LEDs (red and green) on it. This option\r
will display them on top-left corner of the screen.\r
\r
-@@2. "CDDA audio (using mp3s)"\r
+@@2. "CDDA audio"\r
This option enables CD audio playback.\r
\r
@@2. "PCM audio"\r
There is also option to enable 6 button pad (will allow you to configure XYZ\r
keys), and an option to set turbo rate (in Hz) for turbo buttons.\r
#endif\r
+#ifndef UIQ\r
\r
\r
Cheat support\r
\r
Put the file into your ROMs directory. Then load the .pat file as you would\r
a ROM. Then Cheat Menu Option should appear in main menu.\r
+#endif\r
\r
\r
What is emulated?\r
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
-#ifdef UIQ3
+#ifdef __EPOC32__
#include <unistd.h>
#endif
#include "config.h"
\r
\r
// utilities\r
-static void strlwr_(char* string)\r
+static void strlwr_(char *string)\r
{\r
- while ( (*string++ = (char)tolower(*string)) );\r
+ char *p;\r
+ for (p = string; *p; p++)\r
+ *p = (char)tolower(*p);\r
}\r
\r
static int try_rfn_cut(char *fname)\r
return 0;\r
}\r
get_ext(rom_fname, ext);\r
+ lprintf("gmv loaded for %s\n", rom_fname);\r
}\r
else if (!strcmp(ext, ".pat"))\r
{\r
rom_loaded = 0;\r
\r
if ( (ret = PicoCartLoad(rom, &rom_data, &rom_size)) ) {\r
- sprintf(menuErrorMsg, "PicoCartLoad() failed.");\r
+ if (ret == 2) sprintf(menuErrorMsg, "Out of memory");\r
+ else if (ret == 3) sprintf(menuErrorMsg, "Read failed");\r
+ else sprintf(menuErrorMsg, "PicoCartLoad() failed.");\r
lprintf("%s\n", menuErrorMsg);\r
goto fail2;\r
}\r
} else {\r
// MXYZ SACB RLDU\r
PicoPad[0] = ~movie_data[offs] & 0x8f; // ! SCBA RLDU\r
- if(!(movie_data[offs] & 0x10)) PicoPad[0] |= 0x40; // A\r
- if(!(movie_data[offs] & 0x20)) PicoPad[0] |= 0x10; // B\r
- if(!(movie_data[offs] & 0x40)) PicoPad[0] |= 0x20; // A\r
+ if(!(movie_data[offs] & 0x10)) PicoPad[0] |= 0x40; // C\r
+ if(!(movie_data[offs] & 0x20)) PicoPad[0] |= 0x10; // A\r
+ if(!(movie_data[offs] & 0x40)) PicoPad[0] |= 0x20; // B\r
PicoPad[1] = ~movie_data[offs+1] & 0x8f; // ! SCBA RLDU\r
- if(!(movie_data[offs+1] & 0x10)) PicoPad[1] |= 0x40; // A\r
- if(!(movie_data[offs+1] & 0x20)) PicoPad[1] |= 0x10; // B\r
- if(!(movie_data[offs+1] & 0x40)) PicoPad[1] |= 0x20; // A\r
+ if(!(movie_data[offs+1] & 0x10)) PicoPad[1] |= 0x40; // C\r
+ if(!(movie_data[offs+1] & 0x20)) PicoPad[1] |= 0x10; // A\r
+ if(!(movie_data[offs+1] & 0x40)) PicoPad[1] |= 0x20; // B\r
PicoPad[0] |= (~movie_data[offs+2] & 0x0A) << 8; // ! MZYX\r
if(!(movie_data[offs+2] & 0x01)) PicoPad[0] |= 0x0400; // X\r
if(!(movie_data[offs+2] & 0x04)) PicoPad[0] |= 0x0100; // Z\r
4. "CD LEDs"\r
The Sega/Mega CD unit had two blinking LEDs (red and green) on it. This option will display them on top-left corner of the screen.\r
\r
-5. "CDDA audio (using mp3s)"\r
+5. "CDDA audio"\r
This option enables CD audio playback.\r
\r
6. "PCM audio"\r
// 8bit accurate renderer\r
if (Pico.m.dirtyPal)\r
{\r
- int pallen = 0x40;\r
+ int pallen = 0xc0;\r
Pico.m.dirtyPal = 0;\r
if (Pico.video.reg[0xC]&8) // shadow/hilight mode\r
{\r
memcpy32(localPal+0xc0, localPal+0x40, 0x40);\r
pallen = 0x100;\r
}\r
- else if (rendstatus & PDRAW_ACC_SPRITES) {\r
- vidConvCpyRGB32(localPal, Pico.cram, 0x40);\r
- memcpy32(localPal+0x40, localPal, 0x40);\r
- memcpy32(localPal+0x80, localPal, 0x40);\r
- memcpy32(localPal+0xc0, localPal, 0x40);\r
- pallen = 0x100;\r
- }\r
else if (rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes\r
vidConvCpyRGB32(localPal, Pico.cram, 0x40);\r
vidConvCpyRGB32(localPal+0x40, HighPal, 0x40);\r
vidConvCpyRGB32(localPal+0x80, HighPal+0x40, 0x40);\r
- pallen = 0xc0;\r
}\r
else {\r
vidConvCpyRGB32(localPal, Pico.cram, 0x40);\r
+ memcpy32(localPal+0x80, localPal, 0x40); // for spr prio mess\r
}\r
if (pallen > 0xc0) {\r
localPal[0xc0] = 0x0000c000;\r
//#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)
#define dprintf(x...)
+// platform
+#define PLAT_MAX_KEYS 32
+#define PLAT_HAVE_JOY 1
+#define PATH_SEP "/"
+#define PATH_SEP_C '/'
+
#endif //PORT_CONFIG_H
// 8bit accurate renderer\r
if (Pico.m.dirtyPal)\r
{\r
- int pallen = 0x40;\r
+ int pallen = 0xc0;\r
Pico.m.dirtyPal = 0;\r
if (Pico.video.reg[0xC]&8) // shadow/hilight mode\r
{\r
memcpy32(localPal+0xc0, localPal+0x40, 0x40);\r
pallen = 0x100;\r
}\r
- else if (rendstatus & PDRAW_ACC_SPRITES) {\r
- vidConvCpyRGB32(localPal, Pico.cram, 0x40);\r
- memcpy32(localPal+0x40, localPal, 0x40);\r
- memcpy32(localPal+0x80, localPal, 0x40);\r
- memcpy32(localPal+0xc0, localPal, 0x40);\r
- pallen = 0x100;\r
- }\r
else if (rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes\r
vidConvCpyRGB32(localPal, Pico.cram, 0x40);\r
vidConvCpyRGB32(localPal+0x40, HighPal, 0x40);\r
}\r
else {\r
vidConvCpyRGB32(localPal, Pico.cram, 0x40);\r
+ memcpy32(localPal+0x80, localPal, 0x40);\r
}\r
if (pallen > 0xc0) {\r
localPal[0xc0] = 0x0000c000;\r
localPal[0xe0] = 0;
localPal[0xf0] = 0x001f;
}
- else if (allow_as && (rendstatus & PDRAW_ACC_SPRITES))
+ else if (allow_as && (rendstatus & PDRAW_SPR_LO_ON_HI))
{
memcpy32((int *)dpal+0x80/2, (void *)localPal, 0x40*2/4);
}
if (Pico.m.dirtyPal)
do_pal_update(1, 1);
- if ((rendstatus & PDRAW_ACC_SPRITES) && !(Pico.video.reg[0xC]&8))
+ if ((rendstatus & PDRAW_SPR_LO_ON_HI) && !(Pico.video.reg[0xC]&8))
amips_clut_f = amips_clut_6bit;
else amips_clut_f = amips_clut;
}
#include "../common/emu.h"\r
#include "emu.h"\r
\r
+extern "C" char menuErrorMsg[];\r
\r
////////////////////////////////////////////////////////////////\r
//\r
iROMLoaded = EFalse;\r
switch (res)\r
{\r
- case PicoErrRomOpenFailed:\r
- CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to open file."));\r
+ case PicoErrRomOpenFailed: {\r
+ TBuf<64> mErrorBuff;\r
+ TPtrC8 buff8((TUint8*) menuErrorMsg);\r
+ mErrorBuff.Copy(buff8);\r
+ CEikonEnv::Static()->InfoWinL(_L("Error"), mErrorBuff);\r
break;\r
+ }\r
\r
case PicoErrOutOfMem:\r
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to allocate memory."));\r
break;\r
\r
- case PicoErrNotRom:\r
- CEikonEnv::Static()->InfoWinL(_L("Error"), _L("The file you selected is not a game ROM."));\r
- break;\r
-\r
- case PicoErrNoRomsInArchive:\r
- CEikonEnv::Static()->InfoWinL(_L("Error"), _L("No game ROMs found in zipfile."));\r
- break;\r
-\r
- case PicoErrUncomp:\r
- CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed while unzipping ROM."));\r
- break;\r
-\r
case PicoErrEmuThread:\r
CEikonEnv::Static()->InfoWinL(_L("Error"), _L("Failed to create emulation thread. Try to restart this application."));\r
break;\r
RSemaphore initSemaphore;\r
RSemaphore pauseSemaphore;\r
RSemaphore loadWaitSemaphore;\r
-int pico_was_reset = 0;\r
static CPicolAppView *appView = 0;\r
\r
\r
\r
case PicoMsgReset: \r
if(rom_loaded) {\r
- PicoReset();\r
- pico_was_reset = 1;\r
- return ChangeRunState(PGS_Running);\r
+ return ChangeRunState(PGS_Reset);\r
}\r
return 1;\r
\r
// If successful, in will enter PGS_Running state by itself.\r
loadrom_fname = (char *)writeBuf.PtrZ();\r
loadrom_result = 0;\r
+ loadWaitSemaphore.Wait(1); // make sure sem is not set\r
ret = ChangeRunState(PGS_ReloadRom);\r
if(ret) return ret;\r
\r
- loadWaitSemaphore.Wait(20*1000*1000);\r
+ loadWaitSemaphore.Wait(60*1000*1000);\r
\r
if (loadrom_result == 0)\r
- return PicoErrNotRom;\r
+ return PicoErrRomOpenFailed;\r
\r
emu_getGameName(buff);\r
TPtrC8 buff8((TUint8*) buff);\r
\r
// debug\r
#ifdef __DEBUG_PRINT\r
- TInt cells = User::CountAllocCells();\r
- TInt mem;\r
+ TInt mem, cells = User::CountAllocCells();\r
User::AllocSize(mem);\r
DEBUGPRINT(_L("comm: cels=%d, size=%d KB"), cells, mem/1024);\r
- ChangeRunState(PGS_DebugHeap, PGS_Running);\r
#endif\r
\r
return 0;\r
PGS_Paused,\r
PGS_Quit,\r
PGS_KeyConfig,\r
- PGS_DebugHeap,\r
PGS_ReloadRom,\r
+ PGS_Reset,\r
};\r
\r
enum TPicoServRqst {\r
PicoErrNoErr = 0, // OK\r
PicoErrRomOpenFailed,\r
PicoErrOutOfMem,\r
- PicoErrNotRom,\r
- PicoErrNoRomsInArchive,\r
- PicoErrUncomp, // 5\r
PicoErrOutOfMemSnd,\r
- PicoErrGenSnd, // 7 generic sound system error\r
+ PicoErrGenSnd, // generic sound system error\r
PicoErrEmuThread\r
};\r
\r
-# makefile for uiq3_patcher_0_2.tar.gz\r
+# makefile for uiq3_patcher_0_2.tar.gz setup, modified\r
export CROSS = arm-none-symbianelf-\r
APPNAME = PicoDrive\r
VER_MAJ = 1\r
@echo ">>>" $@\r
$(AS) $(ASFLAGS) $< -o $@\r
\r
-# App.o can't be optimized\r
-#App.o : App.cpp\r
-# $(CC) $(CXXFLAGS) -O0 -c $< -o $@\r
+\r
+readme.txt: ../../tools/textfilter ../base_readme.txt\r
+ ../../tools/textfilter ../base_readme.txt $@ UIQ\r
+\r
+# ----------- release -----------\r
+ifneq ($(findstring rel,$(MAKECMDGOALS)),)\r
+ifeq ($(VER),)\r
+$(error need VER)\r
+endif\r
+endif\r
+\r
+rel: picodrive.sis readme.txt\r
+ zip -9 -j ../../PicoDrive_uiq3_$(VER).zip $^\r
+ mkdir bin_to_cso_mp3\r
+ cp ../../tools/bin_to_cso_mp3/* bin_to_cso_mp3/\r
+ zip -9 -r ../../PicoDrive_uiq3_$(VER).zip bin_to_cso_mp3\r
+ rm -rf bin_to_cso_mp3\r
defaultConfig.Frameskip = -1; // auto
defaultConfig.volume = 80;
defaultConfig.scaling = 0;
+ defaultConfig.KeyBinds[0xd5] = 1<<26; // back
}
/* used by config engine only, not actual menus */
menu_entry cdopt_entries[] =
{
{ "CD LEDs", MB_ONOFF, MA_CDOPT_LEDS, ¤tConfig.EmuOpt, 0x0400, 0, 0, 1, 1 },
- { "CDDA audio (using mp3s)", MB_ONOFF, MA_CDOPT_CDDA, &PicoOpt, 0x0800, 0, 0, 1, 1 },
+ { "CDDA audio", MB_ONOFF, MA_CDOPT_CDDA, &PicoOpt, 0x0800, 0, 0, 1, 1 },
{ "PCM audio", MB_ONOFF, MA_CDOPT_PCM, &PicoOpt, 0x0400, 0, 0, 1, 1 },
{ NULL, MB_NONE, MA_CDOPT_READAHEAD, NULL, 0, 0, 0, 1, 1 },
{ "SaveRAM cart", MB_ONOFF, MA_CDOPT_SAVERAM, &PicoOpt, 0x8000, 0, 0, 1, 1 },
#include <stdio.h> // vsprintf\r
\r
// debug print from c code\r
- extern "C" void lprintf(char *format, ...)\r
+ extern "C" void lprintf(const char *format, ...)\r
{\r
va_list args;\r
char buffer[512];\r
#ifdef __cplusplus\r
extern "C"\r
#endif\r
- void lprintf(char *format, ...);\r
+ void lprintf(const char *format, ...);\r
#endif\r
#else\r
#define DEBUGPRINT(x...)\r
int loadrom_result = 0;\r
static timeval noticeMsgTime = { 0, 0 }; // when started showing\r
static CGameAudioMS *gameAudio = 0; // the audio object itself\r
-static int reset_timing;\r
-extern int pico_was_reset;\r
+static int reset_timing = 0;\r
+static int pico_was_reset = 0;\r
extern RSemaphore initSemaphore;\r
extern RSemaphore pauseSemaphore;\r
extern RSemaphore loadWaitSemaphore;\r
int thissec = 0, frames_done = 0, frames_shown = 0;\r
int target_fps, target_frametime;\r
int i, lim_time;\r
- //TRawEvent blevent;\r
\r
MainInit();\r
buff[0] = 0;\r
\r
+ // try to start pico\r
+ DEBUGPRINT(_L("PicoInit()"));\r
PicoInit();\r
-\r
- // just to keep the backlight on (works only on UIQ2)\r
- //blevent.Set(TRawEvent::EActive);\r
+ PicoDrawSetColorFormat(2);\r
+ PicoWriteSound = updateSound;\r
\r
// loop?\r
for(;;)\r
{\r
if (gamestate == PGS_Running)\r
{\r
+ #ifdef __DEBUG_PRINT\r
+ TInt mem, cells = User::CountAllocCells();\r
+ User::AllocSize(mem);\r
+ DEBUGPRINT(_L("worker: cels=%d, size=%d KB"), cells, mem/1024);\r
+ #endif\r
+\r
// switch context to other thread\r
User::After(50000);\r
// prepare window and stuff\r
if(!noticeMsgTime.tv_sec) strcpy(noticeMsg, "NTSC@SYSTEM@/@60@FPS");\r
}\r
target_frametime = 1000000/target_fps;\r
- if(!noticeMsgTime.tv_sec && pico_was_reset)\r
+ if (!noticeMsgTime.tv_sec && pico_was_reset)\r
gettimeofday(¬iceMsgTime, 0);\r
\r
// prepare CD buffer\r
frames_shown -= target_fps; if (frames_shown < 0) frames_shown = 0;\r
if (frames_shown > frames_done) frames_shown = frames_done;\r
}\r
+ User::ResetInactivityTime();\r
}\r
\r
\r
CPolledActiveScheduler::Instance()->Schedule();\r
CGameWindow::FreeResources();\r
}\r
+ else if(gamestate == PGS_Reset)\r
+ {\r
+ PicoReset();\r
+ pico_was_reset = 1;\r
+ gamestate = PGS_Running;\r
+ }\r
else if(gamestate == PGS_ReloadRom)\r
{\r
loadrom_result = emu_ReloadRom(loadrom_fname);\r
pico_was_reset = 1;\r
if (loadrom_result)\r
gamestate = PGS_Running;\r
- else\r
+ else {\r
+ extern char menuErrorMsg[];\r
gamestate = PGS_Paused;\r
+ lprintf("%s\n", menuErrorMsg);\r
+ }\r
DEBUGPRINT(_L("done loading ROM, retval=%i"), loadrom_result);\r
loadWaitSemaphore.Signal();\r
User::After(50000);\r
User::After(150000);\r
}\r
\r
+ emu_WriteConfig(0);\r
CGameWindow::FreeResources();\r
- } else if(gamestate == PGS_DebugHeap) {\r
- #ifdef __DEBUG_PRINT\r
- TInt cells = User::CountAllocCells();\r
- TInt mem;\r
- User::AllocSize(mem);\r
- DEBUGPRINT(_L("worker: cels=%d, size=%d KB"), cells, mem/1024);\r
- gamestate = gamestate_next;\r
- #endif\r
} else if(gamestate == PGS_Quit) {\r
break;\r
}\r
\r
DumpMemInfo();\r
\r
- // try to start pico\r
- DEBUGPRINT(_L("PicoInit()"));\r
- PicoDrawSetColorFormat(2);\r
- PicoWriteSound = updateSound;\r
-\r
// if (pauseSemaphore.Handle() <= 0)\r
// pauseSemaphore.CreateLocal(0);\r
DEBUGPRINT(_L("initSemaphore.Signal()"));\r
areaActions = 0;\r
}\r
}\r
+\r
+ if (movie_data) emu_updateMovie();\r
}\r
\r
\r
sprintf(noticeMsg, "SAVE@SLOT@%i@SELECTED", state_slot);\r
gettimeofday(¬iceMsgTime, 0);\r
}\r
- if(which & 0x0020) if(gameAudio) currentConfig.volume = gameAudio->ChangeVolume(0);\r
- if(which & 0x0010) if(gameAudio) currentConfig.volume = gameAudio->ChangeVolume(1);\r
+ if ((which & 0x0030) && gameAudio != NULL) {\r
+ currentConfig.volume = gameAudio->ChangeVolume((which & 0x0010) ? 1 : 0);\r
+ sprintf(noticeMsg, "VOL@%02i@", currentConfig.volume);\r
+ gettimeofday(¬iceMsgTime, 0);\r
+ }\r
}\r
\r
\r
static void drawTextFpsCenter0(const char *text)\r
{\r
if(!text) return;\r
- drawTextM2(214, 216, text);\r
+ drawTextM2((Pico.video.reg[12]&1) ? 234 : 214, 216, text);\r
}\r
\r
static void drawTextFpsFit0(const char *text)\r
static void drawTextNoticeCenter0(const char *text)\r
{\r
if(!text) return;\r
- drawTextM2(2, 216, text);\r
+ drawTextM2(42, 216, text);\r
}\r
\r
static void drawTextNoticeFit0(const char *text)\r
memcpy32(localPal+0xc0, localPal+0x40, 0x40);\r
localPal[0xe0] = 0x00000000; // reserved pixels for OSD\r
localPal[0xf0] = 0x00ee0000;\r
- } else if (rendstatus & 0x20) { // mid-frame palette changes\r
+ }\r
+ else if (rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes\r
vidConvCpyRGB32(localPal, Pico.cram, 0x40);\r
vidConvCpyRGB32(localPal+0x40, HighPal, 0x40);\r
vidConvCpyRGB32(localPal+0x80, HighPal+0x40, 0x40);\r
} else {\r
vidConvCpyRGB32(localPal, Pico.cram, 0x40);\r
+ memcpy32(localPal+0x80, localPal, 0x40); // for sprite prio mess\r
}\r
}\r
\r
unsigned char *ps = PicoDraw2FB+328*8;\r
unsigned long *pd = (unsigned long *) screenbuff;\r
\r
- if (Pico.m.dirtyPal) fillLocalPal();\r
-\r
if(Pico.video.reg[12]&1)\r
vidConvCpy_90(pd, ps, localPal, 320/8);\r
else {\r
unsigned char *ps = PicoDraw2FB+328*8;\r
unsigned long *pd = (unsigned long *) screenbuff;\r
\r
- if (Pico.m.dirtyPal) fillLocalPal();\r
-\r
if(Pico.video.reg[12]&1)\r
vidConvCpy_270(pd, ps, localPal, 320/8);\r
else {\r
unsigned char *ps = PicoDraw2FB+328*8+8;\r
unsigned long *pd = (unsigned long *) screenbuff;\r
\r
- if (Pico.m.dirtyPal) fillLocalPal();\r
-\r
if(Pico.video.reg[12]&1) ps += 32;\r
vidConvCpy_center_0(pd, ps, localPal);\r
if(full) vidClear(pd + 224*256, 96);\r
unsigned char *ps = PicoDraw2FB+328*8+8;\r
unsigned long *pd = (unsigned long *) screenbuff;\r
\r
- if (Pico.m.dirtyPal) fillLocalPal();\r
-\r
if(Pico.video.reg[12]&1) ps += 32;\r
vidConvCpy_center_180(pd, ps, localPal);\r
if(full) vidClear(pd + 224*256, 96);\r
\r
static void vidBlitFit_0(int full)\r
{\r
- if (Pico.m.dirtyPal) fillLocalPal();\r
-\r
if(Pico.video.reg[12]&1)\r
vidConvCpy_center2_40c_0(screenbuff, PicoDraw2FB+328*8, localPal, 168);\r
else vidConvCpy_center2_32c_0(screenbuff, PicoDraw2FB+328*8, localPal, 168);\r
\r
static void vidBlitFit_180(int full)\r
{\r
- if (Pico.m.dirtyPal) fillLocalPal();\r
-\r
if(Pico.video.reg[12]&1)\r
vidConvCpy_center2_40c_180(screenbuff, PicoDraw2FB+328*8, localPal, 168);\r
else vidConvCpy_center2_32c_180(screenbuff, PicoDraw2FB+328*8-64, localPal, 168);\r
\r
static void vidBlitFit2_0(int full)\r
{\r
- if (Pico.m.dirtyPal) fillLocalPal();\r
-\r
if(Pico.video.reg[12]&1)\r
vidConvCpy_center2_40c_0(screenbuff, PicoDraw2FB+328*8, localPal, 224);\r
else vidConvCpy_center2_32c_0(screenbuff, PicoDraw2FB+328*8, localPal, 224);\r
\r
static void vidBlitFit2_180(int full)\r
{\r
- if (Pico.m.dirtyPal) fillLocalPal();\r
-\r
if(Pico.video.reg[12]&1)\r
vidConvCpy_center2_40c_180(screenbuff, PicoDraw2FB+328*8, localPal, 224);\r
else vidConvCpy_center2_32c_180(screenbuff, PicoDraw2FB+328*8-64, localPal, 224);\r
vidBlit = vidBlit_270;\r
}\r
\r
+ fillLocalPal();\r
vidBlit(1);\r
PicoOpt |= 0x100;\r
Pico.m.dirtyPal = 1;\r
drawTextFps(fpsStr);\r
drawTextNotice(noticeStr);\r
\r
+ if (Pico.m.dirtyPal) fillLocalPal();\r
vidBlit(!num); // copy full frame once a second\r
}\r
\r
#define CAN_HANDLE_240_LINES 0 // for now\r
\r
// logging emu events\r
-#define EL_LOGMASK (EL_STATUS|EL_IDLE) // (EL_STATUS|EL_ANOMALY|EL_UIO|EL_SRAMIO|EL_INTS|EL_CDPOLL) // xffff\r
+#define EL_LOGMASK (EL_STATUS) // |EL_SVP|EL_ANOMALY)\r
\r
//extern void dprintf(char *format, ...);\r
//#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)\r
BMCONV = bmconv
EPOCRC = EPOCROOT=$(EPOCROOT) epocrc
-PATH := $(EPOCROOT)/bin:$(GCCPATH)/bin:$(GCCPATH)/$(GCCPREF)/bin:$(PATH)
+PATH := $(EPOCROOT)/bin:$(GCCPATH)/bin:$(PATH)
-# TODO: do we really need -mapcs?
-# -march=armv5t
+# -march=armv5t ?
CFLAGS += -Wall -pipe -nostdinc -msoft-float
CFLAGS += -DNDEBUG -D_UNICODE -D__GCCE__ -D__SYMBIAN32__ -D__EPOC32__ -D__MARM__
CFLAGS += -D__EABI__ -D__MARM_ARMV5__ -D__EXE__ -D__SUPPORT_CPP_EXCEPTIONS__ -D__MARM_ARMV5__