#include <string.h>\r
\r
#include "version.h"\r
-#include "../../pico/picoInt.h"\r
+#include <pico/pico_int.h>\r
+#include "../common/emu.h"\r
#include "engine/debug.h"\r
-#include "app.h"\r
+#include "App.h"\r
\r
// this is where we start to break a bunch of symbian rules\r
extern TInt machineUid;\r
extern int gamestate, gamestate_next;\r
-extern TPicoConfig *currentConfig;\r
+extern char *loadrom_fname;\r
+extern int loadrom_result;\r
extern const char *actionNames[];\r
-RSemaphore pauseSemaphore;\r
RSemaphore initSemaphore;\r
-const char *RomFileName = 0;\r
-int pico_was_reset = 0;\r
-unsigned char *rom_data = 0;\r
+RSemaphore pauseSemaphore;\r
+RSemaphore loadWaitSemaphore;\r
static CPicolAppView *appView = 0;\r
\r
\r
TInt CPicoGameSession::Do(const TPicoServRqst what, TAny *param)\r
{\r
- switch (what) {\r
+ switch (what)\r
+ {\r
case PicoMsgLoadState: \r
- if(!rom_data) return -1; // no ROM\r
- return saveLoadGame(1);\r
+ if(!rom_loaded) return -1; // no ROM\r
+ return emu_save_load_game(1, 0);\r
\r
case PicoMsgSaveState:\r
- if(!rom_data) return -1;\r
- return saveLoadGame(0);\r
+ if(!rom_loaded) return -1;\r
+ return emu_save_load_game(0, 0);\r
\r
case PicoMsgLoadROM:\r
return loadROM((TPtrC16 *)param);\r
\r
case PicoMsgResume:\r
- DEBUGPRINT(_L("resume with rom %08x"), rom_data);\r
- if(rom_data) {\r
+ DEBUGPRINT(_L("resume"));\r
+ if(rom_loaded) {\r
return ChangeRunState(PGS_Running);\r
}\r
return 1;\r
\r
case PicoMsgReset: \r
- if(rom_data) {\r
- PicoReset();\r
- pico_was_reset = 1;\r
- return ChangeRunState(PGS_Running);\r
+ if(rom_loaded) {\r
+ return ChangeRunState(PGS_Reset);\r
}\r
return 1;\r
\r
initSemaphore.CreateLocal(0);\r
if (pauseSemaphore.Handle() <= 0)\r
pauseSemaphore.CreateLocal(0);\r
+ if (loadWaitSemaphore.Handle() <= 0)\r
+ loadWaitSemaphore.CreateLocal(0);\r
\r
RThread thread;\r
if(iThreadWatcher && (res = thread.Open(iThreadWatcher->iTid)) == KErrNone) {\r
thread.Close();\r
}\r
\r
- //semaphore.CreateLocal(0); // create a semaphore so we know when thread init is finished\r
res=thread.Create(_L("PicoEmuThread"), // create new server thread\r
EmuThreadFunction, // thread's main function\r
KDefaultStackSize,\r
iThreadWatcher = CThreadWatcher::NewL(thread.Id());\r
thread.Resume(); // start it going\r
DEBUGPRINT(_L("initSemaphore.Wait()"));\r
- res = initSemaphore.Wait(1000*1000); // wait until it's initialized\r
+ res = initSemaphore.Wait(3*1000*1000); // wait until it's initialized\r
DEBUGPRINT(_L("initSemaphore resume, ExitReason() == %i"), thread.ExitReason());\r
res |= thread.ExitReason();\r
thread.Close(); // we're no longer interested in the other thread\r
\r
TInt CPicoGameSession::loadROM(TPtrC16 *pptr)\r
{\r
- TInt res, i;\r
- char buff[0x31];\r
+ TInt ret;\r
+ char buff[150];\r
\r
- if(rom_data) {\r
- // save SRAM for previous ROM\r
- if(currentConfig->iFlags & 1)\r
- saveLoadGame(0, 1);\r
- }\r
-\r
- RomFileName = 0;\r
- if(rom_data) {\r
- free(rom_data);\r
- rom_data = 0;\r
- }\r
+ // make sure emu thread is ok\r
+ ret = ChangeRunState(PGS_Paused);\r
+ if(ret) return ret;\r
\r
// read the contents of the client pointer into a TPtr.\r
static TBuf8<KMaxFileName> writeBuf;\r
writeBuf.Copy(*pptr);\r
\r
- // detect wrong extensions (.srm and .mds)\r
- TBuf8<5> ext;\r
- ext.Copy(writeBuf.Right(4));\r
- ext.LowerCase();\r
- if(!strcmp((char *)ext.PtrZ(), ".srm") || !strcmp((char *)ext.PtrZ(), "s.gz") || // .mds.gz\r
- !strcmp((char *)ext.PtrZ(), ".mds")) {\r
- return PicoErrNotRom;\r
- }\r
+ // push the emu thead to a load state. This is done so that it owns all file handles.\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
- FILE *rom = fopen((char *) writeBuf.PtrZ(), "rb");\r
- if(!rom) {\r
- DEBUGPRINT(_L("failed to open rom."));\r
- return PicoErrRomOpenFailed;\r
- }\r
+ loadWaitSemaphore.Wait(60*1000*1000);\r
\r
- // make sure emu thread is ok\r
- res = ChangeRunState(PGS_Paused);\r
- if(res) {\r
- fclose(rom);\r
- return res;\r
- }\r
-\r
- unsigned int rom_size = 0;\r
- // zipfile support\r
- if(!strcmp((char *)ext.PtrZ(), ".zip")) {\r
- fclose(rom);\r
- res = CartLoadZip((const char *) writeBuf.PtrZ(), &rom_data, &rom_size);\r
- if(res) {\r
- DEBUGPRINT(_L("CartLoadZip() failed (%i)"), res);\r
- return res;\r
- }\r
- } else {\r
- if( (res = PicoCartLoad(rom, &rom_data, &rom_size)) ) {\r
- DEBUGPRINT(_L("PicoCartLoad() failed (%i)"), res);\r
- fclose(rom);\r
- return PicoErrOutOfMem;\r
- }\r
- fclose(rom);\r
- }\r
-\r
- // detect wrong files (Pico crashes on very small files), also see if ROM EP is good\r
- if(rom_size <= 0x200 || strncmp((char *)rom_data, "Pico", 4) == 0 ||\r
- ((*(TUint16 *)(rom_data+4)<<16)|(*(TUint16 *)(rom_data+6))) >= (int)rom_size) {\r
- free(rom_data);\r
- rom_data = 0;\r
- return PicoErrNotRom;\r
- }\r
-\r
- DEBUGPRINT(_L("PicoCartInsert(0x%08X, %d);"), rom_data, rom_size);\r
- if(PicoCartInsert(rom_data, rom_size)) {\r
- return PicoErrOutOfMem;\r
- }\r
-\r
- pico_was_reset = 1;\r
-\r
- // global ROM file name for later use\r
- RomFileName = (const char *) writeBuf.PtrZ();\r
+ if (loadrom_result == 0)\r
+ return PicoErrRomOpenFailed;\r
\r
- // name from the ROM itself\r
- for(i = 0; i < 0x30; i++)\r
- buff[i] = rom_data[0x150 + (i^1)]; // unbyteswap\r
- for(buff[i] = 0, i--; i >= 0; i--) {\r
- if(buff[i] != ' ') break;\r
- buff[i] = 0;\r
- }\r
+ emu_get_game_name(buff);\r
TPtrC8 buff8((TUint8*) buff);\r
iRomInternalName.Copy(buff8);\r
\r
- // load SRAM for this ROM\r
- if(currentConfig->iFlags & 1)\r
- saveLoadGame(1, 1);\r
+ DEBUGPRINT(_L("done waiting for ROM load"));\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
- #else\r
- ChangeRunState(PGS_Running);\r
#endif\r
\r
return 0;\r
\r
TInt CPicoGameSession::changeConfig(TPicoConfig *aConfig)\r
{\r
- DEBUGPRINT(_L("got new config."));\r
-\r
- currentConfig = aConfig;\r
-\r
- // set PicoOpt and rate\r
- PicoRegionOverride = currentConfig->PicoRegion;\r
- PicoOpt = currentConfig->iPicoOpt;\r
- switch((currentConfig->iFlags>>3)&7) {\r
- case 1: PsndRate=11025; break;\r
- case 2: PsndRate=16000; break;\r
- case 3: PsndRate=22050; break;\r
- case 4: PsndRate=44100; break;\r
- default: PsndRate= 8000; break;\r
- }\r
-\r
// 6 button pad, enable XYZM config if needed\r
- if(PicoOpt & 0x20) {\r
+ if (PicoOpt & POPT_6BTN_PAD)\r
+ {\r
actionNames[8] = "Z";\r
actionNames[9] = "Y";\r
actionNames[10] = "X";\r
}\r
\r
// if we are in center 90||270 modes, we can bind renderer switcher\r
- if(currentConfig->iScreenMode == TPicoConfig::PMFit &&\r
- (currentConfig->iScreenRotation == TPicoConfig::PRot0 || currentConfig->iScreenRotation == TPicoConfig::PRot180))\r
- actionNames[25] = 0;\r
- else actionNames[25] = "RENDERER";\r
+ if (currentConfig.scaling == TPicoConfig::PMFit &&\r
+ (currentConfig.rotation == TPicoConfig::PRot0 || currentConfig.rotation == TPicoConfig::PRot180))\r
+ actionNames[25] = 0;\r
+ else actionNames[25] = "RENDERER";\r
\r
return 0;\r
}\r
\r
\r
-void MainOldCleanup(); // from main.cpp\r
#ifdef __DEBUG_PRINT_FILE\r
extern RMutex logMutex;\r
#endif\r
\r
}\r
\r
- if(iThreadWatcher != NULL)\r
+ if (iThreadWatcher != NULL)\r
{\r
DEBUGPRINT(_L("delete iThreadWatcher"));\r
delete iThreadWatcher;\r
iThreadWatcher = NULL;\r
}\r
\r
- MainOldCleanup();\r
-\r
if (initSemaphore.Handle() > 0)\r
initSemaphore.Close();\r
if (pauseSemaphore.Handle() > 0)\r
pauseSemaphore.Close();\r
+ if (loadWaitSemaphore.Handle() > 0)\r
+ loadWaitSemaphore.Close();\r
+ DEBUGPRINT(_L("freeResources() returning"));\r
#ifdef __DEBUG_PRINT_FILE\r
if (logMutex.Handle() > 0)\r
logMutex.Close();\r
\r
TBool CPicoGameSession::iEmuRunning = EFalse;\r
CThreadWatcher *CPicoGameSession::iThreadWatcher = 0;\r
-TBuf<0x30> CPicoGameSession::iRomInternalName;\r
-\r
-\r
-void TPicoConfig::SetDefaults()\r
-{\r
- iLastROMFile.SetLength(0);\r
- iScreenRotation = PRot270;\r
- iScreenMode = PMCenter;\r
- iFlags = 1; // use_sram\r
- iPicoOpt = 0; // all off\r
- iFrameskip = PFSkipAuto;\r
-\r
- Mem::FillZ(iKeyBinds, sizeof(iKeyBinds));\r
- Mem::FillZ(iAreaBinds, sizeof(iAreaBinds));\r
- iKeyBinds[0xd5] = 1<<26; // bind back\r
-}\r
-\r
-// load config\r
-void TPicoConfig::InternalizeL(RReadStream &aStream)\r
-{\r
- TInt32 version, fname_len;\r
- version = aStream.ReadInt32L();\r
- fname_len = aStream.ReadInt32L();\r
-\r
- // not sure if this is safe\r
- iLastROMFile.SetMax();\r
- aStream.ReadL((TUint8 *) iLastROMFile.Ptr(), KMaxFileName*2);\r
- iLastROMFile.SetLength(fname_len);\r
-\r
- iScreenRotation = aStream.ReadInt32L();\r
- iScreenMode = aStream.ReadInt32L();\r
- iFlags = aStream.ReadUint32L();\r
- iPicoOpt = aStream.ReadInt32L();\r
- iFrameskip = aStream.ReadInt32L();\r
-\r
- aStream.ReadL((TUint8 *)iKeyBinds, sizeof(iKeyBinds));\r
- aStream.ReadL((TUint8 *)iAreaBinds, sizeof(iAreaBinds));\r
-\r
- PicoRegion = aStream.ReadInt32L();\r
-}\r
-\r
-// save config\r
-void TPicoConfig::ExternalizeL(RWriteStream &aStream) const\r
-{\r
- TInt version = (KPicoMajorVersionNumber<<24)+(KPicoMinorVersionNumber<<16);\r
-\r
- aStream.WriteInt32L(version);\r
- aStream.WriteInt32L(iLastROMFile.Length());\r
- aStream.WriteL((const TUint8 *)iLastROMFile.Ptr(), KMaxFileName*2);\r
-\r
- aStream.WriteInt32L(iScreenRotation);\r
- aStream.WriteInt32L(iScreenMode);\r
- aStream.WriteUint32L(iFlags);\r
- aStream.WriteInt32L(iPicoOpt);\r
- aStream.WriteInt32L(iFrameskip);\r
-\r
- aStream.WriteL((const TUint8 *)iKeyBinds, sizeof(iKeyBinds));\r
- aStream.WriteL((const TUint8 *)iAreaBinds, sizeof(iAreaBinds));\r
-\r
- aStream.WriteInt32L(PicoRegion);\r
-}\r
+TBuf<150> CPicoGameSession::iRomInternalName;\r
\r
\r
// CThreadWatcher\r
thread.Close();\r
}\r
}\r
+\r
+extern "C" void cache_flush_d_inval_i(const void *start_addr, const void *end_addr)\r
+{\r
+ // TODO\r
+ User::IMB_Range((TAny *)start_addr, (TAny *)end_addr);\r
+}\r
+\r