From 6caeb38edc5793dcb6b0c3119ee347655d8526c9 Mon Sep 17 00:00:00 2001 From: zeromus Date: Mon, 9 Dec 2013 01:26:08 +0000 Subject: [PATCH] add --advanscene-import commandline option which reads and writes to .ddb. (and then exits) its not completely clear whether this would work on ports other than windows due to completely disorganized emulator initialization logic between different frontends, but it should be easy to resolve. --- desmume/src/NDSSystem.cpp | 29 +++++++++++-- desmume/src/NDSSystem.h | 3 ++ desmume/src/commandline.cpp | 5 ++- desmume/src/commandline.h | 3 +- desmume/src/utils/advanscene.cpp | 72 +++++++++++++++----------------- desmume/src/utils/advanscene.h | 10 +++-- desmume/src/windows/main.cpp | 3 +- 7 files changed, 74 insertions(+), 51 deletions(-) diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index c217e122f..28d04dd53 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -100,6 +100,20 @@ void Desmume_InitOnce() #endif } +void NDS_RunAdvansceneAutoImport() +{ + if(CommonSettings.run_advanscene_import != "") + { + std::string fname = CommonSettings.run_advanscene_import; + std::string fname_out = fname + ".ddb"; + EMUFILE_FILE outf(fname_out,"wb"); + u32 ret = advsc.convertDB(fname.c_str(),&outf); + if(ret == 0) + exit(0); + else exit(1); + } +} + #ifdef GDB_STUB int NDS_Init( struct armcpu_memory_iface *arm9_mem_if, struct armcpu_ctrl_iface **arm9_ctrl_iface, @@ -119,6 +133,17 @@ int NDS_Init( void) if (Screen_Init() != 0) return -1; + { + char buf[MAX_PATH]; + memset(buf, 0, MAX_PATH); + strcpy(buf, path.pathToModule); + strcat(buf, "desmume.ddb"); // DeSmuME database :) + advsc.setDatabase(buf); + + //why is this done here? shitty engineering. not intended. + NDS_RunAdvansceneAutoImport(); + } + gfx3d_init(); #ifdef GDB_STUB @@ -600,10 +625,6 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi } INFO("ROM developer: %s\n", ((gameInfo.header.makerCode == 0) && gameInfo.isHomebrew())?"Homebrew":getDeveloperNameByID(gameInfo.header.makerCode).c_str()); - memset(buf, 0, MAX_PATH); - strcpy(buf, path.pathToModule); - strcat(buf, "desmume.ddb"); // DeSmuME database :) - advsc.setDatabase(buf); buf[0] = gameInfo.header.gameCode[0]; buf[1] = gameInfo.header.gameCode[1]; buf[2] = gameInfo.header.gameCode[2]; diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index 6bcf13de6..7b45fe161 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -644,8 +644,11 @@ extern struct TCommonSettings { bool ShowInputDisplay, ShowGraphicalInputDisplay, FpsDisplay, FrameCounterDisplay, ShowLagFrameCounter, ShowMicrophone, ShowRTC; } hud; + std::string run_advanscene_import; + } CommonSettings; +void NDS_RunAdvansceneAutoImport(); extern std::string InputDisplayString; extern int LagFrameFlag; diff --git a/desmume/src/commandline.cpp b/desmume/src/commandline.cpp index dbd68b7ec..80166f5b3 100644 --- a/desmume/src/commandline.cpp +++ b/desmume/src/commandline.cpp @@ -58,6 +58,7 @@ CommandLine::CommandLine() , _jit_size(-1) #endif , _console_type(NULL) +, _advanscene_import(NULL) , depth_threshold(-1) , load_slot(-1) , arm9_gdb_port(0) @@ -109,6 +110,7 @@ void CommandLine::loadCommonOptions() { "slot1-fat-dir", 0, 0, G_OPTION_ARG_STRING, &_slot1_fat_dir, "Directory to scan for slot 1", "SLOT1_DIR"}, { "depth-threshold", 0, 0, G_OPTION_ARG_INT, &depth_threshold, "Depth comparison threshold (default 0)", "DEPTHTHRESHOLD"}, { "console-type", 0, 0, G_OPTION_ARG_STRING, &_console_type, "Select console type: {fat,lite,ique,debug,dsi}", "CONSOLETYPE" }, + { "advanscene-import", 0, 0, G_OPTION_ARG_STRING, &_advanscene_import, "Import advanscene, dump .ddb, and exit", "ADVANSCENE_IMPORT" }, #ifdef HAVE_JIT { "cpu-mode", 0, 0, G_OPTION_ARG_INT, &_cpu_mode, "ARM CPU emulation mode: 0 - interpreter, 1 - dynarec (default 1)", NULL}, { "jit-size", 0, 0, G_OPTION_ARG_INT, &_jit_size, "ARM JIT block size: 1..100 (1 - accuracy, 100 - faster) (default 100)", NULL}, @@ -147,6 +149,7 @@ bool CommandLine::parse(int argc,char **argv) return false; } + if(_advanscene_import) CommonSettings.run_advanscene_import = _advanscene_import; if(_slot1_fat_dir) slot1_fat_dir = _slot1_fat_dir; if(_slot1) slot1 = _slot1; slot1 = strtoupper(slot1); if(_console_type) console_type = _console_type; @@ -210,8 +213,6 @@ bool CommandLine::parse(int argc,char **argv) bool CommandLine::validate() { - - if(slot1 != "") { if(slot1 != "R4" && slot1 != "RETAIL" && slot1 != "NONE" && slot1 != "RETAILNAND") { diff --git a/desmume/src/commandline.h b/desmume/src/commandline.h index 407cd4dac..e7b18d364 100644 --- a/desmume/src/commandline.h +++ b/desmume/src/commandline.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2009-2011 DeSmuME team + Copyright (C) 2009-2013 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -101,6 +101,7 @@ private: char* _slot1; char *_slot1_fat_dir; char* _console_type; + char* _advanscene_import; }; #endif diff --git a/desmume/src/utils/advanscene.cpp b/desmume/src/utils/advanscene.cpp index af2233523..87d76336d 100644 --- a/desmume/src/utils/advanscene.cpp +++ b/desmume/src/utils/advanscene.cpp @@ -85,9 +85,16 @@ u8 ADVANsCEne::checkDB(const char *ROMserial, u32 crc) return false; } + +void ADVANsCEne::setDatabase(const char *path) +{ + database_path = path; + + //i guess this means it needs (re)loading on account of the path having changed + loaded = false; +} - -bool ADVANsCEne::getXMLConfig(const char *in_filaname) +bool ADVANsCEne::getXMLConfig(const char *in_filename) { TiXmlDocument *xml = NULL; TiXmlElement *el = NULL; @@ -96,7 +103,7 @@ bool ADVANsCEne::getXMLConfig(const char *in_filaname) xml = new TiXmlDocument(); if (!xml) return false; - if (!xml->LoadFile(in_filaname)) return false; + if (!xml->LoadFile(in_filename)) return false; el = xml->FirstChildElement("dat"); if (!el) return false; el_configuration = el->FirstChildElement("configuration"); @@ -113,7 +120,7 @@ bool ADVANsCEne::getXMLConfig(const char *in_filaname) return true; } -u32 ADVANsCEne::convertDB(const char *in_filaname) +u32 ADVANsCEne::convertDB(const char *in_filename, EMUFILE* output) { //these strings are contained in the xml file, verbatim, so they function as enum values //we leave the strings here rather than pooled elsewhere to remind us that theyre part of the advanscene format. @@ -139,42 +146,38 @@ u32 ADVANsCEne::convertDB(const char *in_filaname) TiXmlElement *el_games = NULL; TiXmlElement *el_crc32 = NULL; TiXmlElement *el_saveType = NULL; - FILE *fp; u32 crc32 = 0; u32 reserved = 0; lastImportErrorMessage = ""; printf("Converting DB...\n"); - if (getXMLConfig(in_filaname)) + if (getXMLConfig(in_filename)) { if (datName.size()==0) return 0; if (datName != _ADVANsCEne_BASE_NAME) return 0; } - fp = fopen(database_path.c_str(), "wb"); - if (!fp) return 0; - // Header - fwrite(_ADVANsCEne_BASE_ID, 1, strlen(_ADVANsCEne_BASE_ID), fp); - fputc(_ADVANsCEne_BASE_VERSION_MAJOR, fp); - fputc(_ADVANsCEne_BASE_VERSION_MINOR, fp); + output->fwrite(_ADVANsCEne_BASE_ID, strlen(_ADVANsCEne_BASE_ID)); + output->fputc(_ADVANsCEne_BASE_VERSION_MAJOR); + output->fputc(_ADVANsCEne_BASE_VERSION_MINOR); if (datVersion.size()) - fwrite(&datVersion[0], 1, datVersion.size(), fp); + output->fwrite(&datVersion[0], datVersion.size()); else - fputc(0, fp); + output->fputc(0); time_t __time = time(NULL); - fwrite(&__time, 1, sizeof(time_t), fp); + output->fwrite(&__time, sizeof(time_t)); xml = new TiXmlDocument(); - if (!xml) { fclose(fp); return 0; } - if (!xml->LoadFile(in_filaname)) { fclose(fp); return 0; } + if (!xml) return 0; + if (!xml->LoadFile(in_filename)) return 0; el = xml->FirstChildElement("dat"); - if (!el) { fclose(fp); return 0; } + if (!el) return 0; el_games = el->FirstChildElement("games"); - if (!el_games) { fclose(fp); return 0; } + if (!el_games) return 0; el = el_games->FirstChildElement("game"); - if (!el) { fclose(fp); return 0; } + if (!el) return 0; u32 count = 0; while (el) { @@ -184,30 +187,22 @@ u32 ADVANsCEne::convertDB(const char *in_filaname) //just a little diagnostic //printf("Importing %s\n",title->GetText()); } - else { fclose(fp); return 0; } + else return 0; el_serial = el->FirstChildElement("serial"); if(!el_serial) { lastImportErrorMessage = "Missing element. Did you use the right xml file? We need the RtoolDS one."; - fclose(fp); return 0; } - if (fwrite(el_serial->GetText(), 1, 8, fp) != 8) - { - lastImportErrorMessage = "Error writing output file"; - fclose(fp); return 0; - } - + output->fwrite(el_serial->GetText(), 8); // CRC32 el_crc32 = el->FirstChildElement("files"); sscanf_s(el_crc32->FirstChildElement("romCRC")->GetText(), "%x", &crc32); - if (fwrite(&crc32, 1, sizeof(u32), fp) != sizeof(u32)) - { - fclose(fp); return 0; - } + output->fwrite(&crc32, sizeof(u32)); + // Save type el_saveType = el->FirstChildElement("saveType"); if (el_saveType) @@ -216,7 +211,7 @@ u32 ADVANsCEne::convertDB(const char *in_filaname) if (tmp) { if (strcmp(tmp, "None") == 0) - fputc(0xFE, fp); + output->fputc(0xFE); else { bool bUnknown = true; @@ -225,26 +220,25 @@ u32 ADVANsCEne::convertDB(const char *in_filaname) if (strcmp(saveTypeNames[i], "") == 0) continue; if (strcasecmp(tmp, saveTypeNames[i]) == 0) { - fputc(i, fp); + output->fputc(i); bUnknown = false; break; } } if (bUnknown) - fputc(0xFF, fp); // Unknown + output->fputc(0xFF); // Unknown } } else - fputc(0xFF, fp); // Unknown + output->fputc(0xFF); // Unknown } - fwrite(&reserved, 1, sizeof(u32), fp); - fwrite(&reserved, 1, sizeof(u32), fp); + output->fwrite(&reserved, sizeof(u32)); + output->fwrite(&reserved, sizeof(u32)); count++; el = el->NextSiblingElement("game"); } printf("\n"); delete xml; - fclose(fp); if (count > 0) printf("done\n"); else diff --git a/desmume/src/utils/advanscene.h b/desmume/src/utils/advanscene.h index 625c8da87..5c39b5af8 100644 --- a/desmume/src/utils/advanscene.h +++ b/desmume/src/utils/advanscene.h @@ -17,11 +17,12 @@ #include #include "types.h" +#include "EMUFILE.h" class ADVANsCEne { private: - std::string database_path; // DeSmuME save types + std::string database_path; time_t createTime; u32 crc32; char serial[6]; @@ -37,7 +38,7 @@ private: std::string datVersion; std::string urlVersion; std::string urlDat; - bool getXMLConfig(const char *in_filaname); + bool getXMLConfig(const char *in_filename); public: ADVANsCEne() @@ -49,8 +50,9 @@ public: memset(version, 0, sizeof(version)); memset(serial, 0, sizeof(serial)); } - void setDatabase(const char *path) { loaded = false; database_path = path; } - u32 convertDB(const char *in_filaname); + void setDatabase(const char *path); + std::string getDatabase() const { return database_path; } + u32 convertDB(const char *in_filename, EMUFILE* output); u8 checkDB(const char *ROMserial, u32 crc); u32 getSaveType() { return saveType; } u32 getCRC32() { return crc32; } diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index fa619b8bb..c70315de5 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -5499,7 +5499,8 @@ DOKEYDOWN: return 0; } - u32 count = advsc.convertDB(ImportSavName); + EMUFILE_FILE outf(advsc.getDatabase(),"wb"); + u32 count = advsc.convertDB(ImportSavName,&outf); if (count > 0) { sprintf(buffer, "ADVANsCEne database was successfully imported\n(%i records)", count);