From 7e1ec9f58362cb4680db93c248690500fa85d518 Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 1 Jun 2010 22:39:59 +0000 Subject: [PATCH] some cleanup of banner info handling, so bitbox 4k demo loads again --- desmume/ChangeLog | 6 +- desmume/src/MMU.cpp | 17 +++--- desmume/src/NDSSystem.cpp | 70 +++++++++++++++++++----- desmume/src/NDSSystem.h | 29 +++++++++- desmume/src/cheatSystem.cpp | 5 +- desmume/src/common.cpp | 7 ++- desmume/src/common.h | 2 +- desmume/src/windows/DeSmuME_2010.vcxproj | 7 +-- desmume/src/windows/ginfo.cpp | 67 ++++++++--------------- 9 files changed, 134 insertions(+), 76 deletions(-) diff --git a/desmume/ChangeLog b/desmume/ChangeLog index 38c9d139c..778b635b8 100644 --- a/desmume/ChangeLog +++ b/desmume/ChangeLog @@ -1,14 +1,16 @@ -0.9.6 -> 0.9.7 (r3493-r3xxx) +0.9.6 -> 0.9.7 (r3493-r3654-r3xxx) General/Core: bug: return Z1 and Z2 from TSC (fixes some touch logic) bug: fix a ton of old, broken cpu opcodes and CP15 logic + bug: gba slot save type detection improved enh: substantial improvements to wifi emulation enh: more realistic exception handling enh: piano controller emulation Graphics: bug: edge marking colors were wrong + bug: handle some "invalid" vram configurations correctly Windows: @@ -81,7 +83,7 @@ Windows: bug: dont crash when no sound device is available bug: change F10 to be save slot 0 bug: fix --start-paused - enh: try not to screensave while using gamepad + enh: try not to screensave while using gamepad enh: add EPX and EPX1.5X resize filters enh: add a japanese translation which will soon be stale like the others enh: add fancy ctrl+printscreen with emulator info on it diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 563c7cea5..3c64811ec 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -829,8 +829,6 @@ static inline void MMU_VRAMmapControl(u8 block, u8 VRAMBankCnt) void MMU_Init(void) { - int i; - LOG("MMU init\n"); memset(&MMU, 0, sizeof(MMU_struct)); @@ -838,13 +836,16 @@ void MMU_Init(void) { MMU.CART_ROM = MMU.UNUSED_RAM; MMU.CART_ROM_MASK = 3; - for(i = 0x80; i<0xA0; ++i) - { - MMU_struct::MMU_MEM[0][i] = MMU.CART_ROM; - MMU_struct::MMU_MEM[1][i] = MMU.CART_ROM; - } + //zero 01-jun-2010 - this makes no sense at all. delete me later + //for(i = 0x80; i<0xA0; ++i) + //{ + // MMU_struct::MMU_MEM[0][i] = MMU.CART_ROM; + // MMU_struct::MMU_MEM[1][i] = MMU.CART_ROM; + //} - MMU.DTCMRegion = 0x027C0000; + //MMU.DTCMRegion = 0x027C0000; + //even though apps may change dtcm immediately upon startup, this is the correct hardware starting value: + MMU.DTCMRegion = 0x08000000; MMU.ITCMRegion = 0x00000000; IPC_FIFOinit(ARMCPU_ARM9); diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 019c654fa..376522f6e 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -288,6 +288,40 @@ static u32 ones32(u32 x) } #endif +RomBanner::RomBanner(bool defaultInit) +{ + if(!defaultInit) return; + version = 1; //Version (0001h) + crc16 = 0; //CRC16 across entries 020h..83Fh + memset(reserved,0,sizeof(reserved)); + memset(bitmap,0,sizeof(bitmap)); + memset(palette,0,sizeof(palette)); + memset(titles,0,sizeof(titles)); + for(int i=0;i romsize) + return false; + else return true; +} + +const RomBanner& GameInfo::getRomBanner() +{ + //we may not have a valid banner. return a default one + if(!hasRomBanner()) + { + static RomBanner defaultBanner(true); + return defaultBanner; + } + + return *(RomBanner*)(romdata+header.IconOff); +} + void GameInfo::populate() { const char *regions[] = { "JPFSEDIRKH", @@ -310,16 +344,17 @@ void GameInfo::populate() memset(ROMserial, 0, sizeof(ROMserial)); memset(ROMname, 0, sizeof(ROMname)); - memset(ROMfullName, 0, sizeof(ROMfullName)); if ( - // ??? in all Homebrews game title have is 2E0000EA - //( + //Option 1. - look for this instruction in the game title + //(did this ever work?) //(header->gameTile[0] == 0x2E) && //(header->gameTile[1] == 0x00) && //(header->gameTile[2] == 0x00) && //(header->gameTile[3] == 0xEA) //) && + //option 2. - look for gamecode #### (default for ndstool) + //or an invalid gamecode ( ((header.gameCode[0] == 0x23) && (header.gameCode[1] == 0x23) && @@ -332,6 +367,7 @@ void GameInfo::populate() header.makerCode == 0x0 ) { + //we can't really make a serial for a homebrew game that hasnt set a game code strcpy(ROMserial, "Homebrew"); } else @@ -344,18 +380,24 @@ void GameInfo::populate() strcat(ROMserial, regions[region]); else strcat(ROMserial, "Unknown"); - memset(ROMname, 0, sizeof(ROMname)); - memcpy(ROMname, header.gameTile, 12); - trim(ROMname); - - u8 num = (T1ReadByte((u8*)romdata, header.IconOff) == 1)?6:7; - for (int i = 0; i < num; i++) - { - wcstombs(ROMfullName[i], (wchar_t *)(romdata+header.IconOff+0x240+(i*0x100)), 0x100); - trim(ROMfullName[i]); - } - } + + //rom name is probably set even in homebrew + memset(ROMname, 0, sizeof(ROMname)); + memcpy(ROMname, header.gameTile, 12); + trim(ROMname,20); + + /*if(header.IconOff < romsize) + { + u8 num = (T1ReadByte((u8*)romdata, header.IconOff) == 1)?6:7; + for (int i = 0; i < num; i++) + { + wcstombs(ROMfullName[i], (wchar_t *)(romdata+header.IconOff+0x240+(i*0x100)), 0x100); + trim(ROMfullName[i]); + } + }*/ + + } #ifdef _WINDOWS diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index ecd729a81..468644a6c 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -271,6 +271,31 @@ void NDS_DeInit(void); BOOL NDS_SetROM(u8 * rom, u32 mask); NDS_header * NDS_getROMHeader(void); +struct RomBanner +{ + RomBanner(bool defaultInit); + u16 version; //Version (0001h) + u16 crc16; //CRC16 across entries 020h..83Fh + u8 reserved[0x1C]; //Reserved (zero-filled) + u8 bitmap[0x200]; //Icon Bitmap (32x32 pix) (4x4 tiles, each 4x8 bytes, 4bit depth) + u16 palette[0x10]; //Icon Palette (16 colors, 16bit, range 0000h-7FFFh) (Color 0 is transparent, so the 1st palette entry is ignored) + enum { NUM_TITLES = 6 }; + union { + struct { + wchar_t title_jp[0x80]; //Title 0 Japanese (128 characters, 16bit Unicode) + wchar_t title_en[0x80]; //Title 1 English ("") + wchar_t title_fr[0x80]; //Title 2 French ("") + wchar_t title_de[0x80]; //Title 3 German ("") + wchar_t title_it[0x80]; //Title 4 Italian ("") + wchar_t title_es[0x80]; //Title 5 Spanish ("") + }; + wchar_t titles[NUM_TITLES][0x80]; + }; + u8 end0xFF[0x1C0]; + //840h ? (Maybe newer/chinese firmware do also support chinese title?) + //840h - End of Icon/Title structure (next 1C0h bytes usually FFh-filled) +}; + struct GameInfo { GameInfo() @@ -312,12 +337,14 @@ struct GameInfo NDS_header header; char ROMserial[20]; char ROMname[20]; - char ROMfullName[7][0x100]; + //char ROMfullName[7][0x100]; void populate(); char* romdata; u32 romsize; u32 allocatedSize; u32 mask; + const RomBanner& getRomBanner(); + bool hasRomBanner(); }; typedef struct TSCalInfo diff --git a/desmume/src/cheatSystem.cpp b/desmume/src/cheatSystem.cpp index 798b05b40..a17cbfa14 100644 --- a/desmume/src/cheatSystem.cpp +++ b/desmume/src/cheatSystem.cpp @@ -27,6 +27,7 @@ #include "mem.h" #include "MMU.h" #include "debug.h" +#include "utils/xstring.h" CHEATS *cheats = NULL; CHEATSEARCH *cheatSearch = NULL; @@ -543,7 +544,9 @@ BOOL CHEATS::save() if (flist) { fprintf(flist, "; DeSmuME cheats file. VERSION %i.%03i\n", CHEAT_VERSION_MAJOR, CHEAT_VERSION_MINOR); - strcpy(buf, gameInfo.ROMfullName[0]); + std::wstring wtemp = (std::wstring)gameInfo.getRomBanner().titles[1]; + std::string temp = wcstombs(wtemp); + strcpy(buf, temp.c_str()); trim(buf); removeSpecialChars(buf); fprintf(flist, "Name=%s\n", buf); diff --git a/desmume/src/common.cpp b/desmume/src/common.cpp index 4677c8fce..3399f0fe8 100644 --- a/desmume/src/common.cpp +++ b/desmume/src/common.cpp @@ -37,13 +37,16 @@ const u8 logo_data[156] = { 0x78,0x00,0x90,0xCB,0x88,0x11,0x3A,0x94,0x65,0xC0,0x7C,0x63,0x87,0xF0,0x3C,0xAF, 0xD6,0x25,0xE4,0x8B,0x38,0x0A,0xAC,0x72,0x21,0xD4,0xF8,0x07}; -char *trim(char *s) +char *trim(char *s, int len) { char *ptr = NULL; if (!s) return NULL; if (!*s) return s; - for (ptr = s + strlen(s) - 1; (ptr >= s) && isspace(*ptr); ptr--); + if(len==-1) + ptr = s + strlen(s) - 1; + else ptr = s+len - 1; + for (; (ptr >= s) && (!*ptr || isspace((u8)*ptr)) ; ptr--); ptr[1] = '\0'; return s; } diff --git a/desmume/src/common.h b/desmume/src/common.h index f1dd5e6d6..d7ee82619 100644 --- a/desmume/src/common.h +++ b/desmume/src/common.h @@ -83,7 +83,7 @@ char *intToBin(T val) return strdup(buf); } -extern char *trim(char *s); +extern char *trim(char *s, int len=-1); extern char *removeSpecialChars(char *s); #endif diff --git a/desmume/src/windows/DeSmuME_2010.vcxproj b/desmume/src/windows/DeSmuME_2010.vcxproj index 012f683f4..0c00752cd 100644 --- a/desmume/src/windows/DeSmuME_2010.vcxproj +++ b/desmume/src/windows/DeSmuME_2010.vcxproj @@ -580,10 +580,6 @@ - - - - @@ -624,6 +620,9 @@ + + + diff --git a/desmume/src/windows/ginfo.cpp b/desmume/src/windows/ginfo.cpp index 916b8e3e1..e4fa6c263 100644 --- a/desmume/src/windows/ginfo.cpp +++ b/desmume/src/windows/ginfo.cpp @@ -83,53 +83,34 @@ LRESULT GInfo_Paint(HWND hDlg, WPARAM wParam, LPARAM lParam) u32 icontitleOffset; wchar_t *utf16text; u32 val; - + + hdc = BeginPaint(hDlg, &ps); - icontitleOffset = T1ReadLong(MMU.CART_ROM, 0x68); + const RomBanner& banner = gameInfo.getRomBanner(); - if(icontitleOffset >= 0x8000) - { - utf16text = (wchar_t*)(MMU.CART_ROM + icontitleOffset + 0x240 + (0x100 * win_fw_config.language)); - sprintf(text, "%ws", utf16text); - SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLE), text); + sprintf(text, "%ws", banner.titles[win_fw_config.language]); + SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLE), text); - utf16text = (wchar_t*)(MMU.CART_ROM + icontitleOffset + 0x240); - sprintf(text, "%ws", utf16text); - SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLEJP), text); + sprintf(text, "%ws", banner.titles[0]); + SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLEJP), text); - utf16text = (wchar_t*)(MMU.CART_ROM + icontitleOffset + 0x340); - sprintf(text, "%ws", utf16text); - SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLEEN), text); + sprintf(text, "%ws", banner.titles[1]); + SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLEEN), text); - utf16text = (wchar_t*)(MMU.CART_ROM + icontitleOffset + 0x440); - sprintf(text, "%ws", utf16text); - SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLEFR), text); + sprintf(text, "%ws", banner.titles[2]); + SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLEFR), text); - utf16text = (wchar_t*)(MMU.CART_ROM + icontitleOffset + 0x540); - sprintf(text, "%ws", utf16text); - SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLEGE), text); + sprintf(text, "%ws", banner.titles[3]); + SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLEGE), text); - utf16text = (wchar_t*)(MMU.CART_ROM + icontitleOffset + 0x640); - sprintf(text, "%ws", utf16text); - SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLEIT), text); - - utf16text = (wchar_t*)(MMU.CART_ROM + icontitleOffset + 0x740); - sprintf(text, "%ws", utf16text); - SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLESP), text); - } - else - { - SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLE), "\nNo title\n"); - - SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLEJP), "None"); - SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLEEN), "None"); - SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLEFR), "None"); - SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLEGE), "None"); - SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLEIT), "None"); - SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLESP), "None"); - } + sprintf(text, "%ws", banner.titles[4]); + SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLEIT), text); + sprintf(text, "%ws", banner.titles[5]); + SetWindowText(GetDlgItem(hDlg, IDC_GI_TITLESP), text); + + //TODO - pull this from the header, not straight out of the rom (yuck!) memcpy(text, MMU.CART_ROM, 12); text[12] = '\0'; @@ -197,7 +178,7 @@ LRESULT GInfo_Paint(HWND hDlg, WPARAM wParam, LPARAM lParam) sprintf(text, "%i bytes", val); SetWindowText(GetDlgItem(hDlg, IDC_GI_FATSIZE), text); - + icontitleOffset = T1ReadLong(MMU.CART_ROM, 0x68); sprintf(text, "0x%08X", icontitleOffset); SetWindowText(GetDlgItem(hDlg, IDC_GI_ICONTITLEOFS), text); @@ -278,9 +259,9 @@ LRESULT GInfo_IconBoxPaint(HWND hCtl, WPARAM wParam, LPARAM lParam) bmph.bV4Width = 32; bmph.bV4Height = -32; - icontitleOffset = T1ReadLong(MMU.CART_ROM, 0x68); + const RomBanner& banner = gameInfo.getRomBanner(); - if(icontitleOffset >= 0x8000) + if(gameInfo.hasRomBanner()) { for(y = 0; y < 32; y++) { @@ -291,14 +272,14 @@ LRESULT GInfo_IconBoxPaint(HWND hCtl, WPARAM wParam, LPARAM lParam) int tiley = (y % 8); int mapoffset = ((tilenum * 64) + (tiley * 8) + tilex); - u8 val = T1ReadByte(MMU.CART_ROM, (icontitleOffset + 0x20 + (mapoffset>>1))); + u8 val = banner.bitmap[(mapoffset>>1)]; if(mapoffset & 1) val = ((val >> 4) & 0xF); else val = (val & 0xF); - icon[(y * 32) + x] = T1ReadWord(MMU.CART_ROM, (icontitleOffset + 0x220 + (val<<1))); + icon[(y * 32) + x] = banner.palette[val]; } }