diff --git a/CMakeLists.txt b/CMakeLists.txt index 6051cf9e..1d855eef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -217,6 +217,7 @@ SET(SRC_GBA src/gba/Cheats.cpp src/gba/CheatSearch.cpp src/gba/EEprom.cpp + src/gba/ereader.cpp src/gba/Flash.cpp src/gba/GBA.cpp src/gba/GBAGfx.cpp diff --git a/project/vc2008_mfc/VBA2008.vcproj b/project/vc2008_mfc/VBA2008.vcproj index 7dcbc0ee..ee0e758e 100644 --- a/project/vc2008_mfc/VBA2008.vcproj +++ b/project/vc2008_mfc/VBA2008.vcproj @@ -430,6 +430,14 @@ RelativePath="..\..\src\gba\agbprint.h" > + + + + diff --git a/project/vs2010_mfc/VBA2010.sln b/project/vs2010_mfc/VBA2010.sln index e5211571..59df2772 100644 --- a/project/vs2010_mfc/VBA2010.sln +++ b/project/vs2010_mfc/VBA2010.sln @@ -6,7 +6,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VisualBoyAdvance-M", "VBA20 EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\..\dependencies\zlib\project\vs2010\zlib.vcxproj", "{3E03C179-8251-46E4-81F4-466F114BAC63}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SFML_Network", "..\..\..\dependencies\SFML\build\vc2010\sfml-network.vcxproj", "{823DDC98-42D5-4A38-88CF-9DC06C788AE4}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SFML", "..\..\..\dependencies\SFML\build\vc2010\sfml-network.vcxproj", "{823DDC98-42D5-4A38-88CF-9DC06C788AE4}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "..\..\..\dependencies\libpng\project\vs2010\libpng.vcxproj", "{0008960E-E0DD-41A6-8265-00B31DDB4C21}" EndProject diff --git a/project/vs2010_mfc/VBA2010.vcxproj b/project/vs2010_mfc/VBA2010.vcxproj index 6ed18df8..ef232c28 100644 --- a/project/vs2010_mfc/VBA2010.vcxproj +++ b/project/vs2010_mfc/VBA2010.vcxproj @@ -110,7 +110,7 @@ AnySuitable Speed ..\..\src;..\..\fex;..\..\..\dependencies\libpng;..\..\..\dependencies\msvc;..\..\..\dependencies\SFML\include;..\..\..\dependencies\SubWCRev;..\..\..\dependencies\zlib;%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;NDEBUG;GBA_LOGGING;OEMRESOURCE;MMX;ASM;FINAL_VERSION;BKPT_SUPPORT;_CRT_SECURE_NO_DEPRECATE;HAS_FILE_EXTRACTOR;%(PreprocessorDefinitions) + WIN32;_WINDOWS;NO_OAL;NDEBUG;GBA_LOGGING;OEMRESOURCE;MMX;ASM;FINAL_VERSION;BKPT_SUPPORT;_CRT_SECURE_NO_DEPRECATE;HAS_FILE_EXTRACTOR;%(PreprocessorDefinitions) MultiThreaded StreamingSIMDExtensions Fast @@ -166,6 +166,7 @@ + @@ -295,6 +296,7 @@ + diff --git a/project/vs2010_mfc/VBA2010.vcxproj.filters b/project/vs2010_mfc/VBA2010.vcxproj.filters index 689f593f..0af12e8f 100644 --- a/project/vs2010_mfc/VBA2010.vcxproj.filters +++ b/project/vs2010_mfc/VBA2010.vcxproj.filters @@ -106,6 +106,9 @@ Core\GBA + + Core\GBA + Core\GBA @@ -481,6 +484,9 @@ Core\GBA + + Core\GBA + Core\GBA diff --git a/project/vs2013_mfc/VBA2013.vcxproj b/project/vs2013_mfc/VBA2013.vcxproj index 70d3d60d..fa2ffe80 100644 --- a/project/vs2013_mfc/VBA2013.vcxproj +++ b/project/vs2013_mfc/VBA2013.vcxproj @@ -176,6 +176,7 @@ + @@ -303,6 +304,7 @@ + diff --git a/project/vs2013_mfc/VBA2013.vcxproj.filters b/project/vs2013_mfc/VBA2013.vcxproj.filters index 70ddff39..d4a40f95 100644 --- a/project/vs2013_mfc/VBA2013.vcxproj.filters +++ b/project/vs2013_mfc/VBA2013.vcxproj.filters @@ -118,6 +118,9 @@ Core\GBA + + Core\GBA + Core\GBA @@ -487,6 +490,9 @@ Core\GBA + + Core\GBA + Core\GBA diff --git a/src/gba/GBA.cpp b/src/gba/GBA.cpp index 2cb4f075..71494e34 100644 --- a/src/gba/GBA.cpp +++ b/src/gba/GBA.cpp @@ -20,6 +20,7 @@ #include "../common/Port.h" #include "../System.h" #include "agbprint.h" +#include "ereader.h" #include "GBALink.h" #ifdef PROFILING @@ -161,6 +162,9 @@ u8 memoryWaitSeq32[16] = u8 biosProtected[4]; +const char *loadDotCodeFile; +const char *saveDotCodeFile; + #ifdef WORDS_BIGENDIAN bool cpuBiosSwapped = false; #endif @@ -1618,6 +1622,26 @@ void doMirroring (bool b) } } +const char* GetLoadDotCodeFile() +{ + return loadDotCodeFile; +} + +const char* GetSaveDotCodeFile() +{ + return saveDotCodeFile; +} + +void SetLoadDotCodeFile(const char *szFile) +{ + loadDotCodeFile = szFile; +} + +void SetSaveDotCodeFile(const char *szFile) +{ + saveDotCodeFile = szFile; +} + void CPUUpdateRender() { switch(DISPCNT & 7) { @@ -1933,8 +1957,19 @@ void CPUSoftwareInterrupt(int comment) VCOUNT); } #endif - CPUSoftwareInterrupt(); - return; + if ((comment & 0xF8) != 0xE0) + { + CPUSoftwareInterrupt(); + return; + } + else + { + if (CheckEReaderRegion()) + BIOS_EReader_ScanCard(comment); + else + CPUSoftwareInterrupt(); + return; + } } // This would be correct, but it causes problems if uncommented // else { @@ -2162,6 +2197,17 @@ void CPUSoftwareInterrupt(int comment) case 0x1F: BIOS_MidiKey2Freq(); break; + case 0xE0: + case 0xE1: + case 0xE2: + case 0xE3: + case 0xE4: + case 0xE5: + case 0xE6: + case 0xE7: + if (CheckEReaderRegion()) + BIOS_EReader_ScanCard(comment); + break; case 0x2A: BIOS_SndDriverJmpTableCopy(); // let it go, because we don't really emulate this function @@ -3272,6 +3318,18 @@ void CPUReset() break; } } + switch (CheckEReaderRegion()) + { + case 1: //US + EReaderWriteMemory(0x8009134, 0x46C0DFE0); + break; + case 2: + EReaderWriteMemory(0x8008A8C, 0x46C0DFE0); + break; + case 3: + EReaderWriteMemory(0x80091A8, 0x46C0DFE0); + break; + } rtcReset(); // clean registers memset(®[0], 0, sizeof(reg)); diff --git a/src/gba/GBA.h b/src/gba/GBA.h index 7da9df11..5feca67c 100644 --- a/src/gba/GBA.h +++ b/src/gba/GBA.h @@ -114,6 +114,11 @@ extern void cpuProfil(profile_segment *seg); extern void cpuEnableProfiling(int hz); #endif +const char* GetLoadDotCodeFile(); +const char* GetSaveDotCodeFile(); +void SetLoadDotCodeFile(const char *szFile); +void SetSaveDotCodeFile(const char *szFile); + extern struct EmulatedSystem GBASystem; #define R13_IRQ 18 diff --git a/src/gba/ereader.cpp b/src/gba/ereader.cpp new file mode 100644 index 00000000..64197a92 --- /dev/null +++ b/src/gba/ereader.cpp @@ -0,0 +1,670 @@ +#include +#include +#include +#include + +#include "GBA.h" +#include "GBAinline.h" +#include "Globals.h" +#include "ereader.h" + + +//#include "win32/stdafx.h" +//#include "win32/vba.h" +//#include "win32/MainWnd.h" +//#include "win32/FileDlg.h" +//#include "win32/WinResUtil.h" +//#include "win32/MainWnd.h" + + +int eReaderSaveRAW = 1; + +char US_Ereader[19] = "CARDE READERPSAE01"; +char JAP_Ereader[19] = "CARDE READERPEAJ01"; +char JAP_Ereader_plus[19] = "CARDEREADER+PSAJ01"; +char rom_info[19]; + +char Signature[0x29] = "E-Reader Dotcode -Created- by CaitSith2"; + + +unsigned char ShortDotCodeHeader[0x30] = { + 0x00, 0x30, 0x01, 0x01, + 0x00, 0x01, 0x05, 0x10, + 0x00, 0x00, 0x10, 0x12, //Constant data + + 0x00, 0x00, //Header First 2 bytes + + 0x02, 0x00, //Constant data + + 0x00, 0x00, //Header Second 2 bytes + + 0x10, 0x47, 0xEF, //Global Checksum 1 + + 0x19, 0x00, 0x00, 0x00, 0x08, 0x4E, 0x49, + 0x4E, 0x54, 0x45, 0x4E, 0x44, 0x4F, 0x00, 0x22, + 0x00, 0x09, //Constant data + + 0x00, 0x00, //Header, last 8 bytes + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + 0x00, //Header Checksum + 0x57 //Global Checksum 2 +}; + +unsigned char LongDotCodeHeader[0x30] = { + 0x00, 0x30, 0x01, 0x02, + 0x00, 0x01, 0x08, 0x10, + 0x00, 0x00, 0x10, 0x12, //Constant Data + + 0x00, 0x00, //Header, first 2 bytes + + 0x01, 0x00, //Constant data + + 0x00, 0x00, //Header, second 2 bytes + 0x10, 0x9A, 0x99, //Global Checksum 1 + + 0x19, 0x00, 0x00, 0x00, 0x08, 0x4E, 0x49, + 0x4E, 0x54, 0x45, 0x4E, 0x44, 0x4F, 0x00, 0x22, + 0x00, 0x09, //Constant data + + + 0x00, 0x00, //Header, last 8 bytes + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + 0x00, //Header Checksum + 0x57 //Global Checksum 2 +}; + +unsigned char shortheader[0x18] = { + 0x00, 0x02, 0x00, 0x01, 0x40, 0x10, 0x00, 0x1C, + 0x10, 0x6F, 0x40, 0xDA, 0x39, 0x25, 0x8E, 0xE0, + 0x7B, 0xB5, 0x98, 0xB6, 0x5B, 0xCF, 0x7F, 0x72 +}; +unsigned char longheader[0x18] = { + 0x00, 0x03, 0x00, 0x19, 0x40, 0x10, 0x00, 0x2C, + 0x0E, 0x88, 0xED, 0x82, 0x50, 0x67, 0xFB, 0xD1, + 0x43, 0xEE, 0x03, 0xC6, 0xC6, 0x2B, 0x2C, 0x93 +}; + +unsigned char dotcodeheader[0x48]; +unsigned char dotcodedata[0xB38]; +unsigned char dotcodetemp[0xB00]; +int dotcodepointer; +int dotcodeinterleave; +int decodestate; + +u32 GFpow; + +unsigned char *DotCodeData; +char filebuffer[2048]; + +int dotcodesize; + +int CheckEReaderRegion(void) //US = 1, JAP = 2, JAP+ = 3 +{ + int i; + for(i=0;i<18;i++) + rom_info[i] = rom[0xA0+i]; + rom_info[i] = 0; + + if (std::tolower(*rom_info, std::locale()) == std::tolower(*US_Ereader, std::locale())) + return 1; + if (std::tolower(*rom_info, std::locale()) == std::tolower(*JAP_Ereader, std::locale())) + return 2; + if (std::tolower(*rom_info, std::locale()) == std::tolower(*JAP_Ereader_plus, std::locale())) + return 3; + + return 0; +} + +int LoadDotCodeData(int size, u32* DCdata, unsigned long MEM1, unsigned long MEM2, int loadraw) +{ + u32 temp1; + int i,j; + + unsigned char scanmap[28]; + int scantotal=0; + + for(i=0;i<28;i++) + scanmap[i] = 0; + + unsigned char longdotcodescan[28] = { + 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, + 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, + 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, + 0xF1, 0xF2, 0xB1, 0xB1 + }; + unsigned char shortdotcodescan[18] = { + 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, + 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, + 0xF1, 0xF1, 0xF1, 0xF2, 0xB1, 0xB1 + }; + + temp1 = CPUReadMemory(MEM1-4); + for(i=0;i<0x60;i+=4) + CPUWriteMemory((MEM2-8)+i,0); + for(i=0;i<0x1860;i+=4) + CPUWriteMemory(temp1+i,0); + if(DCdata != NULL) + { + if(size==0xB60) + { + for(i=0;i<28;i++) + { + for(j=0,scantotal=0;j<0x68;j+=4) + { + scantotal += DCdata[((i*0x68)+j)>>2]; + } + if(scantotal) + scanmap[i] = longdotcodescan[i]; + } + for(i=0;i>2]); + } + } + else if (size==0x750) + { + for(i=0;i<18;i++) + { + if((DCdata[0] == 0x02011394) && (DCdata[1] == 0x0203E110) && (i == 0)) + continue; + for(j=0,scantotal=0;j<0x68;j+=4) + { + scantotal += DCdata[((i*0x68)+j)>>2]; + } + if(scantotal) + scanmap[i] = longdotcodescan[i]; + } + for(i=0;i>2]); + } + } + } + CPUWriteMemory(MEM2-8,0x1860); + CPUWriteMemory(MEM2-4,temp1); + + + if(size==0xB60) + { + if(loadraw) + { + for(i=0;i<28;i++) + CPUWriteByte(MEM2+0x18+i,scanmap[i]); + } + else + { + CPUWriteMemory(MEM2+0x18,0xF1F1F1F1); + CPUWriteMemory(MEM2+0x18+4,0xF1F1F1F1); + CPUWriteMemory(MEM2+0x18+8,0xF1F1F1F1); + CPUWriteMemory(MEM2+0x18+12,0xF1F1F1F1); + CPUWriteMemory(MEM2+0x18+16,0xF1F1F1F1); + CPUWriteMemory(MEM2+0x18+20,0xF1F1F1F1); + CPUWriteMemory(MEM2+0x18+24,0xB1B1F2F1); + } + CPUWriteMemory(MEM2+0x40,0x19); + CPUWriteMemory(MEM2+0x44,0x34); + } + else if (size==0x750) + { + if(loadraw) + { + for(i=0;i<18;i++) + CPUWriteByte(MEM2+i,scanmap[i]); + } + else + { + CPUWriteMemory(MEM2,0xF1F1F1F1); + CPUWriteMemory(MEM2+4,0xF1F1F1F1); + CPUWriteMemory(MEM2+8,0xF1F1F1F1); + CPUWriteMemory(MEM2+12,0xF2F1F1F1); + CPUWriteMemory(MEM2+16,0xB1B1); + } + CPUWriteMemory(MEM2+0x40,0x01); + CPUWriteMemory(MEM2+0x44,0x12); + } + CPUWriteMemory(MEM2+0x48,0x3C); + CPUWriteMemory(MEM2+0x4C,MEM2); + + return 0; +} + +void EReaderWriteMemory(u32 address, u32 value) +{ + switch(address >> 24) + { + case 2: + WRITE32LE(((u32 *)&workRAM[address & 0x3FFFF]), value); + break; + case 3: + WRITE32LE(((u32 *)&internalRAM[address & 0x7FFF]), value); + break; + default: + WRITE32LE(((u32 *)&rom[address & 0x1FFFFFF]), value); + //rom[address & 0x1FFFFFF] = data; + break; + } +} + + +void BIOS_EReader_ScanCard(int swi_num) +{ + + int i,j,k; + int dotcodetype; + + int global1, global2; + + FILE *f; + + //Open dotcode bin/raw + + if(swi_num == 0xE0) + { + dotcodepointer = 0; + dotcodeinterleave = 0; + decodestate = 0; + + const char* loadDotCodeFile = GetLoadDotCodeFile(); + + if (loadDotCodeFile == 0) + { + reg[0].I = 0x301; + return; + } + f=fopen(loadDotCodeFile,"rb"); + //f=fopen(filebuffer,"rb"); + //f=fopen("dotcode4.raw","rb"); + if(f==NULL) + { + reg[0].I = 0x303; + return; + } + fseek(f,0,SEEK_END); + i=ftell(f); + fseek(f,0,SEEK_SET); + if((i==0xB60) || (i==0x750)) + { + dotcodetype = 0; + } + else if ((i==0x81C) || (i==0x51C)) + { + dotcodetype = 1; + } + else + { + fclose(f); + reg[0].I = 0x303; + return; + } + DotCodeData = (unsigned char*)malloc(i); + if(DotCodeData == NULL) + { + reg[0].I = 0x303; + return; + } + fread(DotCodeData,1,i,f); + fclose(f); + + if(dotcodetype == 0) + { + + switch(CheckEReaderRegion()) + { + case 1: //US + LoadDotCodeData(i,(u32 *)DotCodeData,0x2032D14,0x2028B28,1); + EReaderWriteMemory(0x80091BA,0x46C0DFE2); + break; + case 2: + LoadDotCodeData(i,(u32 *)DotCodeData,0x2006EC4,0x2002478,1); + EReaderWriteMemory(0x8008B12,0x46C0DFE2); + break; + case 3: + LoadDotCodeData(i,(u32 *)DotCodeData,0x202F8A4,0x2031034,1); + EReaderWriteMemory(0x800922E,0x46C0DFE2); + break; + } + reg[0].I = 0; + free(DotCodeData); + } + else + { + //dotcodesize = i; + if(i==0x81C) + dotcodesize = 0xB60; + else + dotcodesize = 0x750; + + + switch(CheckEReaderRegion()) + { + case 1: //US + LoadDotCodeData(dotcodesize,(u32 *)NULL,0x2032D14,0x2028B28,0); + EReaderWriteMemory(0x80091BA,0x46C0DFE1); + break; + case 2: + LoadDotCodeData(dotcodesize,(u32 *)NULL,0x2006EC4,0x2002478,0); + EReaderWriteMemory(0x8008B12,0x46C0DFE1); + break; + case 3: + LoadDotCodeData(dotcodesize,(u32 *)NULL,0x202F8A4,0x2031034,0); + EReaderWriteMemory(0x800922E,0x46C0DFE1); + break; + } + reg[0].I = 0; + dotcodesize = i; + } + } + else if (swi_num == 0xE1) + { + + switch(CheckEReaderRegion()) + { + case 1: //US + EReaderWriteMemory(0x80091BA,0xF8A5F03B); + EReaderWriteMemory(0x3002F7C,0xEFE40000); //Beginning of Reed-Solomon decoder + EReaderWriteMemory(0x3003144,0xCA00002F); //Fix required to Correct 16 "Erasures" + EReaderWriteMemory(0x300338C,0xEFE50000); //End of Reed-Solomon decoder + GFpow = 0x3000A6C; + break; + case 2: + EReaderWriteMemory(0x8008B12,0xFB0BF035); + EReaderWriteMemory(0x3002F88,0xEFE40000); + EReaderWriteMemory(0x3003150,0xCA00002F); + EReaderWriteMemory(0x3003398,0xEFE50000); + GFpow = 0x3000A78; + break; + case 3: + EReaderWriteMemory(0x800922E,0xF94BF04B); + EReaderWriteMemory(0x3002F7C,0xEFE40000); + EReaderWriteMemory(0x3003144,0xCA00002F); + EReaderWriteMemory(0x300338C,0xEFE50000); + GFpow = 0x3000A6C; + break; + } + armNextPC -= 2; + reg[15].I -= 2; + + for(i=0,j=0;i<12;i++) + j ^= DotCodeData[i]; + if(dotcodesize == 0x81C) + { + LongDotCodeHeader[0x2E] = j; + LongDotCodeHeader[0x0D] = DotCodeData[0]; + LongDotCodeHeader[0x0C] = DotCodeData[1]; + LongDotCodeHeader[0x11] = DotCodeData[2]; + LongDotCodeHeader[0x10] = DotCodeData[3]; + + LongDotCodeHeader[0x26] = DotCodeData[4]; + LongDotCodeHeader[0x27] = DotCodeData[5]; + LongDotCodeHeader[0x28] = DotCodeData[6]; + LongDotCodeHeader[0x29] = DotCodeData[7]; + LongDotCodeHeader[0x2A] = DotCodeData[8]; + LongDotCodeHeader[0x2B] = DotCodeData[9]; + LongDotCodeHeader[0x2C] = DotCodeData[10]; + LongDotCodeHeader[0x2D] = DotCodeData[11]; + + + LongDotCodeHeader[0x12] = 0x10; //calculate Global Checksum 1 + LongDotCodeHeader[0x02] = 1; //Do not calculate Global Checksum 2 + + for(i=0x0C,j=0;i<0x81C;i++) + { + if(i&1) + j += DotCodeData[i]; + else + j += (DotCodeData[i] << 8); + } + j &= 0xFFFF; + j ^= 0xFFFF; + LongDotCodeHeader[0x13] = (j & 0xFF00) >> 8; + LongDotCodeHeader[0x14] = (j & 0x00FF); + + for(i=0,j=0;i<0x2F;i++) + j+=LongDotCodeHeader[i]; + j &= 0xFF; + for(i=1,global2=0;i<0x2C;i++) + { + for(k=0,global1=0;k<0x30;k++) + { + global1 ^= DotCodeData[((i-1)*0x30)+k+0x0C]; + } + global2 += global1; + } + global2 += j; + global2 &= 0xFF; + global2 ^= 0xFF; + LongDotCodeHeader[0x2F] = global2; + + + } + else + { + ShortDotCodeHeader[0x2E] = j; + ShortDotCodeHeader[0x0D] = DotCodeData[0]; + ShortDotCodeHeader[0x0C] = DotCodeData[1]; + ShortDotCodeHeader[0x11] = DotCodeData[2]; + ShortDotCodeHeader[0x10] = DotCodeData[3]; + + ShortDotCodeHeader[0x26] = DotCodeData[4]; + ShortDotCodeHeader[0x27] = DotCodeData[5]; + ShortDotCodeHeader[0x28] = DotCodeData[6]; + ShortDotCodeHeader[0x29] = DotCodeData[7]; + ShortDotCodeHeader[0x2A] = DotCodeData[8]; + ShortDotCodeHeader[0x2B] = DotCodeData[9]; + ShortDotCodeHeader[0x2C] = DotCodeData[10]; + ShortDotCodeHeader[0x2D] = DotCodeData[11]; + + ShortDotCodeHeader[0x12] = 0x10; //calculate Global Checksum 1 + ShortDotCodeHeader[0x02] = 1; //Do not calculate Global Checksum 2 + + for(i=0x0C,j=0;i<0x51C;i++) + { + if(i&1) + j += DotCodeData[i]; + else + j += (DotCodeData[i] << 8); + } + j &= 0xFFFF; + j ^= 0xFFFF; + ShortDotCodeHeader[0x13] = (j & 0xFF00) >> 8; + ShortDotCodeHeader[0x14] = (j & 0x00FF); + + for(i=0,j=0;i<0x2F;i++) + j+=ShortDotCodeHeader[i]; + j &= 0xFF; + for(i=1,global2=0;i<0x1C;i++) + { + for(k=0,global1=0;k<0x30;k++) + { + global1 ^= DotCodeData[((i-1)*0x30)+k+0x0C]; + } + global2 += global1; + } + global2 += j; + global2 &= 0xFF; + global2 ^= 0xFF; + ShortDotCodeHeader[0x2F] = global2; + } + + } + else if (swi_num == 0xE2) //Header + { + switch(CheckEReaderRegion()) + { + case 1: //US + EReaderWriteMemory(0x80091BA,0xF8A5F03B); + EReaderWriteMemory(0x300338C,0xEFE30000); + GFpow = 0x3000A6C; + break; + case 2: + EReaderWriteMemory(0x8008B12,0xFB0BF035); + EReaderWriteMemory(0x3003398,0xEFE30000); + GFpow = 0x3000A78; + break; + case 3: + EReaderWriteMemory(0x800922E,0xF94BF04B); + EReaderWriteMemory(0x300338C,0xEFE30000); + GFpow = 0x3000A6C; + break; + } + armNextPC -= 2; + reg[15].I -= 2; + } + else if ((swi_num == 0xE3) || (swi_num == 0xE5)) //Dotcode data + { + if((reg[0].I >= 0) && (reg[0].I <= 0x10)) + { + if(decodestate == 0) + { + for(i=0x17;i>=0;i--) + { + if((0x17 - i) < 8) + j=CPUReadByte(GFpow + CPUReadByte(GFpow+0x200+i)); + else + j=CPUReadByte(GFpow + CPUReadByte(GFpow+0x200+i)) ^ 0xFF; + + dotcodeheader[(0x17-i)] = j; + dotcodeheader[(0x17-i)+0x18] = j; + dotcodeheader[(0x17-i)+0x30] = j; + } + for(i=0;i<28;i++) + for(j=0;j<2;j++) + dotcodedata[(i*0x68)+j] = dotcodeheader[(i*2)+j]; + dotcodeinterleave = dotcodeheader[7]; + decodestate = 1; + } + else + { + for(i=0x3F;i>=0;i--) + { + if((0x3F - i) < 0x30) + j=CPUReadByte(GFpow + CPUReadByte(GFpow+0x200+i)); + else + j=CPUReadByte(GFpow + CPUReadByte(GFpow+0x200+i)) ^ 0xFF; + dotcodetemp[((0x3F-i)*dotcodeinterleave)+dotcodepointer] = j; + } + dotcodepointer++; + + if((dotcodepointer == dotcodeinterleave)) + { + switch(dotcodeinterleave) + { + case 0x1C: + j = 0x724; + k = 0x750 - j; + break; + case 0x2C: + j = 0xB38; + k = 0xB60 - j; + break; + } + dotcodepointer = 0; + for(i=2;iSetCheck(agbPrintIsEnabled()); } +void MainWnd::OnOptionsEmulatorEreader() +{ + eReaderSaveRAW = !eReaderSaveRAW; +} + +void MainWnd::OnUpdateOptionsEmulatorEreader(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(eReaderSaveRAW == 1); +} + void MainWnd::OnOptionsEmulatorRealtimeclock() { theApp.winRtcEnable = !theApp.winRtcEnable; diff --git a/src/win32/VBA.cpp b/src/win32/VBA.cpp index 69411a00..4a5e199d 100644 --- a/src/win32/VBA.cpp +++ b/src/win32/VBA.cpp @@ -25,6 +25,7 @@ #include "../System.h" #include "../gba/agbprint.h" +#include "../gba/ereader.h" #include "../gba/cheatSearch.h" #include "../gba/GBA.h" #include "../gba/Globals.h" @@ -1396,6 +1397,10 @@ void VBA::loadSettings() { CString buffer; + eReaderSaveRAW = regQueryDwordValue("eReaderSaveRAW", 1); + if (eReaderSaveRAW < 0 || eReaderSaveRAW > 1) + eReaderSaveRAW = 1; + lastFullscreen = (VIDEO_SIZE)regQueryDwordValue("lastFullscreen", VIDEO_1024x768); languageOption = regQueryDwordValue("language", 1); @@ -2492,6 +2497,8 @@ void VBA::movieReadNext() void VBA::saveSettings() { + regSetDwordValue("eReaderSaveRAW", eReaderSaveRAW); + regSetDwordValue("language", languageOption); regSetStringValue("languageName", languageName); diff --git a/src/win32/VBA.h b/src/win32/VBA.h index 86cc4166..086e22a4 100644 --- a/src/win32/VBA.h +++ b/src/win32/VBA.h @@ -202,6 +202,9 @@ class VBA : public CWinApp CString filename; CString dir; + CString loadDotCodeFile; + CString saveDotCodeFile; + CString wndClass; public: diff --git a/src/win32/VBA.rc b/src/win32/VBA.rc index 41a25e76..441cd8da 100644 --- a/src/win32/VBA.rc +++ b/src/win32/VBA.rc @@ -202,7 +202,7 @@ FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN ICON IDI_MAINICON,IDC_STATIC,6,6,20,20 CTEXT "VisualBoyAdvance-M Emulator",IDC_STATIC,36,6,138,8 - CTEXT "Copyright © 2008 VBA-M development team",IDC_STATIC,6,48,168,8 + CTEXT "Copyright � 2008 VBA-M development team",IDC_STATIC,6,48,168,8 CTEXT "http://vba-m.com",IDC_URL,7,138,168,8 RTEXT "Version:",IDC_STATIC,36,18,54,8 LTEXT "",IDC_VERSION,96,18,78,8,SS_NOPREFIX @@ -1626,7 +1626,7 @@ BEGIN VALUE "FileDescription", "VisualBoyAdvance-M" VALUE "FileVersion", "1, 8, 0, 0" VALUE "InternalName", "VBA-M" - VALUE "LegalCopyright", "Copyright © 2008-2009 VBA-M development team" + VALUE "LegalCopyright", "Copyright � 2008-2009 VBA-M development team" VALUE "OriginalFilename", "VisualBoyAdvance-M.exe" VALUE "ProductName", "GB/C/A emulator for Windows" VALUE "ProductVersion", "1, 8, 0, 0" @@ -1652,7 +1652,10 @@ BEGIN MENUITEM "Open GBC...", ID_FILE_OPEN_GBC MENUITEM "Open GB...", ID_FILE_OPEN_GB MENUITEM "Close", ID_FILE_CLOSE - MENUITEM SEPARATOR + MENUITEM SEPARATOR + MENUITEM "Load E-Reader DotCode...", ID_FILE_LOAD_DOTCODE + MENUITEM "Save E-Reader DotCode...", ID_FILE_SAVE_DOTCODE + MENUITEM SEPARATOR POPUP "Recent" BEGIN MENUITEM "&Reset", ID_FILE_RECENT_RESET @@ -1915,6 +1918,7 @@ BEGIN MENUITEM "Auto-apply IPS/UPS/PPF", ID_OPTIONS_EMULATOR_AUTOMATICALLYAPPLYPATCHFILES MENUITEM "Pause when inactive", ID_OPTIONS_EMULATOR_PAUSEWHENINACTIVE MENUITEM "AGB Print", ID_OPTIONS_EMULATOR_AGBPRINT + MENUITEM "E-Reader", ID_OPTIONS_EMULATOR_EREADER MENUITEM "Real Time Clock", ID_OPTIONS_EMULATOR_REALTIMECLOCK MENUITEM "&Game Overrides...", ID_OPTIONS_EMULATOR_GAMEOVERRIDES POPUP "Show speed" diff --git a/src/win32/resource.h b/src/win32/resource.h index 493aaba5..aaf88322 100644 --- a/src/win32/resource.h +++ b/src/win32/resource.h @@ -775,6 +775,7 @@ #define ID_OPTIONS_VIDEO_RENDEROPTIONS_GLTRIANGLE 40239 #define ID_OPTIONS_VIDEO_RENDEROPTIONS_GLQUADS 40240 #define ID_OPTIONS_EMULATOR_AGBPRINT 40247 +#define ID_OPTIONS_EMULATOR_EREADER 40280 #define ID_OPTIONS_EMULATOR_REALTIMECLOCK 40248 #define ID_OPTIONS_GAMEBOY_SGB2 40249 #define ID_SYSTEM_MINIMIZE 40250 @@ -877,6 +878,8 @@ #define ID_AUDIO_CORE_SETTINGS 40365 #define ID_FILE_OPEN_GBA 40366 #define ID_OPTIONS_VIDEO_LAYERS_RESET 40367 +#define ID_FILE_LOAD_DOTCODE 40368 +#define ID_FILE_SAVE_DOTCODE 40369 #define ID_LOADGAME_DONOTCHANGECHEATLIST 40371 #define ID_OPTIONS_EMULATOR_SAVETYPE_DETECTNOW 40372 #define ID_FILE_PAUSE 40373