UIQ3 update, some makefile unification, rm old configs, stuff
[picodrive.git] / platform / uiq3 / Engine.cpp
index 5e21b91..ee9b6a5 100644 (file)
 #include <string.h>\r
 \r
 #include "version.h"\r
-#include "../../pico/picoInt.h"\r
+#include <Pico/PicoInt.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
+RSemaphore pauseSemaphore;\r
+RSemaphore loadWaitSemaphore;\r
 int pico_was_reset = 0;\r
-unsigned char *rom_data = 0;\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_SaveLoadGame(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_SaveLoadGame(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
+                       if(rom_loaded) {\r
                                PicoReset();\r
                                pico_was_reset = 1;\r
                                return ChangeRunState(PGS_Running);\r
@@ -104,6 +106,8 @@ TInt CPicoGameSession::StartEmuThread()
        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
@@ -118,7 +122,6 @@ TInt CPicoGameSession::StartEmuThread()
                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
@@ -134,7 +137,7 @@ TInt CPicoGameSession::StartEmuThread()
                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
@@ -164,96 +167,34 @@ TInt CPicoGameSession::ChangeRunState(TPicoGameState newstate, TPicoGameState ne
 \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
-\r
-       FILE *rom = fopen((char *) writeBuf.PtrZ(), "rb");\r
-       if(!rom) {\r
-               DEBUGPRINT(_L("failed to open rom."));\r
-               return PicoErrRomOpenFailed;\r
-       }\r
-\r
-       // make sure emu thread is ok\r
-       res = ChangeRunState(PGS_Paused);\r
-       if(res) {\r
-               fclose(rom);\r
-               return res;\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
+       ret = ChangeRunState(PGS_ReloadRom);\r
+       if(ret) return ret;\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
+       loadWaitSemaphore.Wait(20*1000*1000);\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
+       if (loadrom_result == 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
-\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_getGameName(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
@@ -262,8 +203,6 @@ TInt CPicoGameSession::loadROM(TPtrC16 *pptr)
        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
@@ -272,23 +211,9 @@ TInt CPicoGameSession::loadROM(TPtrC16 *pptr)
 \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
@@ -298,16 +223,15 @@ TInt CPicoGameSession::changeConfig(TPicoConfig *aConfig)
        }\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
@@ -346,7 +270,7 @@ void CPicoGameSession::freeResources()
 \r
        }\r
 \r
-       if(iThreadWatcher != NULL)\r
+       if (iThreadWatcher != NULL)\r
        {\r
                DEBUGPRINT(_L("delete iThreadWatcher"));\r
                delete iThreadWatcher;\r
@@ -354,12 +278,13 @@ void CPicoGameSession::freeResources()
                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
@@ -368,67 +293,7 @@ void CPicoGameSession::freeResources()
 \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
@@ -482,3 +347,10 @@ void CThreadWatcher::DoCancel()
                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