#pragma once #include "stdafx.h" enum class MirroringType { Horizontal, Vertical, ScreenAOnly, ScreenBOnly, FourScreens, }; struct NESHeader { char NES[4]; uint8_t ROMCount; uint8_t VROMCount; uint8_t Flags1; uint8_t Flags2; uint8_t RAMCount; uint8_t CartType; uint8_t Reserved[6]; uint8_t GetMapperID() { return (Flags2 & 0xF0) | (Flags1 >> 4); } MirroringType GetMirroringType() { if(Flags1 & 0x08) { return MirroringType::FourScreens; } else { return Flags1 & 0x01 ? MirroringType::Vertical : MirroringType::Horizontal; } } }; class ROMLoader { private: NESHeader _header; uint8_t* _prgRAM; uint32_t _prgSize; uint8_t* _chrRAM; uint32_t _chrSize; public: ROMLoader(wstring filename) { ifstream romFile(filename, ios::in | ios::binary); if(!romFile) { throw std::exception("File could not be read"); } romFile.read((char*)&_header, sizeof(NESHeader)); uint8_t* prgBuffer = new uint8_t[0x4000 * _header.ROMCount]; for(int i = 0; i < _header.ROMCount; i++) { romFile.read((char*)prgBuffer+i*0x4000, 0x4000); } _prgRAM = prgBuffer; uint8_t* chrBuffer = new uint8_t[0x2000 * _header.VROMCount]; for(int i = 0; i < _header.VROMCount; i++) { romFile.read((char*)chrBuffer+i*0x2000, 0x2000); } _chrRAM = chrBuffer; romFile.close(); } uint8_t* GetPRGRam() { return _prgRAM; } uint8_t* GetCHRRam() { return _chrRAM; } uint32_t GetPRGSize() { return _header.ROMCount * 0x4000; } uint32_t GetCHRSize() { return _header.VROMCount * 0x2000; } NESHeader GetHeader() { return _header; } };