8 #include <picodrive.rsg>
\r
10 #include <picodriveS60.rsg>
\r
13 #include <aknlistquerydialog.h>
\r
14 #include <s32file.h>
\r
18 #include <sys\time.h>
\r
20 #include "PicoDriveexe.h"
\r
23 #include "PicoInt.h"
\r
27 static const char* KAboutText =
\r
28 "This emulator uses code from\n"
\r
29 "these people/projects:\n"
\r
32 "Cyclone 68000 core,\n"
\r
33 "Pico emulation library\n"
\r
34 "Homepage:http://www.finalburn.com\n"
\r
35 "E-mail: david(at)finalburn.com\n"
\r
38 "UIQ port,Cyclone 68000 hacks,some\n"
\r
39 "additional coding (see changelog).\n"
\r
40 "Homepage:http://notaz.atspace.com/\n"
\r
41 "E-mail: notasas(at)gmail.com\n"
\r
44 "DrZ80, the Z80 emulator\n"
\r
45 "written in ARM assembly.\n"
\r
46 "Homepage: http://reesy.gp32x.de/\n"
\r
47 "E-mail:drsms_reesy(at)yahoo.co.uk\n"
\r
49 "Tatsuyuki Satoh, Jarek Burczynski,\n"
\r
50 "MultiArcadeMachineEmulator\n"
\r
52 "software implementation of\n"
\r
53 "Yamaha FM sound generator\n"
\r
55 "MultiArcadeMachineEmulator(MAME)\n"
\r
57 "Texas Instruments SN76489/SN76496\n"
\r
58 "programmable tone/noise generator\n"
\r
59 "Homepage: http://www.mame.net/\n"
\r
61 "Additional thanks\n"
\r
62 "-----------------\n"
\r
63 "* Peter van Sebille for ECompXL\n"
\r
64 " and his various open-source\n"
\r
65 " Symbian project to learn from.\n"
\r
66 "* Mark and Jean-loup for zlib\n"
\r
68 "* Reesy for also finding some\n"
\r
70 "* Charles MacDonald\n"
\r
71 " (http://cgfm2.emuviews.com/)\n"
\r
72 " for old but still very useful\n"
\r
73 " info about genesis hardware.\n"
\r
74 "* Stúphane Dallongeville\n"
\r
75 " for creating Gens\n"
\r
76 " (http://www.gens.ws)\n"
\r
77 "*The development team behind the\n"
\r
78 " Symbian GCC Improvement Project\n"
\r
79 " http://www.inf.u-szeged.hu\n"
\r
80 " /symbian-gcc/) for their updated\n"
\r
81 " compiler tools.\n"
\r
82 "* Inder for the icons.\n";
\r
84 // Picodrive prefrence uid
\r
85 const TUid KPicoDrivePrefs={0x1234432E};
\r
87 // Bittable corresponding to the bitvalues for the different control actions
\r
88 TUint16 KBitValTable[EPicoNoKeys]={1,2,4,8 ,64,16,32,1024,512,256,2048,128,5,9,10,6,0,0,0};
\r
90 extern"C" unsigned short *framebuff = 0; // temporary buffer in sega native BGR format
\r
91 const int framebuffsize = ((8+320)*(224+16))*2; // actual framebuffer size (in bytes+to support new rendering mode)
\r
93 // Colour lookuptable from BGR to RGB
\r
94 unsigned short gColorMapTab[4096];
\r
96 // Scaling line table
\r
97 TUint8 gColumnStepTable[320];
\r
98 TUint8 gNarrowColumnStepTable[256];
\r
99 unsigned short gLineTable[240];
\r
100 TUint32 gLineOffsets[416];
\r
101 TUint32 gFullOffset;
\r
102 extern int PsndLen;
\r
105 GLDEF_C TInt E32Dll(TDllReason)
\r
110 _LIT(KLitResourceFileName, "z:\\system\\apps\\picodrives60\\PicoDriveS60.rsc");
\r
112 _LIT(KLitResourceFileName, "PicoDriveS60.rsc");
\r
120 struct Target Targ;
\r
123 #include "S60V3Video.inl"
\r
125 #include "NormalVideo.inl"
\r
126 #include "InterpolateVideo.inl"
\r
129 TInt CPicoDriveUi::AsyncUpdateL(TAny* aAppUi)
\r
131 static_cast<CPicoDriveUi*>(aAppUi)->UpdateScreen();
\r
135 void CPicoDriveUi::StartAsynchUpdate()
\r
137 TCallBack callback(AsyncUpdateL,iEikonEnv->EikAppUi());
\r
138 iAsyncUpdate.Cancel();
\r
139 iAsyncUpdate.Set(callback);
\r
140 iAsyncUpdate.CallBack();
\r
144 CPicoDriveUi::CPicoDriveUi():iIdleCallBack(CActive::EPriorityIdle),iStartUp(CActive::EPriorityIdle),
\r
145 iAsyncUpdate(CActive::EPriorityStandard)
\r
148 FramesPerSecond=60;
\r
150 iLastAboutPos = -1;
\r
153 iInterpolate = ETrue;
\r
158 CPicoDriveUi::~CPicoDriveUi()
\r
164 RemoveFromStack(iView);
\r
167 delete iBackBuffer;
\r
170 iCoeEnv->DeleteResourceFile(iResourceFileId);
\r
184 TKeyResponse CPicoDriveUi::HandleKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
\r
188 return iCheatDlg->OfferKeyEventL(aKeyEvent,aType);
\r
191 if(aType==EEventKey && aKeyEvent.iScanCode==EStdKeyBackspace)
\r
193 if(iPicoMenu ==ESelectSoundMenu)
\r
195 if(iSndRateChanged)
\r
197 if(!UpdatePSndRate()) // Not compatible.. reset to 8000
\r
210 iPicoMenu = EPicoMainMenu;
\r
212 return EKeyWasConsumed;
\r
214 else if (iPicoMenu == ESelectControlsMenu)
\r
217 iPicoMenu = EPicoMainMenu;
\r
219 return EKeyWasConsumed;
\r
221 else if(iPicoMenu == ESelectScrMenu)
\r
223 iScrMode = iLastScrMode;
\r
225 iPicoMenu = EPicoMainMenu;
\r
227 return EKeyWasConsumed;
\r
229 else if(iPicoMenu == ESelectCheatMenu)
\r
231 if(iCheatSelection<2)
\r
234 iPicoMenu = EPicoMainMenu;
\r
239 TInt index = (iListOffset+iCheatSelection)-2;
\r
241 for(TInt i = 0; i < 256;i++)
\r
243 if (Liste_GG[i].code[0] != 0)
\r
246 if(noFound-1 == index)
\r
248 Liste_GG[i].code[0] = 0;
\r
249 Liste_GG[i].active = 0;
\r
252 iCheatSelection = 0;
\r
263 return EKeyWasConsumed;
\r
266 if(!iEmuRunning && (iPicoMenu!=EPicoMainMenu ||iCurrentScan!=-1) )
\r
267 return EKeyWasNotConsumed;
\r
271 iEmuRunning=!iEmuRunning;
\r
273 if(iEmuRunning && iRomLoaded)
\r
276 TCallBack callback(StartEmulatorL,this);
\r
277 iStartUp.Set(callback);
\r
278 iStartUp.CallBack();
\r
281 return EKeyWasConsumed;
\r
286 if(iCurrentScan==-1)
\r
288 if(aType==EEventKey)
\r
291 switch(aKeyEvent.iScanCode) // first determine bit value to change
\r
293 case EStdKeyUpArrow:
\r
296 case ESelectControlsMenu:
\r
298 iCtrlSelection=!iCtrlSelection;
\r
299 PutControllerSelect();
\r
301 case EPicoMainMenu:
\r
304 else iSelection=EExitPico;
\r
307 case ESelectScrMenu:
\r
313 case ESelectCheatMenu:
\r
314 if(iCheatSelection>0)
\r
317 iCheatSelection = ELastCheatItem-1;
\r
320 case EAboutPicoMenu:
\r
325 case ESelectSoundMenu:
\r
327 if(iSndSelection>0)
\r
330 iSndSelection = ELastSoundItem-1;
\r
335 case EStdKeyDownArrow:
\r
338 case ESelectControlsMenu:
\r
340 iCtrlSelection=!iCtrlSelection;
\r
341 PutControllerSelect();
\r
343 case EPicoMainMenu:
\r
345 if(iSelection==ELastMenuItem)
\r
349 case ESelectScrMenu:
\r
355 case ESelectCheatMenu:
\r
356 if(iCheatSelection<(ELastCheatItem+iNoCheats-1) && iCheatSelection<6)
\r
358 else if(iCheatSelection == ELastCheatItem+4 && iListOffset<iNoCheats-5)
\r
365 iCheatSelection = 0;
\r
369 case EAboutPicoMenu:
\r
374 case ESelectSoundMenu:
\r
377 if(iSndSelection==ELastSoundItem)
\r
383 case EStdKeyDevice0:
\r
384 case EStdKeyDevice3:
\r
388 case ESelectControlsMenu:
\r
390 if(iCtrlSelection == EConfigControls)
\r
392 iPicoMenu = EPicoMainMenu;
\r
399 iEnableSixButtons = !iEnableSixButtons;
\r
400 PicoOpt=PicoOpt^ 32;
\r
402 PutControllerSelect();
\r
405 case ESelectCheatMenu:
\r
407 switch(iCheatSelection)
\r
411 TBuf8<16> cheatCode;
\r
412 iCheatEnter = ETrue;
\r
413 iCheatDlg = new (ELeave) CPicoAddCheatDlg(cheatCode);
\r
414 iCheatDlg->SetMopParent(iEikonEnv->EikAppUi());
\r
415 TInt result = iCheatDlg->ExecuteLD(R_PICO_ADD_CHEAT);
\r
417 if(result == EEikBidOk)
\r
419 for(TInt i = 0; i < 256;i++)
\r
421 if (Liste_GG[i].code[0] == 0)
\r
423 if(check_code((const char*) cheatCode.PtrZ(),i))
\r
425 decode( Liste_GG[i].code, (patch *) (&(Liste_GG[i].addr)));
\r
427 if ((Liste_GG[i].restore == 0xFFFFFFFF) && (Liste_GG[i].addr < Pico.romsize) && (iRomLoaded))
\r
429 Liste_GG[i].restore = (unsigned int) (Pico.rom[Liste_GG[i].addr] & 0xFF);
\r
430 Liste_GG[i].restore += (unsigned int) ((Pico.rom[Liste_GG[i].addr + 1] & 0xFF) << 8);
\r
433 Liste_GG[i].active = 1;
\r
435 break; // Found position free
\r
440 iCheatEnter = EFalse;
\r
445 for(TInt i = 0; i < 256;i++)
\r
447 Liste_GG[i].code[0] = 0;
\r
448 Liste_GG[i].active = 0;
\r
454 TInt index = (iListOffset+iCheatSelection)-2;
\r
456 for(TInt i = 0; i < 256;i++)
\r
458 if (Liste_GG[i].code[0] != 0)
\r
461 if(noFound-1 == index)
\r
463 Liste_GG[i].active=!Liste_GG[i].active;
\r
477 case EAboutPicoMenu:
\r
482 case ESelectScrMenu:
\r
488 iInterpolate = !iInterpolate;
\r
494 if(iFrameSkip == 11)
\r
502 PicoOpt = PicoOpt^0x40;
\r
507 PicoOpt = PicoOpt^0x80;
\r
512 PicoOpt = PicoOpt^0x10;
\r
517 switch(PicoRegionOverride)
\r
521 PicoRegionOverride = 1;
\r
524 PicoRegionOverride = 2;
\r
527 PicoRegionOverride = 4;
\r
530 PicoRegionOverride = 8;
\r
533 PicoRegionOverride = 0;
\r
542 TBitmapUtil util(iBackBuffer);
\r
543 util.Begin(TPoint(0,0));
\r
544 TSize sz=iBackBuffer->SizeInPixels();
\r
545 TInt dataSize=sz.iWidth*sz.iHeight*2;
\r
546 TPtr8 ptr(reinterpret_cast<unsigned char*>(iBackBuffer->DataAddress()),dataSize,dataSize);
\r
549 iPicoMenu=EPicoMainMenu;
\r
557 case ESelectSoundMenu:
\r
559 switch(iSndSelection)
\r
564 case EEnableYM2612:
\r
567 case EEnableSN76496:
\r
573 if(iSoundVolume==11)
\r
576 iEnableSound=EFalse;
\r
580 iEnableSound=ETrue;
\r
581 iSndStream->SetVolume((iSndStream->MaxVolume()*iSoundVolume)/10);
\r
586 iSndStream->Stop();
\r
591 iSndRateChanged = ETrue;
\r
612 case EPicoMainMenu:
\r
621 TCallBack callback(StartEmulatorL,this);
\r
622 iStartUp.Set(callback);
\r
623 iStartUp.CallBack();
\r
631 saveLoadGame(1,0);
\r
634 TCallBack callback(StartEmulatorL,this);
\r
635 iStartUp.Set(callback);
\r
636 iStartUp.CallBack();
\r
647 TCallBack callback(StartEmulatorL,this);
\r
648 iStartUp.Set(callback);
\r
649 iStartUp.CallBack();
\r
656 TParsePtr parse(iRomName);
\r
657 iRomName=parse.DriveAndPath();
\r
658 if(SelectFile(iRomName))
\r
662 TPtr8 ptr((unsigned char*)RomName,256);
\r
664 ptr.Copy(iRomName);
\r
665 User::CompressAllHeaps();
\r
666 if(EmulateInit()==0)
\r
670 FramesPerSecond=50;
\r
674 FramesPerSecond=60;
\r
677 SetKeyBlockMode(ENoKeyBlock);
\r
681 TCallBack callback(StartEmulatorL,this);
\r
682 iStartUp.Set(callback);
\r
683 iStartUp.CallBack();
\r
687 iRomName=KNullDesC();
\r
701 iPicoMenu = ESelectControlsMenu;
\r
702 PutControllerSelect();
\r
706 iLastScrMode = iScrMode; // In case of cancel
\r
708 iPicoMenu=ESelectScrMenu;
\r
712 iSndRateChanged = EFalse;
\r
713 iPicoMenu=ESelectSoundMenu;
\r
718 iPicoMenu=ESelectCheatMenu;
\r
721 for(TInt i = 0; i < 256;i++)
\r
723 if (Liste_GG[i].code[0] != 0)
\r
726 if ((Liste_GG[i].restore != 0xFFFFFFFF) && (Liste_GG[i].addr < Pico.romsize) && (iRomLoaded))
\r
728 Pico.rom[Liste_GG[i].addr] = (unsigned char)(Liste_GG[i].restore & 0xFF);
\r
729 Pico.rom[Liste_GG[i].addr + 1] = (unsigned char)((Liste_GG[i].restore & 0xFF00) >> 8);
\r
742 iPicoMenu=EAboutPicoMenu;
\r
761 if(aType == EEventKeyDown)
\r
763 if(aKeyEvent.iScanCode != EStdKeyBackspace)
\r
765 iScanCodes[iCurrentScan]=aKeyEvent.iScanCode;
\r
769 iScanCodes[iCurrentScan] = KErrNotFound;
\r
773 if(iCurrentScan==iKeyNames->Count())
\r
777 iView->DrawText(_L("Done!"),TPoint(0,iFontHeight*11));
\r
779 User::After(1000000);
\r
793 if((aType == EEventKeyUp || aType == EEventKeyDown))
\r
796 for(TInt loop=0;loop<16;loop++)
\r
798 if(aKeyEvent.iScanCode==iScanCodes[loop])
\r
800 bitVal=KBitValTable[loop];
\r
805 if(aType == EEventKeyUp)
\r
807 iPad1=iPad1&(65535-bitVal); // remove bit
\r
811 iPad1=(iPad1|bitVal); // set bit
\r
815 if(aType == EEventKey)
\r
817 if(aKeyEvent.iScanCode == iScanCodes[EPicoResetKey])
\r
822 if(aKeyEvent.iScanCode == iScanCodes[EPicoPanLKey] && gFullOffset>0)
\r
826 else if(aKeyEvent.iScanCode == iScanCodes[EPicoPanRKey]&& gFullOffset<144)
\r
833 return EKeyWasConsumed;
\r
836 TInt CPicoDriveUi::SelectFile(TFileName& aFileName)
\r
838 TFileName filename=aFileName;
\r
839 TInt selectedIndex=-1;
\r
840 RArray<TEntry> romList;
\r
841 TDriveList driveList;
\r
842 TBool refresh=EFalse;
\r
843 TInt lastLength=-1;
\r
846 CAknListQueryDialog* dlg = new (ELeave) CAknListQueryDialog(&selectedIndex);
\r
847 CDesCArrayFlat* list=new (ELeave) CDesCArrayFlat(5);
\r
849 if(filename.Length()==0)
\r
852 iEikonEnv->FsSession().DriveList(driveList);
\r
853 for(TInt drive=0;drive<driveList.Length();drive++)
\r
855 if(driveList[drive]!=0)
\r
858 form.Format(_L("%c:\\"),drive+65);
\r
859 list->AppendL(form);
\r
865 CDir* romDir = NULL;;
\r
867 iEikonEnv->FsSession().GetDir(filename,KEntryAttMatchMask,0,romDir);
\r
870 list->AppendL(_L(".. <DIR>"));
\r
872 if(romDir!=NULL && romDir->Count()>0)
\r
874 for(TInt loop=0;loop<romDir->Count();loop++)
\r
876 const TEntry& entry=(*romDir)[loop];
\r
877 TFileName name=entry.iName;
\r
880 name.Append(_L(" <DIR>"));
\r
881 list->AppendL(name);
\r
882 romList.Append(entry);
\r
886 TParsePtr parse(name);
\r
888 if(parse.Ext().CompareF(_L(".bin"))==KErrNone ||
\r
889 parse.Ext().CompareF(_L(".smd"))==KErrNone ||
\r
890 parse.Ext().CompareF(_L(".zip"))==KErrNone)
\r
892 romList.Append(entry);
\r
893 list->AppendL(name);
\r
901 else // no files found.. or path not found.. return to
\r
903 if(filename.Length()>3) // more than a c:\ specified
\r
907 filename=KNullDesC();
\r
909 else return EFalse;
\r
913 if(list->Count()>0)
\r
915 dlg->PrepareLC(R_PICO_FILE_SELECT_DIALOG);
\r
916 dlg->SetItemTextArray(list);
\r
919 if(filename.Length()==0)
\r
921 TFileName driveLetter;
\r
923 TInt countedDrives=0;
\r
924 for(TInt drive=0;drive<driveList.Length();drive++)
\r
926 if(driveList[drive]!=0 && countedDrives==selectedIndex)
\r
928 driveLetter.Format(_L("%c:\\"),drive+65);
\r
932 else if(driveList[drive]!=0) countedDrives++;
\r
935 filename=driveLetter;
\r
940 if(selectedIndex>0)
\r
943 const TEntry& entry=romList[selectedIndex];
\r
944 TFileName name =entry.iName;
\r
947 lastLength=aFileName.Length();
\r
948 filename.Append(name);
\r
949 filename.Append(_L("\\"));
\r
956 filename.Append(name);
\r
957 aFileName=filename;
\r
965 TInt pos=filename.Left(filename.Length()-1).LocateReverse('\\');
\r
966 if(pos!=KErrNotFound)
\r
967 filename=filename.Left(pos+1);// keep
\r
968 else filename=KNullDesC();
\r
969 // and changefilename..
\r
971 //return 2;// go up one.
\r
986 void CPicoDriveUi::SaveSettingsL()
\r
989 CDictionaryStore* prefs = Application()->OpenIniFileLC(iEikonEnv->FsSession());
\r
991 CDictionaryFileStore* prefs=CDictionaryFileStore::OpenLC(iEikonEnv->FsSession(),iAppPath,TUid::Uid(0));
\r
993 ExternalizeL(*prefs);
\r
995 CleanupStack::PopAndDestroy();//close prefs
\r
999 void CPicoDriveUi::ExternalizeL(CDictionaryStore& aStore)
\r
1001 RDictionaryWriteStream writeStream;
\r
1002 writeStream.AssignLC(aStore, KPicoDrivePrefs);
\r
1005 for(loop=0;loop<EPicoNoKeys;loop++)
\r
1007 writeStream.WriteInt32L(iScanCodes[loop]);
\r
1010 writeStream.WriteInt32L(iScrMode);
\r
1011 writeStream.WriteInt32L(PicoOpt);
\r
1012 writeStream.WriteInt32L(iSoundVolume);
\r
1013 writeStream.WriteInt32L(iFrameSkip);
\r
1014 writeStream.WriteInt32L(PsndRate);
\r
1015 writeStream.WriteInt32L(iInterpolate);
\r
1016 writeStream.WriteInt32L(iEnableSixButtons);
\r
1017 writeStream.WriteInt32L(PicoRegionOverride);
\r
1018 TParsePtr parser(iRomName);
\r
1019 writeStream.WriteInt32L(parser.DriveAndPath().Length());
\r
1020 writeStream.WriteL(parser.DriveAndPath(),parser.DriveAndPath().Length());
\r
1021 writeStream.CommitL();
\r
1023 CleanupStack::PopAndDestroy();//writeStream
\r
1026 void CPicoDriveUi::InternalizeL(const CDictionaryStore& aStore)
\r
1028 if (!aStore.IsPresentL(KPicoDrivePrefs))
\r
1030 iFirstStart = ETrue;
\r
1033 RDictionaryReadStream readStream;
\r
1034 readStream.OpenLC(aStore, KPicoDrivePrefs);
\r
1036 for(loop=0;loop<EPicoNoKeys;loop++)
\r
1038 iScanCodes[loop] = readStream.ReadInt32L();
\r
1041 iScrMode=readStream.ReadInt32L();
\r
1042 PicoOpt=readStream.ReadInt32L();
\r
1043 iEnableSound = PicoOpt&3;
\r
1044 iSoundVolume=readStream.ReadInt32L();
\r
1045 iFrameSkip = readStream.ReadInt32L();
\r
1046 PsndRate = readStream.ReadInt32L();
\r
1047 iInterpolate = readStream.ReadInt32L();
\r
1048 iEnableSixButtons = readStream.ReadInt32L();
\r
1049 PicoRegionOverride = readStream.ReadInt32L();
\r
1052 TRAPD(err,len=readStream.ReadInt32L())
\r
1055 readStream.ReadL(iRomName,len);
\r
1058 CleanupStack::PopAndDestroy();//readStream
\r
1061 void CPicoDriveUi::ConstructL()
\r
1064 CAknAppUi::BaseConstructL(CAknAppUi::EAknEnableSkin);
\r
1066 BaseConstructL(ENoAppResourceFile);
\r
1068 framebuff = (unsigned short *) malloc(framebuffsize);
\r
1069 memset(framebuff,0,framebuffsize);
\r
1071 iFontHeight = iEikonEnv->NormalFont()->HeightInPixels()+KLineGap;
\r
1072 iScanCodes[0]= EStdKeyUpArrow;
\r
1073 iScanCodes[1]= EStdKeyDownArrow;
\r
1074 iScanCodes[2]=EStdKeyLeftArrow;
\r
1075 iScanCodes[3]= EStdKeyRightArrow;
\r
1076 iScanCodes[6]=EStdKeyDevice0;
\r
1077 iScanCodes[4]= EStdKeyDevice1;
\r
1078 iScanCodes[5]=EStdKeyDevice3;
\r
1079 iScanCodes[7]=0;//x
\r
1080 iScanCodes[8]=0; // y
\r
1081 iScanCodes[9]=0;//z
\r
1082 iScanCodes[10]=0;// mode
\r
1083 iScanCodes[11]= '0'; // start
\r
1085 gChunk = UserHeap::ChunkHeap(&_L("ROMHEAP"),512000,16384000);
\r
1090 iEikonEnv->RootWin().SetName(_L("PicoDrive"));
\r
1093 process.Rename(_L("PicoDrive"));
\r
1094 TFileName fname =process.FileName();
\r
1095 TParsePtr parser(fname);
\r
1096 name.Append(parser.DriveAndPath());
\r
1098 name.Append(KLitResourceFileName());
\r
1099 iAppPath=_L("C:");
\r
1100 iAppPath.Append(TParsePtr(name).Path());
\r
1101 iAppPath.Append(_L("PicoDriveS60.ini"));
\r
1102 iResourceFileId = iCoeEnv->AddResourceFileL(name); // eb205: needs to hunt around drives
\r
1104 iKeyNames =iEikonEnv->ReadDesCArrayResourceL(R_PICODRIVE_KEYS);
\r
1105 iRegNames = iEikonEnv->ReadDesCArrayResourceL(R_PICODRIVE_REGIONS);
\r
1107 iEikonEnv->FsSession().MkDirAll(TParsePtr(iAppPath).DriveAndPath());
\r
1109 CDictionaryStore* prefs = Application()->OpenIniFileLC(iEikonEnv->FsSession());
\r
1110 InternalizeL(*prefs);
\r
1111 CleanupStack::PopAndDestroy();//close prefs
\r
1113 TRAPD(err,{CDictionaryFileStore* prefs=CDictionaryFileStore::OpenLC(iEikonEnv->FsSession(),iAppPath,TUid::Uid(0));
\r
1114 InternalizeL(*prefs);
\r
1115 CleanupStack::PopAndDestroy();//close prefs
\r
1121 iPicoMenu = EAboutPicoMenu;
\r
1124 iView=new (ELeave)CQPicoDriveView;
\r
1125 iView->ConstructL();
\r
1126 AddToStackL(iView);
\r
1127 iDisplayMode =iEikonEnv->ScreenDevice()->DisplayMode();
\r
1128 if(iDisplayMode != EColor64K && iDisplayMode != EColor4K)
\r
1130 iDisplayMode=EColor64K;; // Also tried to switch to by the view.
\r
1132 CalculatePaletteTable();
\r
1133 iBackBuffer= new (ELeave)CFbsBitmap;
\r
1134 iBackBuffer->Create(iEikonEnv->ScreenDevice()->SizeInPixels(),iDisplayMode);
\r
1135 TBitmapUtil util(iBackBuffer);
\r
1136 util.Begin(TPoint(0,0));
\r
1137 TSize sz=iBackBuffer->SizeInPixels();
\r
1138 Targ.view = TRect(TPoint(0,0),sz);
\r
1139 TInt dataSize=sz.iWidth*sz.iHeight*2;
\r
1140 Targ.scanline_length = sz.iWidth*2;
\r
1141 Targ.screen_offset = Targ.scanline_length*(sz.iHeight-1);
\r
1142 TPtr8 ptr(reinterpret_cast<unsigned char*>(iBackBuffer->DataAddress()),dataSize,dataSize);
\r
1145 SetKeyBlockMode(ENoKeyBlock);
\r
1148 iSndStream = CMdaAudioOutputStream::NewL(*this);
\r
1149 iAudioSettings.Query();
\r
1150 iAudioSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate8000Hz;
\r
1151 iAudioSettings.iChannels = TMdaAudioDataSettings::EChannelsMono;
\r
1152 iAudioSettings.iFlags = 0;
\r
1153 iAudioSettings.iVolume = iAudioSettings.iMaxVolume/2;
\r
1154 iSndStream->Open(&iAudioSettings);
\r
1155 CActiveScheduler::Start(); // wait for open
\r
1158 void CPicoDriveUi::PutAbout(TBool iOnlyRedraw)
\r
1160 TPtrC8 charPtr((unsigned char*)KAboutText,strlen(KAboutText));
\r
1161 HBufC* credits = HBufC::NewLC(charPtr.Length());
\r
1162 credits->Des().Copy(charPtr);
\r
1164 if(iLastAboutPos>=credits->Length())
\r
1166 iLastAboutPos = -1;
\r
1168 iPicoMenu = EPicoMainMenu;
\r
1173 if(iLastAboutPos == -1)
\r
1174 iLastAboutPos = 0;
\r
1175 iView->DrawText(_L("PicoDrive S60 Credits"),TPoint(0,0));
\r
1176 if(iOnlyRedraw && iLastAboutPos == 0)
\r
1177 iView->DrawTextInRect(*credits,TRect(0,iFontHeight*2,Targ.view.iBr.iX,Targ.view.iBr.iY),iLastAboutPos);
\r
1179 iLastAboutPos = iView->DrawTextInRect(*credits,TRect(0,iFontHeight*2,Targ.view.iBr.iX,Targ.view.iBr.iY),iLastAboutPos);
\r
1181 CleanupStack::PopAndDestroy(credits);
\r
1184 void CPicoDriveUi::PutMainMenu()
\r
1186 iView->DrawText(_L("PicoDrive S60"),TPoint(0,0));
\r
1187 iView->DrawText(_L("by Dave et Co"),TPoint(0,iFontHeight*1));
\r
1189 iView->DrawText(_L("Load ROM"),TPoint(0,iFontHeight*3),iSelection==0);
\r
1190 iView->DrawText(_L("Load state"),TPoint(0,iFontHeight*4),iSelection==1);
\r
1191 iView->DrawText(_L("Save state"),TPoint(0,iFontHeight*5),iSelection==2);
\r
1192 iView->DrawText(_L("Configure controls"),TPoint(0,iFontHeight*6),iSelection==3);
\r
1193 iView->DrawText(_L("Configure screen"),TPoint(0,iFontHeight*7),iSelection==4);
\r
1194 iView->DrawText(_L("Configure sound"),TPoint(0,iFontHeight*8),iSelection==5);
\r
1195 iView->DrawText(_L("Game Genie/Cheats"),TPoint(0,iFontHeight*9),iSelection==6);
\r
1197 iView->DrawText(_L("Reset"),TPoint(0,iFontHeight*10),iSelection==7);
\r
1199 iView->DrawText(_L("Credits"),TPoint(0,iFontHeight*11),iSelection==8);
\r
1200 iView->DrawText(_L("Exit"),TPoint(0,iFontHeight*12),iSelection==9);
\r
1201 if(iRomName.Length()>0)
\r
1203 iView->DrawText(TParsePtr(iRomName).Name(),TPoint(0,iFontHeight*13));
\r
1207 iView->DrawText(_L("No rom loaded"),TPoint(0,iFontHeight*13));
\r
1212 void CPicoDriveUi::PutScreenSelect()
\r
1214 TInt regionIndex = 0;
\r
1216 switch(PicoRegionOverride)
\r
1235 iView->DrawText(_L("PicoDrive S60"),TPoint(0,0));
\r
1236 iView->DrawText(_L("Screen options"),TPoint(0,iFontHeight));
\r
1237 iView->DrawText(_L("Portrait"),TPoint(0,iFontHeight*3),iScrMode==0);
\r
1238 iView->DrawText(_L("Landscape Left"),TPoint(0,iFontHeight*4),iScrMode==1);
\r
1239 iView->DrawText(_L("Landscape Right"),TPoint(0,iFontHeight*5),iScrMode==2);
\r
1240 iView->DrawText(_L("Portrait stretched"),TPoint(0,iFontHeight*6),iScrMode==3);
\r
1241 iView->DrawText(_L("Portrait full"),TPoint(0,iFontHeight*7),iScrMode==4);
\r
1244 iView->DrawText(_L("Interpolate on"),TPoint(0,iFontHeight*8),iScrMode==5);
\r
1248 iView->DrawText(_L("Interpolate off"),TPoint(0,iFontHeight*8),iScrMode==5);
\r
1251 if(iFrameSkip == -1)
\r
1253 iView->DrawText(_L("Frameskip auto"),TPoint(0,iFontHeight*9),iScrMode==6);
\r
1258 skip.Format(_L("Frameskip %d"),iFrameSkip);
\r
1259 iView->DrawText(skip,TPoint(0,iFontHeight*9),iScrMode==6);
\r
1262 if(PicoOpt & 0x40)
\r
1264 iView->DrawText(_L("Accurate timing on"),TPoint(0,iFontHeight*10),iScrMode==7);
\r
1268 iView->DrawText(_L("Accurate timing off"),TPoint(0,iFontHeight*10),iScrMode==7);
\r
1271 if(PicoOpt & 0x80)
\r
1273 iView->DrawText(_L("Accurate sprites on"),TPoint(0,iFontHeight*11),iScrMode==8);
\r
1277 iView->DrawText(_L("Accurate sprites off"),TPoint(0,iFontHeight*11),iScrMode==8);
\r
1280 if(PicoOpt & 0x10)
\r
1282 iView->DrawText(_L("Alt. renderer on"),TPoint(0,iFontHeight*12),iScrMode==9);
\r
1286 iView->DrawText(_L("Alt. renderer off"),TPoint(0,iFontHeight*12),iScrMode==9);
\r
1289 iView->DrawText(iRegNames->MdcaPoint(regionIndex),TPoint(0,iFontHeight*13),iScrMode==10);
\r
1293 void CPicoDriveUi::PutSoundSelect()
\r
1296 iView->DrawText(_L("PicoDrive S60"),TPoint(0,0));
\r
1297 iView->DrawText(_L("Sound options"),TPoint(0,iFontHeight));
\r
1299 iView->DrawText(_L("Z80 enabled"),TPoint(0,iFontHeight*3),iSndSelection==EEnableZ80);
\r
1301 iView->DrawText(_L("Z80 disabled"),TPoint(0,iFontHeight*3),iSndSelection==EEnableZ80);
\r
1303 iView->DrawText(_L("YM2612 enabled"),TPoint(0,iFontHeight*4),iSndSelection==EEnableYM2612);
\r
1305 iView->DrawText(_L("YM2612 disabled"),TPoint(0,iFontHeight*4),iSndSelection==EEnableYM2612);
\r
1308 iView->DrawText(_L("SN76496 enabled"),TPoint(0,iFontHeight*5),iSndSelection==EEnableSN76496);
\r
1310 iView->DrawText(_L("SN76496 disabled"),TPoint(0,iFontHeight*5),iSndSelection==EEnableSN76496);
\r
1314 vol.Format(_L("Volume %d"),iSoundVolume*10);
\r
1315 iView->DrawText(vol,TPoint(0,iFontHeight*6),iSndSelection==ESoundVolume);
\r
1317 vol.Format(_L("Sample rate %dKhz"),PsndRate/1000);
\r
1318 iView->DrawText(vol,TPoint(0,iFontHeight*7),iSndSelection==ESoundRate);
\r
1322 void CPicoDriveUi::PutCheatSelect()
\r
1325 iView->DrawText(_L("PicoDrive S60"),TPoint(0,0));
\r
1326 iView->DrawText(_L("Cheat options"),TPoint(0,iFontHeight));
\r
1328 iView->DrawText(_L("Add cheat"),TPoint(0,iFontHeight*3),iCheatSelection==EAddCheat);
\r
1329 iView->DrawText(_L("Clear cheats"),TPoint(0,iFontHeight*4),iCheatSelection==EClearCheats);
\r
1330 TInt noCheats = 0;
\r
1331 TBuf<17>cheatCode;
\r
1333 for(TInt i = iListOffset; (i < 256)&&(noCheats<5); i++)
\r
1335 if (Liste_GG[i].code[0] != 0)
\r
1338 TRgb textColour = Liste_GG[i].active?KRgbGreen:KRgbDarkGreen;
\r
1339 if(iCheatSelection == 2+(i-iListOffset))
\r
1341 textColour = Liste_GG[i].active?KRgbRed:KRgbDarkRed;
\r
1344 TPtrC8 ptr((const unsigned char*)Liste_GG[i].code,strlen(Liste_GG[i].code));
\r
1345 cheatCode.Copy(ptr);
\r
1347 iView->DrawText(cheatCode,TPoint(0,iFontHeight*(5+noCheats)),EFalse,textColour);
\r
1353 iView->DrawText(_L("Supports GG & Patch"),TPoint(0,iFontHeight*11));
\r
1354 iView->DrawText(_L("GG: XXXX-XXXX"),TPoint(0,iFontHeight*12));
\r
1355 iView->DrawText(_L("Patch: XXXXXX:YYYY"),TPoint(0,iFontHeight*13));
\r
1358 void CPicoDriveUi::PutControllerSelect()
\r
1361 iView->DrawText(_L("PicoDrive S60"),TPoint(0,0));
\r
1362 iView->DrawText(_L("Controller options"),TPoint(0,iFontHeight));
\r
1363 if (iEnableSixButtons)
\r
1364 iView->DrawText(_L("6 button pad"),TPoint(0,iFontHeight*3),iCtrlSelection==EControllerType);
\r
1366 iView->DrawText(_L("3 button pad"),TPoint(0,iFontHeight*3),iCtrlSelection==EControllerType);
\r
1367 iView->DrawText(_L("Configure keys"),TPoint(0,iFontHeight*4),iCtrlSelection==EConfigControls);
\r
1374 void CPicoDriveUi::PutConfigKeys()
\r
1376 iView->DrawText(_L("PicoDrive S60"),TPoint(0,0));
\r
1377 iView->DrawText(_L("Configure keys"),TPoint(0,iFontHeight));
\r
1378 iView->DrawText(_L("Please press:"),TPoint(0,iFontHeight*3));
\r
1379 iView->DrawText(iKeyNames->MdcaPoint(iCurrentScan),TPoint(0,iFontHeight*4));
\r
1381 iView->DrawText(_L("Press 'C' to skip this!"),TPoint(0,iFontHeight*6));
\r
1385 TInt CPicoDriveUi::IdleCallBackStop(TAny* /*aAppUi*/)
\r
1387 CActiveScheduler::Stop();
\r
1391 TInt CPicoDriveUi::StartEmulatorL(TAny* aAppUi)
\r
1393 static_cast<CPicoDriveUi*>(aAppUi)->StartEmulatorL();
\r
1397 void CPicoDriveUi::HandleForegroundEventL(TBool aForeground)
\r
1401 iView->iForeground=aForeground;
\r
1408 iView->AbortNow(RDirectScreenAccess::ETerminateCancel);
\r
1415 iView->Restart(RDirectScreenAccess::ETerminateCancel);
\r
1419 SetKeyBlockMode(ENoKeyBlock);
\r
1424 void CPicoDriveUi::UpdateScreen()
\r
1429 if(iCurrentScan>=0)
\r
1433 else if(iPicoMenu==ESelectScrMenu)
\r
1435 PutScreenSelect();
\r
1437 else if (iPicoMenu==EAboutPicoMenu)
\r
1441 else if (iPicoMenu==ESelectSoundMenu)
\r
1445 else if (iPicoMenu==ESelectControlsMenu)
\r
1447 PutControllerSelect();
\r
1449 else if (iPicoMenu==ESelectCheatMenu)
\r
1459 void CPicoDriveUi::StartEmulatorL()
\r
1465 LastSecond=(TInt)(time.Int64()/1000);//GetTickCount();
\r
1467 LastSecond=(TInt)(time.Int64()/1000).GetTInt();//GetTickCount();
\r
1471 iSndStream->SetVolume((iSndStream->MaxVolume()*iSoundVolume)/10);
\r
1474 while(iEmuRunning)
\r
1478 iSndStream->Stop();
\r
1485 * Calculates the palette table 0-4096
\r
1487 void CPicoDriveUi::CalculatePaletteTable()
\r
1489 for(TInt cram =0;cram<4096;cram++)
\r
1491 if(iDisplayMode == EColor4K)
\r
1493 unsigned short high=0x111;
\r
1494 high|=(cram&0x00e)<<8; // Red
\r
1495 high|=(cram&0x0e0); // Green
\r
1496 high|=(cram&0xe00)>> 8; // Blue
\r
1497 gColorMapTab[cram] = high;
\r
1499 else // 64K color mode
\r
1501 unsigned short high=0x0841;
\r
1502 // Convert 0000bbbb ggggrrrr
\r
1503 // to rrrr1ggg g10bbbb1
\r
1504 high|=(cram&0x00f)<<12; // Red
\r
1505 high|=(cram&0x0f0)<< 3; // Green
\r
1506 high|=(cram&0xf00)>> 7; // Blue
\r
1507 gColorMapTab[cram] = high;
\r
1512 int CPicoDriveUi::TargetInit()
\r
1515 TUint16 currentLine = 0;
\r
1516 TReal xFactor = 1;
\r
1517 TReal xNarrowFactor = 1;
\r
1518 TReal yFactor = 1;
\r
1521 memset(framebuff,0,framebuffsize);
\r
1526 xFactor = ((TReal)Targ.view.iBr.iX/(TReal)320);
\r
1527 xNarrowFactor = ((TReal)Targ.view.iBr.iX/(TReal)256);
\r
1532 if(xNarrowFactor>1)
\r
1533 xNarrowFactor = 1;
\r
1535 yFactor = ((TReal)Targ.view.iBr.iY/(TReal)240);
\r
1540 for(loop = 0;loop<256;loop++)
\r
1542 TInt line = (loop*xNarrowFactor);
\r
1543 TInt nextLine = ((loop+1)*xNarrowFactor);
\r
1544 if(line != nextLine)
\r
1546 gNarrowColumnStepTable[loop] = 1;
\r
1550 gNarrowColumnStepTable[loop] = 0;
\r
1554 for(loop = 0;loop<320;loop++)
\r
1556 TInt line = (loop*xFactor);
\r
1557 TInt nextLine = ((loop+1)*xFactor);
\r
1558 if( line != nextLine)
\r
1560 gColumnStepTable[loop] = 1;
\r
1564 gColumnStepTable[loop] = 0;
\r
1568 for(TInt loop = 0;loop<240;loop++)
\r
1570 gLineTable[loop] = currentLine;
\r
1571 if((loop*yFactor) != ((loop+1)*yFactor))
\r
1574 myPicoScan=EmulateScan16;
\r
1578 myPicoScan=EmulateScan16_176Interpolate;
\r
1580 myPicoScan=EmulateScan16_176;
\r
1581 for(TInt loop = 0;loop<240;loop++)
\r
1583 gLineTable[loop] = currentLine;
\r
1584 if(((loop*3)/4) != (((loop+1)*3)/4))
\r
1588 KBitValTable[0] = 1;
\r
1589 KBitValTable[1] = 2;
\r
1590 KBitValTable[2] = 4;
\r
1591 KBitValTable[3] = 8;
\r
1594 else if (iScrMode == 1 || iScrMode == 2)
\r
1596 xFactor = ((TReal)Targ.view.iBr.iY/(TReal)320);
\r
1597 xNarrowFactor = ((TReal)Targ.view.iBr.iY/(TReal)256);
\r
1602 if(xNarrowFactor>2)
\r
1603 xNarrowFactor = 2;
\r
1605 yFactor = ((TReal)Targ.view.iBr.iX/(TReal)240);
\r
1609 for(loop = 0;loop<256;loop++)
\r
1611 TInt col = (loop*xNarrowFactor);
\r
1612 TInt nextCol= ((loop+1)*xNarrowFactor);
\r
1614 gNarrowColumnStepTable[loop] = nextCol-col;;
\r
1617 for(loop = 0;loop<320;loop++)
\r
1619 TInt col = (loop*xFactor);
\r
1620 TInt nextCol= ((loop+1)*xFactor);
\r
1622 gColumnStepTable[loop] = nextCol-col;;
\r
1625 for(TInt loop = 0;loop<240;loop++)
\r
1627 gLineTable[loop] = currentLine;
\r
1628 TInt line = (loop*yFactor);
\r
1629 TInt nextLine = ((loop+1)*yFactor);
\r
1630 currentLine+=(nextLine-line);
\r
1634 KBitValTable[0] = 4;
\r
1635 KBitValTable[1] = 8;
\r
1636 KBitValTable[2] = 2;
\r
1637 KBitValTable[3] = 1;
\r
1638 myPicoScan=EmulateScanFullRight16;
\r
1642 KBitValTable[0] = 8;
\r
1643 KBitValTable[1] = 4;
\r
1644 KBitValTable[2] = 1;
\r
1645 KBitValTable[3] = 2;
\r
1646 myPicoScan=EmulateScanFull16;
\r
1649 else if (iScrMode == 1)
\r
1652 myPicoScan=EmulateScanFull16_176Interpolate;
\r
1654 myPicoScan=EmulateScanFull16_176;
\r
1656 for(TInt loop = 0;loop<240;loop++)
\r
1658 gLineTable[loop] = currentLine;
\r
1659 if(((loop*3)/4) != (((loop+1)*3)/4))
\r
1662 KBitValTable[0] = 8;
\r
1663 KBitValTable[1] = 4;
\r
1664 KBitValTable[2] = 1;
\r
1665 KBitValTable[3] = 2;
\r
1669 else if(iScrMode==2)
\r
1672 myPicoScan=EmulateScanFullRight16_176Interpolate;
\r
1674 myPicoScan=EmulateScanFullRight16_176;
\r
1675 for(TInt loop = 0;loop<240;loop++)
\r
1677 gLineTable[loop] = currentLine;
\r
1678 if(((loop*3)/4) != (((loop+1)*3)/4))
\r
1681 KBitValTable[0] = 4;
\r
1682 KBitValTable[1] = 8;
\r
1683 KBitValTable[2] = 2;
\r
1684 KBitValTable[3] = 1;
\r
1690 xFactor = ((TReal)Targ.view.iBr.iX/(TReal)320);
\r
1691 xNarrowFactor = ((TReal)Targ.view.iBr.iX/(TReal)256);
\r
1696 if(xNarrowFactor>2)
\r
1697 xNarrowFactor = 2;
\r
1699 yFactor = ((TReal)Targ.view.iBr.iY/(TReal)240);
\r
1704 for(loop = 0;loop<256;loop++)
\r
1706 TInt col = (loop*xNarrowFactor);
\r
1707 TInt nextCol= ((loop+1)*xNarrowFactor);
\r
1709 gNarrowColumnStepTable[loop] = nextCol-col;;
\r
1712 for(loop = 0;loop<320;loop++)
\r
1714 TInt col = (loop*xFactor);
\r
1715 TInt nextCol= ((loop+1)*xFactor);
\r
1717 gColumnStepTable[loop] = nextCol-col;;
\r
1720 for(TInt loop = 0;loop<240;loop++)
\r
1722 gLineTable[loop] = currentLine;
\r
1723 TInt line = (loop*yFactor);
\r
1724 TInt nextLine = ((loop+1)*yFactor);
\r
1725 currentLine+=(nextLine-line);
\r
1727 myPicoScan=EmulateStretchScan16;
\r
1731 myPicoScan=EmulateStretchScan16_320;
\r
1732 iInterpolate = EFalse; // not needed
\r
1737 myPicoScan=EmulateStretchScan16_176Interpolate;
\r
1739 myPicoScan=EmulateStretchScan16_176;
\r
1742 for(TInt loop = 0;loop<240;loop++)
\r
1744 gLineTable[loop] = currentLine;
\r
1745 if(((loop*15)/16) != (((loop+1)*15)/16))
\r
1749 KBitValTable[0] = 1;
\r
1750 KBitValTable[1] = 2;
\r
1751 KBitValTable[2] = 4;
\r
1752 KBitValTable[3] = 8;
\r
1756 iView->SetRect(TRect(TPoint(0,0),iEikonEnv->ScreenDevice()->SizeInPixels()));
\r
1763 iPutRect=TRect(TPoint(0,0),TSize(xFactor*320,yFactor*240));
\r
1764 iPutPoint=TPoint(Targ.view.Size().iWidth/2-iPutRect.Size().iWidth/2,Targ.view.Size().iHeight/2-iPutRect.Size().iHeight/2);
\r
1769 iPutRect=TRect(TPoint(0,0),TSize(yFactor*240,xFactor*320));
\r
1770 iPutPoint=TPoint(Targ.view.Size().iWidth/2-iPutRect.Size().iWidth/2,Targ.view.Size().iHeight/2-iPutRect.Size().iHeight/2);
\r
1778 iPutPoint=TPoint(0,20);
\r
1779 iPutRect=TRect(TPoint(0,0),TSize(176,168));
\r
1783 iPutPoint=TPoint(4,1);
\r
1784 iPutRect=TRect(TPoint(4,1),TSize(168,205));
\r
1789 iPutPoint=TPoint(0,0);
\r
1790 iPutRect=TRect(TPoint(0,0),TSize(176,208));
\r
1794 CalulateLineStarts();
\r
1798 #define KCenterOffset 8
\r
1800 #define KCenterOffset 0
\r
1802 void CPicoDriveUi::CalulateLineStarts()
\r
1810 for(TInt loop = 0;loop<Targ.view.Size().iHeight;loop++)
\r
1812 gLineOffsets[loop] = loop*Targ.scanline_length;
\r
1817 for(TInt loop = 0;loop<Targ.view.Size().iHeight;loop++)
\r
1819 gLineOffsets[loop] = loop*2+Targ.screen_offset+KCenterOffset;
\r
1824 for(TInt loop = 0;loop<Targ.view.Size().iHeight;loop++)
\r
1826 gLineOffsets[loop] = Targ.scanline_length-loop*2-KCenterOffset;
\r
1832 bool IsZip(char *filename)
\r
1834 unsigned char buf[2];
\r
1837 if((fp=fopen(filename,"rb"))!=NULL)
\r
1839 fread(buf, 2, 1, fp);
\r
1841 return(memcmp(buf,"PK",2)==0);
\r
1847 int CPicoDriveUi::EmulateInit()
\r
1850 EmulateExit(); // Make sure exited
\r
1851 TargetInit(); // Find out where to put the screen
\r
1854 if(IsZip(RomName))
\r
1856 if(CartLoadZip(RomName,&RomData,&RomSize))
\r
1865 TInt error = file.Open(iEikonEnv->FsSession(),iRomName,0);
\r
1867 f=fopen(RomName,"rb");
\r
1870 TInt result =PicoCartLoad(f,&RomData,&RomSize);
\r
1873 return 1; // failed to load cart
\r
1876 TParsePtr parser(iRomName);
\r
1877 TPtr8 ptr(Pico.rom_name,511);
\r
1878 ptr.Copy(parser.DriveAndPath());
\r
1879 ptr.Append(parser.Name());
\r
1880 ptr.ZeroTerminate();
\r
1882 PicoCartInsert(RomData,RomSize);
\r
1883 Load_Patch_File();
\r
1884 saveLoadGame(1, 1); // load sram if any saved
\r
1886 if(!iEnableSixButtons)
\r
1887 PicoOpt=PicoOpt& 223;
\r
1889 PicoOpt=PicoOpt|32;
\r
1893 void CPicoDriveUi::EmulateExit()
\r
1895 // Save sram if any
\r
1896 if(RomData != NULL)
\r
1900 saveLoadGame(0,1);
\r
1904 Save_Patch_File();
\r
1905 // Remove cartridge
\r
1906 PicoCartInsert(NULL,0);
\r
1907 PicoUnloadCart(RomData);
\r
1908 RomData=NULL; RomSize=0;
\r
1913 int CPicoDriveUi::InputFrame()
\r
1917 PsndOut=(short*)(iMonoSound.Ptr()+2*iCurrentSeg*PsndLen);
\r
1931 if(iCurrentSeg==6)
\r
1933 iMonoSound.SetLength(PsndLen*2*6);
\r
1934 iSndStream->WriteL(iMonoSound);
\r
1939 TCallBack callback(IdleCallBackStop,this);
\r
1940 iIdleCallBack.Cancel();
\r
1941 iIdleCallBack.Set(callback);
\r
1942 iIdleCallBack.CallBack();
\r
1943 CActiveScheduler::Start();
\r
1952 int CPicoDriveUi::EmulateFrame()
\r
1957 // Speed throttle:
\r
1958 if(iFrameSkip ==-1) // auto skipping
\r
1960 int time=0,frame=0;
\r
1962 newtime.HomeTime();
\r
1964 TInt64 tic=(newtime.Int64()/1000);
\r
1965 time=(tic-LastSecond); // This will be about 0-1000 ms
\r
1967 TInt64 tic=(newtime.Int64()/1000).GetTInt();
\r
1968 time=(tic-LastSecond).GetTInt(); // This will be about 0-1000 ms
\r
1970 frame=time*FramesPerSecond/1000;
\r
1971 need=frame-FramesDone;
\r
1974 if (FramesPerSecond>0)
\r
1976 // Carry over any >60 frame count to one second
\r
1977 while (FramesDone>=FramesPerSecond) { FramesDone-=FramesPerSecond; LastSecond+=1000; }
\r
1984 nextTime.HomeTime();
\r
1985 }while((nextTime.Int64()-newtime.Int64())<15000);
\r
1987 if (need>10) need=10; // Limit frame skipping
\r
1991 need = iFrameSkip+1;
\r
1994 for (i=0;i<need-1;i++) InputFrame(); // Frame skip if needed
\r
1997 // Now final frame is drawn:
\r
1998 TBitmapUtil util(iBackBuffer);
\r
1999 util.Begin(TPoint(0,0));
\r
2000 Targ.screen=(unsigned char*)iBackBuffer->DataAddress();
\r
2002 if (Targ.screen == NULL)
\r
2008 PicoScan=myPicoScan; // Setup scanline callback
\r
2012 if(PicoOpt & 0x10) // need to render separatly
\r
2014 unsigned short* framebuffptr = framebuff+2632;
\r
2016 if(!(Pico.video.reg[12]&1))
\r
2018 framebuffptr=framebuffptr-32;
\r
2022 for(TInt loop = 0;loop<224;loop++)
\r
2026 skipNext = PicoScan(loop,framebuffptr);
\r
2030 framebuffptr+=328;
\r
2036 Targ.screen = NULL;
\r
2038 iView->PutBitmap(iBackBuffer,iPutPoint,iPutRect);;
\r
2044 void CPicoDriveUi::MaoscOpenComplete(TInt aError)
\r
2046 if(aError == KErrNone)
\r
2048 iSndStream->SetPriority(EPriorityMuchMore, EMdaPriorityPreferenceNone);
\r
2049 iSndStream->SetVolume((iSndStream->MaxVolume()*iSoundVolume)/10);
\r
2050 if(!UpdatePSndRate())
\r
2056 CActiveScheduler::Stop();
\r
2059 void CPicoDriveUi::MaoscBufferCopied(TInt /*aError*/, const TDesC8& /*aBuffer*/)
\r
2063 void CPicoDriveUi::MaoscPlayComplete(TInt aError)
\r
2065 if(aError != KErrNone)
\r
2067 iSndStream->SetVolume((iSndStream->MaxVolume()*iSoundVolume)/10);
\r
2072 TBool CPicoDriveUi::UpdatePSndRate()
\r
2074 TInt sampleRate = TMdaAudioDataSettings::ESampleRate8000Hz;
\r
2075 if(PsndRate == 11025)
\r
2076 sampleRate = TMdaAudioDataSettings::ESampleRate11025Hz;
\r
2077 else if (PsndRate == 16000)
\r
2078 sampleRate = TMdaAudioDataSettings::ESampleRate16000Hz;
\r
2079 else if (PsndRate == 22050)
\r
2080 sampleRate = TMdaAudioDataSettings::ESampleRate22050Hz;
\r
2082 TRAPD(err,iSndStream->SetAudioPropertiesL(sampleRate,TMdaAudioDataSettings::EChannelsMono));
\r
2083 return (err == KErrNone);
\r
2086 size_t gzRead2(void *p, size_t _size, size_t _n, void *file)
\r
2088 return gzread(file, p, _n);
\r
2092 size_t gzWrite2(void *p, size_t _size, size_t _n, void *file)
\r
2094 return gzwrite(file, p, _n);
\r
2099 // this function is shared between both threads
\r
2100 int CPicoDriveUi::saveLoadGame(int load, int sram)
\r
2104 if(!(iRomName.Length()>0)) return -1;
\r
2106 // make save filename
\r
2107 strcpy(saveFname,RomName);
\r
2108 saveFname[KMaxFileName-5] = 0;
\r
2109 if(saveFname[strlen(saveFname)-4] == '.') saveFname[strlen(saveFname)-4] = 0;
\r
2110 strcat(saveFname, sram ? ".srm" : ".mds");
\r
2113 int sram_size = SRam.end-SRam.start+1;
\r
2114 if(SRam.reg_back & 4) sram_size=0x2000;
\r
2115 if(!SRam.data) return 0; // SRam forcefully disabled for this game
\r
2117 PmovFile = fopen(saveFname, "rb");
\r
2118 if(!PmovFile) return -1;
\r
2119 fread(SRam.data, 1, sram_size, (FILE *) PmovFile);
\r
2120 fclose((FILE *) PmovFile);
\r
2122 // sram save needs some special processing
\r
2123 // see if we have anything to save
\r
2124 for(; sram_size > 0; sram_size--)
\r
2125 if(SRam.data[sram_size-1]) break;
\r
2128 PmovFile = fopen(saveFname, "wb");
\r
2129 res = fwrite(SRam.data, 1, sram_size, (FILE *) PmovFile);
\r
2130 res = (res != sram_size) ? -1 : 0;
\r
2131 fclose((FILE *) PmovFile);
\r
2138 //if(currentConfig.iFlags & 0x80) {
\r
2139 strcat(saveFname, ".gz");
\r
2140 if( (PmovFile = gzopen(saveFname, load ? "rb" : "wb")) ) {
\r
2141 areaRead = gzRead2;
\r
2142 areaWrite = gzWrite2;
\r
2143 if(!load) gzsetparams(PmovFile, 9, Z_DEFAULT_STRATEGY);
\r
2145 saveFname[strlen(saveFname)-3] = 0;
\r
2148 if(!PmovFile) { // gzip failed or was disabled
\r
2149 if( (PmovFile = fopen(saveFname, load ? "rb" : "wb")) ) {
\r
2150 areaRead = (arearw *) fread;
\r
2151 areaWrite = (arearw *) fwrite;
\r
2155 PmovAction = load ? 6 : 5; // load/save
\r
2157 if(areaRead == gzRead2)
\r
2158 gzclose(PmovFile);
\r
2159 else fclose ((FILE *) PmovFile);
\r
2170 CQPicoDriveView::~CQPicoDriveView()
\r
2176 void CQPicoDriveView::Restart(RDirectScreenAccess::TTerminationReasons /*aReason*/)
\r
2182 iDsa->Gc()->SetClippingRegion(iDsa->DrawingRegion());
\r
2187 void CQPicoDriveView::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
\r
2190 iDrawingOn=EFalse;
\r
2195 void CQPicoDriveView::Draw(const TRect& aRect) const
\r
2197 CWindowGc& gc=SystemGc();
\r
2199 gc.SetBrushColor(KRgbBlack);
\r
2200 gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
\r
2201 gc.SetPenStyle(CGraphicsContext::ENullPen);
\r
2202 gc.DrawRect(aRect);
\r
2203 static_cast<CPicoDriveUi*>(iEikonEnv->EikAppUi())->StartAsynchUpdate();
\r
2206 void CQPicoDriveView::ConstructL()
\r
2211 SetRect(TRect(TPoint(0,0),iEikonEnv->ScreenDevice()->SizeInPixels())/*iEikonEnv->EikAppUi()->ClientRect()*/);
\r
2212 iDsa=CDirectScreenAccess::NewL(iEikonEnv->WsSession(),*iEikonEnv->ScreenDevice(),Window(),*this);
\r
2214 iDsa->Gc()->SetClippingRegion(iDsa->DrawingRegion());
\r
2216 if(Window().DisplayMode() != EColor4K && Window().DisplayMode() != EColor64K)
\r
2218 Window().SetRequiredDisplayMode(EColor64K); // Try to set 64K color mode
\r
2221 void CQPicoDriveView::Clear()
\r
2223 CBitmapContext* gc;
\r
2234 gc->SetBrushColor(KRgbBlack);
\r
2235 gc->SetBrushStyle(CGraphicsContext::ESolidBrush);
\r
2236 gc->SetPenStyle(CGraphicsContext::ENullPen);
\r
2237 gc->DrawRect(Rect());
\r
2240 iDsa->ScreenDevice()->Update();
\r
2241 iEikonEnv->WsSession().Flush();
\r
2249 void CQPicoDriveView::DrawText(const TDesC& aText,TPoint aPoint,TBool aHighLight,TRgb aTextColour)
\r
2251 CBitmapContext* gc;
\r
2262 gc->SetBrushColor(KRgbBlack);
\r
2263 gc->SetBrushStyle(CGraphicsContext::ESolidBrush);
\r
2266 gc->SetPenColor(aTextColour);
\r
2270 gc->SetPenColor(KRgbRed);
\r
2272 gc->SetPenStyle(CGraphicsContext::ESolidPen);
\r
2273 aPoint.iY+=iEikonEnv->NormalFont()->HeightInPixels()-2;
\r
2274 aPoint.iX=Size().iWidth/2-iEikonEnv->NormalFont()->TextWidthInPixels(aText)/2;
\r
2275 gc->UseFont(iEikonEnv->NormalFont());
\r
2276 gc->DrawText(aText,aPoint);
\r
2277 gc->DiscardFont();
\r
2281 iDsa->ScreenDevice()->Update();
\r
2289 TInt CQPicoDriveView::DrawTextInRect(const TDesC& aText,TRect aRect,TInt aStartPos)
\r
2291 CBitmapContext* gc;
\r
2292 TInt pos = aStartPos;
\r
2293 TInt len = aText.Length();
\r
2304 gc->SetBrushColor(KRgbBlack);
\r
2305 gc->SetBrushStyle(CGraphicsContext::ESolidBrush);
\r
2307 gc->SetPenColor(KRgbWhite);
\r
2309 gc->SetPenStyle(CGraphicsContext::ESolidPen);
\r
2310 gc->UseFont(iEikonEnv->DenseFont());
\r
2311 while(pos<len && aRect.iTl.iY<aRect.iBr.iY-(iEikonEnv->DenseFont()->HeightInPixels()+3))
\r
2313 TInt newline = aText.Right(len-pos).Locate('\n');
\r
2314 if(newline == KErrNotFound)
\r
2315 newline=(len-1)-pos;
\r
2316 gc->DrawText(aText.Mid(pos,newline),aRect,iEikonEnv->DenseFont()->HeightInPixels());
\r
2317 pos=pos+newline+1; // skip new line
\r
2318 aRect.iTl+=TSize(0,iEikonEnv->DenseFont()->HeightInPixels()+3);
\r
2320 gc->DiscardFont();
\r
2324 iDsa->ScreenDevice()->Update();
\r
2334 void CQPicoDriveView::PutBitmap(CFbsBitmap* aBitmap,TPoint aPoint,TRect aRect)
\r
2339 iDsa->Gc()->BitBlt(aPoint,aBitmap,aRect);
\r
2340 iDsa->ScreenDevice()->Update();
\r
2342 //iEikonEnv->WsSession().Flush();
\r
2347 CWindowGc& gc=SystemGc();
\r
2348 gc.BitBlt(aPoint,aBitmap,aRect);
\r
2358 CTrapCleanup* cleanup = CTrapCleanup::New();
\r
2360 // Create a eikenv
\r
2361 CEikonEnv* eikenv = new CEikonEnv;
\r
2364 return /*KErrNoMemory*/;
\r
2366 TRAPD(eikErr, eikenv->ConstructL());
\r
2367 if (eikErr != KErrNone)
\r
2370 return /*eikErr*/;
\r
2372 CPicoDriveUi* appUi = new (ELeave) CPicoDriveUi;
\r
2376 return /*KErrNoMemory*/;
\r
2379 TRAPD(constructErr,appUi->ConstructL());
\r
2381 eikenv->SetAppUi(appUi); // passing ownership of appUi to coe
\r
2383 TInt leaveValue = KErrNone;
\r
2384 if (leaveValue != KErrNone)
\r
2390 // now accept request from clients (start the scheduler)
\r
2391 eikenv->ExecuteD();
\r
2392 //delete eikenv; // ExecuteD kills eikenv
\r
2403 CPicoDriveApp::CPicoDriveApp()
\r
2407 CPicoDriveApp::~CPicoDriveApp()
\r
2411 CApaDocument* CPicoDriveApp::CreateDocumentL()
\r
2413 return new (ELeave) CPicoDriveDoc(*this);
\r
2417 TUid CPicoDriveApp::AppDllUid()const
\r
2419 return TUid::Uid(0xA00007BE);
\r
2423 * From @c CApaApplication. Opens the .ini file associated with the
\r
2424 * application. By default, ini files are not supported by SERIES60
\r
2425 * applications. If you want to use an ini file, either override this
\r
2426 * function to base call @c CEikApplication::OpenIniFileLC, or call it
\r
2428 * @param aFs File server session to use. Not used.
\r
2429 * @return Pointer to the dictionary store object representing the
\r
2430 * application's .ini file.
\r
2432 CDictionaryStore* CPicoDriveApp::OpenIniFileLC(RFs& aFs) const
\r
2434 return CEikApplication::OpenIniFileLC(aFs);
\r
2437 CPicoDriveDoc::CPicoDriveDoc(CEikApplication& aApp):CAknDocument(aApp)
\r
2441 CPicoDriveDoc::~CPicoDriveDoc()
\r
2445 CEikAppUi* CPicoDriveDoc::CreateAppUiL()
\r
2447 return new (ELeave) CPicoDriveUi;
\r
2453 CApaApplication* NewApplication() {
\r
2454 // Return pointer to newly created Application
\r
2455 return new CPicoDriveApp;
\r
2457 #include <eikstart.h>
\r
2459 GLDEF_C TInt E32Main()
\r
2462 return EikStart::RunApplication(NewApplication);
\r
2468 #if defined(__WINS__)
\r
2471 EXPORT_C TInt WinsMain()
\r
2478 extern "C" void my_free(void* anAddress)
\r
2480 if(gChunk != NULL)
\r
2482 gChunk->Free(anAddress);
\r
2486 extern "C" void* my_malloc(int aSize)
\r
2488 if(gChunk != NULL)
\r
2490 return gChunk->Alloc(aSize);
\r