int read32le(u32 *Bufo, EMUFILE *fp) { u32 buf = 0; if(fp->_fread(&buf,4)<4) return 0; *Bufo = LE_TO_LOCAL_32(buf); return 1; }
static int read32le(u32 *Bufo, std::istream *is) { u32 buf; if(is->read((char*)&buf,4).gcount() != 4) return 0; *Bufo = LE_TO_LOCAL_32(buf); return 1; }
size_t EMUFILE::read32le(u32* Bufo) { u32 buf; if(fread(&buf,4)<4) return 0; *Bufo = LE_TO_LOCAL_32(buf); return 1; }
// ============================================= ADVANsCEne u8 ADVANsCEne::checkDB(const char *serial, u32 crc) { loaded = false; FILE *fp = fopen(database_path, "rb"); if (fp) { char buf[64]; memset(buf, 0, sizeof(buf)); if (fread(buf, 1, strlen(_ADVANsCEne_BASE_ID), fp) == strlen(_ADVANsCEne_BASE_ID)) { //printf("ID: %s\n", buf); if (strcmp(buf, _ADVANsCEne_BASE_ID) == 0) { if (fread(&versionBase[0], 1, 2, fp) == 2) { //printf("Version base: %i.%i\n", versionBase[0], versionBase[1]); if (fread(&version[0], 1, 4, fp) == 4) { //printf("Version: %c%c%c%c\n", version[3], version[2], version[1], version[0]); if (fread(&createTime, 1, sizeof(time_t), fp) == sizeof(time_t)) { memset(buf, 0,sizeof(buf)); // serial(8) + crc32(4) + save_type(1) = 13 + reserved(8) = 21 while (true) { if (fread(buf, 1, 21, fp) != 21) break; bool serialFound = (memcmp(&buf[4], serial, 4) == 0); u32 dbcrc = LE_TO_LOCAL_32(*(u32*)(buf+8)); bool crcFound = (crc == dbcrc); if(serialFound || crcFound) { foundAsCrc = crcFound; foundAsSerial = serialFound; memcpy(&crc32, &buf[8], 4); //printf("%s founded: crc32=%04X, save type %02X\n", serial, crc32, buf[12]); saveType = buf[12]; fclose(fp); loaded = true; return true; } } } } } } } fclose(fp); } return false; }
void ColorspaceHandlerInit() { static bool needInitTables = true; if (needInitTables) { #define RGB15TO18_BITLOGIC(col) ( (material_5bit_to_6bit[((col)>>10)&0x1F]<<16) | (material_5bit_to_6bit[((col)>>5)&0x1F]<<8) | material_5bit_to_6bit[(col)&0x1F] ) #define RGB15TO18_SWAP_RB_BITLOGIC(col) ( material_5bit_to_6bit[((col)>>10)&0x1F] | (material_5bit_to_6bit[((col)>>5)&0x1F]<<8) | (material_5bit_to_6bit[(col)&0x1F]<<16) ) #define RGB15TO24_BITLOGIC(col) ( (material_5bit_to_8bit[((col)>>10)&0x1F]<<16) | (material_5bit_to_8bit[((col)>>5)&0x1F]<<8) | material_5bit_to_8bit[(col)&0x1F] ) #define RGB15TO24_SWAP_RB_BITLOGIC(col) ( material_5bit_to_8bit[((col)>>10)&0x1F] | (material_5bit_to_8bit[((col)>>5)&0x1F]<<8) | (material_5bit_to_8bit[(col)&0x1F]<<16) ) for (size_t i = 0; i < 32768; i++) { color_555_to_666[i] = LE_TO_LOCAL_32( RGB15TO18_BITLOGIC(i) ); color_555_to_6665_opaque[i] = LE_TO_LOCAL_32( RGB15TO18_BITLOGIC(i) | 0x1F000000 ); color_555_to_6665_opaque_swap_rb[i] = LE_TO_LOCAL_32( RGB15TO18_SWAP_RB_BITLOGIC(i) | 0x1F000000 ); color_555_to_888[i] = LE_TO_LOCAL_32( RGB15TO24_BITLOGIC(i) ); color_555_to_8888_opaque[i] = LE_TO_LOCAL_32( RGB15TO24_BITLOGIC(i) | 0xFF000000 ); color_555_to_8888_opaque_swap_rb[i] = LE_TO_LOCAL_32( RGB15TO24_SWAP_RB_BITLOGIC(i) | 0xFF000000 ); } } }
u32 Slot1Comp_Rom::read() { switch(operation) { case eSlot1Operation_00_ReadHeader_Unencrypted: { u32 ret = gameInfo.readROM(address); address = (address + 4) & 0xFFF; return ret; } break; case eSlot1Operation_2x_SecureAreaLoad: { //see B7 for details //zero 15-sep-2014 - this is meaningless. newer mask is actually reasonable //address &= gameInfo.mask; //sanity check u32 secureAreaAddress = (address - 0x4000); secureAreaAddress &= 0x3FFF; //memory safe sanity test u32 ret = LE_TO_LOCAL_32(*(u32*)(gameInfo.secureArea + secureAreaAddress)); address = (address&~0xFFF) + ((address+4)&0xFFF); return ret; } case eSlot1Operation_B7_Read: { //TODO - check about non-4-byte aligned addresses //it seems that etrian odyssey 3 doesnt work unless we mask this to cart size. //but, a thought: does the internal rom address counter register wrap around? we may be making a mistake by keeping the extra precision //but there is no test case yet address &= gameInfo.mask; //feature of retail carts: //B7 "Can be used only for addresses 8000h and up, smaller addresses will be silently redirected to address `8000h+(addr AND 1FFh)`" if(address < 0x8000) address = (0x8000 + (address & 0x1FF)); //1. as a sanity measure for funny-sized roms (homebrew and perhaps truncated retail roms) we need to protect ourselves by returning 0xFF for things still out of range. //2. this isnt right, unless someone documents otherwise: //if (address > gameInfo.header.endROMoffset) // ... the cart hardware doesnt know anything about the rom header. if it has a totally bogus endROMoffset, the cart will probably work just fine. and, the +4 is missing anyway: //3. this is better: it just allows us to read 0xFF anywhere we dont have rom data. forget what the header says //note: we allow the reading to proceed anyway, because the readROM method is built to allow jaggedy reads off the end of the rom to support trimmed roms if(address+4 > gameInfo.romsize) { DEBUG_Notify.ReadBeyondEndOfCart(address,gameInfo.romsize); } //actually read from the ROM provider u32 ret = gameInfo.readROM(address); //"However, the datastream wraps to the begin of the current 4K block when address+length crosses a 4K boundary (1000h bytes)" address = (address&~0xFFF) + ((address+4)&0xFFF); return ret; } break; default: return 0; } //switch(operation) } //Slot1Comp_Rom::read()