#include #include #include #include "NLS.h" #include "System.h" #include "Util.h" #include "common/Port.h" #include "common/ConfigManager.h" #include "gba/Flash.h" #include "gba/GBA.h" #include "gba/Globals.h" #include "gba/RTC.h" #include "gb/gbGlobals.h" #include "gba/gbafilter.h" #ifndef _MSC_VER #include #define _stricmp strcasecmp #endif // ! _MSC_VER // Because Configmanager was introduced, this has to be done. int rtcEnabled = 0; int cpuDisableSfx = 0; int skipBios = 0; int saveType = 0; int cpuSaveType = 0; int skipSaveGameBattery = 0; int skipSaveGameCheats = 0; int useBios = 0; int cheatsEnabled = 0; int layerSettings = 0xff00; int layerEnable = 0xff00; bool speedup = false; bool parseDebug = false; bool speedHack = false; bool mirroringEnable = false; bool cpuIsMultiBoot = false; const char* loadDotCodeFile; const char* saveDotCodeFile; extern int systemColorDepth; extern int systemRedShift; extern int systemGreenShift; extern int systemBlueShift; extern uint16_t systemColorMap16[0x10000]; extern uint32_t systemColorMap32[0x10000]; const char gb_image_header[] = { static_cast ( 0xce, 0xed, 0x66, 0x66, 0xcc, 0x0d, 0x00, 0x0b, 0x03, 0x73, 0x00, 0x83, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x08, 0x11, 0x1f, 0x88, 0x89, 0x00, 0x0e, 0xdc, 0xcc, 0x6e, 0xe6, 0xdd, 0xdd, 0xd9, 0x99, 0xbb, 0xbb, 0x67, 0x63, 0x6e, 0x0e, 0xec, 0xcc, 0xdd, 0xdc, 0x99, 0x9f, 0xbb, 0xb9, 0x33, 0x3e ) }; bool utilWritePNGFile(const char* fileName, int w, int h, uint8_t* pix) { return false; } void utilPutDword(uint8_t* p, uint32_t value) { *p++ = value & 255; *p++ = (value >> 8) & 255; *p++ = (value >> 16) & 255; *p = (value >> 24) & 255; } void utilPutWord(uint8_t* p, uint16_t value) { *p++ = value & 255; *p = (value >> 8) & 255; } bool utilWriteBMPFile(const char* fileName, int w, int h, uint8_t* pix) { return false; } extern bool cpuIsMultiBoot; bool utilIsGBAImage(const char* file) { cpuIsMultiBoot = false; if (strlen(file) > 4) { const char* p = strrchr(file, '.'); if (p != NULL) { if ((_stricmp(p, ".agb") == 0) || (_stricmp(p, ".gba") == 0) || (_stricmp(p, ".bin") == 0) || (_stricmp(p, ".elf") == 0)) return true; if (_stricmp(p, ".mb") == 0) { cpuIsMultiBoot = true; return true; } } } return false; } bool utilIsGBImage(const char* file) { FILE *fp; bool ret = false; char buffer[47]; if (!file || !(fp = fopen (file, "r"))) //TODO more checks here (does file exist, is it a file, a symlink or a blockdevice) return ret; fseek (fp, 0, SEEK_END); if (ftell (fp) >= 0x8000) { //afaik there can be no gb-rom smaller than this fseek (fp, 0x104, SEEK_SET); fread (buffer, sizeof (char), 47, fp); ret = !memcmp (buffer, gb_image_header, 47); } fclose (fp); return ret; } // strip .gz or .z off end void utilStripDoubleExtension(const char* file, char* buffer) { if (buffer != file) // allows conversion in place strcpy(buffer, file); } static bool utilIsImage(const char* file) { return utilIsGBAImage(file) || utilIsGBImage(file); } IMAGE_TYPE utilFindType(const char* file) { //char buffer[2048]; if (!utilIsImage(file)) // TODO: utilIsArchive() instead? { return IMAGE_UNKNOWN; } return utilIsGBAImage(file) ? IMAGE_GBA : IMAGE_GB; } static int utilGetSize(int size) { int res = 1; while(res < size) res <<= 1; return res; } uint8_t *utilLoad(const char *file, bool (*accept)(const char *), uint8_t *data, int &size) { FILE *fp = NULL; //char *buf = NULL; fp = fopen(file,"rb"); if(!fp) return NULL; fseek(fp, 0, SEEK_END); //go to end size = ftell(fp); // get position at end (length) rewind(fp); uint8_t *image = data; if(image == NULL) { //allocate buffer memory if none was passed to the function image = (uint8_t *)malloc(utilGetSize(size)); if(image == NULL) { systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), "data"); return NULL; } } fread(image, 1, size, fp); // read into buffer fclose(fp); return image; } void utilGBAFindSave(const uint8_t *data, const int size) { uint32_t *p = (uint32_t *)data; uint32_t *end = (uint32_t *)(data + size); int saveType = 0; int flashSize = 0x10000; bool rtcFound = false; while(p < end) { uint32_t d = READ32LE(p); if(d == 0x52504545) { if(memcmp(p, "EEPROM_", 7) == 0) { if(saveType == 0) saveType = 3; } } else if (d == 0x4D415253) { if(memcmp(p, "SRAM_", 5) == 0) { if(saveType == 0) saveType = 1; } } else if (d == 0x53414C46) { if(memcmp(p, "FLASH1M_", 8) == 0) { if(saveType == 0) { saveType = 2; flashSize = 0x20000; } } else if(memcmp(p, "FLASH", 5) == 0) { if(saveType == 0) { saveType = 2; flashSize = 0x10000; } } } else if (d == 0x52494953) { if(memcmp(p, "SIIRTC_V", 8) == 0) rtcFound = true; } p++; } // if no matches found, then set it to NONE if(saveType == 0) { saveType = 5; } rtcEnable(rtcFound); cpuSaveType = saveType; flashSetSize(flashSize); } void utilUpdateSystemColorMaps(bool lcd) { switch (systemColorDepth) { case 16: { for (int i = 0; i < 0x10000; i++) { systemColorMap16[i] = ((i & 0x1f) << systemRedShift) | (((i & 0x3e0) >> 5) << systemGreenShift) | (((i & 0x7c00) >> 10) << systemBlueShift); } if (lcd) gbafilter_pal(systemColorMap16, 0x10000); } break; case 24: case 32: { for (int i = 0; i < 0x10000; i++) { systemColorMap32[i] = ((i & 0x1f) << systemRedShift) | (((i & 0x3e0) >> 5) << systemGreenShift) | (((i & 0x7c00) >> 10) << systemBlueShift); } if (lcd) gbafilter_pal32(systemColorMap32, 0x10000); } break; } } // Check for existence of file. bool utilFileExists(const char* filename) { FILE* f = fopen(filename, "r"); if (f == NULL) { return false; } else { fclose(f); return true; } } // Not endian safe, but VBA itself doesn't seem to care, so hey <_< void utilWriteIntMem(uint8_t*& data, int val) { memcpy(data, &val, sizeof(int)); data += sizeof(int); } void utilWriteMem(uint8_t*& data, const void* in_data, unsigned size) { memcpy(data, in_data, size); data += size; } void utilWriteDataMem(uint8_t*& data, variable_desc* desc) { while (desc->address) { utilWriteMem(data, desc->address, desc->size); desc++; } } int utilReadIntMem(const uint8_t*& data) { int res; memcpy(&res, data, sizeof(int)); data += sizeof(int); return res; } void utilReadMem(void* buf, const uint8_t*& data, unsigned size) { memcpy(buf, data, size); data += size; } void utilReadDataMem(const uint8_t*& data, variable_desc* desc) { while (desc->address) { utilReadMem(desc->address, data, desc->size); desc++; } }