Skip to content

Commit

Permalink
pointer instead of reference
Browse files Browse the repository at this point in the history
  • Loading branch information
Kautenja committed Jul 18, 2019
1 parent 934c8f8 commit cc9e9ca
Show file tree
Hide file tree
Showing 13 changed files with 80 additions and 65 deletions.
19 changes: 19 additions & 0 deletions backup_restore.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from nes_py import NESEnv
import tqdm
env = NESEnv('./nes_py/tests/games/super-mario-bros-1.nes')

done = True

try:
for i in tqdm.tqdm(range(5000)):
if done:
state = env.reset()
done = False
else:
state, reward, done, info = env.step(env.action_space.sample())
if (i + 1) % 12:
env._backup()
if (i + 1) % 27:
env._restore()
except KeyboardInterrupt:
pass
16 changes: 13 additions & 3 deletions nes_py/nes/include/emulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class Emulator {
///
/// @param rom_path the path to the ROM for the emulator to run
///
Emulator(std::string rom_path);
explicit Emulator(std::string rom_path);

/// Return a 32-bit pointer to the screen buffer's first address.
///
Expand Down Expand Up @@ -88,10 +88,20 @@ class Emulator {
void step();

/// Create a backup state on the emulator.
void backup();
inline void backup() {
backup_bus = bus;
backup_picture_bus = picture_bus;
backup_cpu = cpu;
backup_ppu = ppu;
}

/// Restore the backup state on the emulator.
void restore();
inline void restore() {
bus = backup_bus;
picture_bus = backup_picture_bus;
cpu = backup_cpu;
ppu = backup_ppu;
}
};

} // namespace NES
Expand Down
10 changes: 5 additions & 5 deletions nes_py/nes/include/mapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ enum NameTableMirroring {
class Mapper {
protected:
/// The cartridge this mapper associates with
Cartridge& cartridge;
Cartridge* cartridge;

public:
/// an enumeration of mapper IDs
Expand All @@ -42,15 +42,15 @@ class Mapper {
///
/// @param game a reference to a cartridge for the mapper to access
///
Mapper(Cartridge& game) : cartridge(game) { }
Mapper(Cartridge* game) : cartridge(game) { }

/// Create a mapper based on given type, a game cartridge.
///
/// @param game a reference to a cartridge for the mapper to access
/// @param callback the callback to signify a change in mirroring mode
/// @return a pointer to a mapper class based on the given game
///
static Mapper* create(Cartridge& game, std::function<void(void)> callback);
static Mapper* create(Cartridge* game, std::function<void(void)> callback);

/// Read a byte from the PRG RAM.
///
Expand Down Expand Up @@ -89,11 +89,11 @@ class Mapper {

/// Return the name table mirroring mode of this mapper.
inline virtual NameTableMirroring getNameTableMirroring() {
return static_cast<NameTableMirroring>(cartridge.getNameTableMirroring());
return static_cast<NameTableMirroring>(cartridge->getNameTableMirroring());
}

/// Return true if this mapper has extended RAM, false otherwise.
inline bool hasExtendedRAM() { return cartridge.hasExtendedRAM(); }
inline bool hasExtendedRAM() { return cartridge->hasExtendedRAM(); }
};

} // namespace NES
Expand Down
4 changes: 2 additions & 2 deletions nes_py/nes/include/mappers/mapper_CNROM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class MapperCNROM : public Mapper {
///
/// @param cart a reference to a cartridge for the mapper to access
///
MapperCNROM(Cartridge& cart);
explicit MapperCNROM(Cartridge* cart);

/// Read a byte from the PRG RAM.
///
Expand All @@ -49,7 +49,7 @@ class MapperCNROM : public Mapper {
/// @return the byte located at the given address in CHR RAM
///
inline NES_Byte readCHR(NES_Address address) {
return cartridge.getVROM()[address | (select_chr << 13)];
return cartridge->getVROM()[address | (select_chr << 13)];
}

/// Write a byte to an address in the CHR RAM.
Expand Down
2 changes: 1 addition & 1 deletion nes_py/nes/include/mappers/mapper_NROM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class MapperNROM : public Mapper {
///
/// @param cart a reference to a cartridge for the mapper to access
///
MapperNROM(Cartridge& cart);
MapperNROM(Cartridge* cart);

/// Read a byte from the PRG RAM.
///
Expand Down
2 changes: 1 addition & 1 deletion nes_py/nes/include/mappers/mapper_SxROM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class MapperSxROM : public Mapper {
/// @param cart a reference to a cartridge for the mapper to access
/// @param mirroring_cb the callback to change mirroring modes on the PPU
///
MapperSxROM(Cartridge& cart, std::function<void(void)> mirroring_cb);
MapperSxROM(Cartridge* cart, std::function<void(void)> mirroring_cb);

/// Read a byte from the PRG RAM.
///
Expand Down
2 changes: 1 addition & 1 deletion nes_py/nes/include/mappers/mapper_UxROM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class MapperUxROM : public Mapper {
///
/// @param cart a reference to a cartridge for the mapper to access
///
MapperUxROM(Cartridge& cart);
MapperUxROM(Cartridge* cart);

/// Read a byte from the PRG RAM.
///
Expand Down
16 changes: 1 addition & 15 deletions nes_py/nes/src/emulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Emulator::Emulator(std::string rom_path) {
// load the ROM from disk, expect that the Python code has validated it
cartridge.loadFromFile(rom_path);
// create the mapper based on the mapper ID in the iNES header of the ROM
Mapper* mapper(Mapper::create(cartridge, [&](){ picture_bus.update_mirroring(); }));
Mapper* mapper(Mapper::create(&cartridge, [&](){ picture_bus.update_mirroring(); }));
// give the IO buses a pointer to the mapper
bus.set_mapper(mapper);
picture_bus.set_mapper(mapper);
Expand All @@ -49,18 +49,4 @@ void Emulator::step() {
}
}

void Emulator::backup() {
backup_bus = bus;
backup_picture_bus = picture_bus;
backup_cpu = cpu;
backup_ppu = ppu;
}

void Emulator::restore() {
bus = backup_bus;
picture_bus = backup_picture_bus;
cpu = backup_cpu;
ppu = backup_ppu;
}

} // namespace NES
4 changes: 2 additions & 2 deletions nes_py/nes/src/mapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

namespace NES {

Mapper* Mapper::create(Cartridge& game, std::function<void(void)> callback) {
switch (static_cast<Mapper::Type>(game.getMapper())) {
Mapper* Mapper::create(Cartridge* game, std::function<void(void)> callback) {
switch (static_cast<Mapper::Type>(game->getMapper())) {
case NROM:
return new MapperNROM(game);
case SxROM:
Expand Down
12 changes: 6 additions & 6 deletions nes_py/nes/src/mappers/mapper_CNROM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,24 @@

namespace NES {

MapperCNROM::MapperCNROM(Cartridge& cart) : Mapper(cart), select_chr(0) {
is_one_bank = cart.getROM().size() == 0x4000;
MapperCNROM::MapperCNROM(Cartridge* cart) : Mapper(cart), select_chr(0) {
is_one_bank = cart->getROM().size() == 0x4000;
}

NES_Byte MapperCNROM::readPRG(NES_Address address) {
if (!is_one_bank)
return cartridge.getROM()[address - 0x8000];
return cartridge->getROM()[address - 0x8000];
// mirrored
else
return cartridge.getROM()[(address - 0x8000) & 0x3fff];
return cartridge->getROM()[(address - 0x8000) & 0x3fff];
}

const NES_Byte* MapperCNROM::getPagePtr(NES_Address address) {
if (!is_one_bank)
return &cartridge.getROM()[address - 0x8000];
return &cartridge->getROM()[address - 0x8000];
// mirrored
else
return &cartridge.getROM()[(address - 0x8000) & 0x3fff];
return &cartridge->getROM()[(address - 0x8000) & 0x3fff];
}

void MapperCNROM::writeCHR(NES_Address address, NES_Byte value) {
Expand Down
16 changes: 8 additions & 8 deletions nes_py/nes/src/mappers/mapper_NROM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@

namespace NES {

MapperNROM::MapperNROM(Cartridge &cart) : Mapper(cart) {
if (cart.getROM().size() == 0x4000) // 1 bank
MapperNROM::MapperNROM(Cartridge* cart) : Mapper(cart) {
if (cart->getROM().size() == 0x4000) // 1 bank
is_one_bank = true;
else // 2 banks
is_one_bank = false;

if (cart.getVROM().size() == 0) {
if (cart->getVROM().size() == 0) {
has_character_ram = true;
character_ram.resize(0x2000);
LOG(Info) << "Uses character RAM" << std::endl;
Expand All @@ -27,9 +27,9 @@ MapperNROM::MapperNROM(Cartridge &cart) : Mapper(cart) {

NES_Byte MapperNROM::readPRG(NES_Address address) {
if (!is_one_bank)
return cartridge.getROM()[address - 0x8000];
return cartridge->getROM()[address - 0x8000];
else // mirrored
return cartridge.getROM()[(address - 0x8000) & 0x3fff];
return cartridge->getROM()[(address - 0x8000) & 0x3fff];
}

void MapperNROM::writePRG(NES_Address address, NES_Byte value) {
Expand All @@ -45,7 +45,7 @@ NES_Byte MapperNROM::readCHR(NES_Address address) {
if (has_character_ram)
return character_ram[address];
else
return cartridge.getVROM()[address];
return cartridge->getVROM()[address];
}

void MapperNROM::writeCHR(NES_Address address, NES_Byte value) {
Expand All @@ -61,9 +61,9 @@ void MapperNROM::writeCHR(NES_Address address, NES_Byte value) {

const NES_Byte* MapperNROM::getPagePtr(NES_Address address) {
if (!is_one_bank)
return &cartridge.getROM()[address - 0x8000];
return &cartridge->getROM()[address - 0x8000];
else // mirrored
return &cartridge.getROM()[(address - 0x8000) & 0x3fff];
return &cartridge->getROM()[(address - 0x8000) & 0x3fff];
}

} // namespace NES
30 changes: 15 additions & 15 deletions nes_py/nes/src/mappers/mapper_SxROM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace NES {

MapperSxROM::MapperSxROM(Cartridge &cart, std::function<void(void)> mirroring_cb) :
MapperSxROM::MapperSxROM(Cartridge* cart, std::function<void(void)> mirroring_cb) :
Mapper(cart),
mirroring_callback(mirroring_cb),
mirroing(HORIZONTAL),
Expand All @@ -25,20 +25,20 @@ MapperSxROM::MapperSxROM(Cartridge &cart, std::function<void(void)> mirroring_cb
second_bank_prg(nullptr),
first_bank_chr(nullptr),
second_bank_chr(nullptr) {
if (cart.getVROM().size() == 0) {
if (cart->getVROM().size() == 0) {
has_character_ram = true;
character_ram.resize(0x2000);
LOG(Info) << "Uses character RAM" << std::endl;
} else {
LOG(Info) << "Using CHR-ROM" << std::endl;
has_character_ram = false;
first_bank_chr = &cart.getVROM()[0];
second_bank_chr = &cart.getVROM()[0x1000 * register_chr1];
first_bank_chr = &cart->getVROM()[0];
second_bank_chr = &cart->getVROM()[0x1000 * register_chr1];
}
// first bank
first_bank_prg = &cart.getROM()[0];
first_bank_prg = &cart->getROM()[0];
// last bank
second_bank_prg = &cart.getROM()[cart.getROM().size() - 0x4000];
second_bank_prg = &cart->getROM()[cart->getROM().size() - 0x4000];
}

NES_Byte MapperSxROM::readPRG(NES_Address address) {
Expand Down Expand Up @@ -70,22 +70,22 @@ void MapperSxROM::writePRG(NES_Address address, NES_Byte value) {
// Recalculate CHR pointers
if (mode_chr == 0) { // one 8KB bank
// ignore last bit
first_bank_chr = &cartridge.getVROM()[0x1000 * (register_chr0 | 1)];
first_bank_chr = &cartridge->getVROM()[0x1000 * (register_chr0 | 1)];
second_bank_chr = first_bank_chr + 0x1000;
} else { // two 4KB banks
first_bank_chr = &cartridge.getVROM()[0x1000 * register_chr0];
second_bank_chr = &cartridge.getVROM()[0x1000 * register_chr1];
first_bank_chr = &cartridge->getVROM()[0x1000 * register_chr0];
second_bank_chr = &cartridge->getVROM()[0x1000 * register_chr1];
}
} else if (address <= 0xbfff) { // CHR Reg 0
register_chr0 = temp_register;
// OR 1 if 8KB mode
first_bank_chr = &cartridge.getVROM()[0x1000 * (temp_register | (1 - mode_chr))];
first_bank_chr = &cartridge->getVROM()[0x1000 * (temp_register | (1 - mode_chr))];
if (mode_chr == 0)
second_bank_chr = first_bank_chr + 0x1000;
} else if (address <= 0xdfff) {
register_chr1 = temp_register;
if(mode_chr == 1)
second_bank_chr = &cartridge.getVROM()[0x1000 * temp_register];
second_bank_chr = &cartridge->getVROM()[0x1000 * temp_register];
} else {
// TODO: PRG-RAM
if ((temp_register & 0x10) == 0x10) {
Expand All @@ -110,15 +110,15 @@ void MapperSxROM::writePRG(NES_Address address, NES_Byte value) {
void MapperSxROM::calculatePRGPointers() {
if (mode_prg <= 1) { // 32KB changeable
// equivalent to multiplying 0x8000 * (register_prg >> 1)
first_bank_prg = &cartridge.getROM()[0x4000 * (register_prg & ~1)];
first_bank_prg = &cartridge->getROM()[0x4000 * (register_prg & ~1)];
// add 16KB
second_bank_prg = first_bank_prg + 0x4000;
} else if (mode_prg == 2) { // fix first switch second
first_bank_prg = &cartridge.getROM()[0];
first_bank_prg = &cartridge->getROM()[0];
second_bank_prg = first_bank_prg + 0x4000 * register_prg;
} else { // switch first fix second
first_bank_prg = &cartridge.getROM()[0x4000 * register_prg];
second_bank_prg = &cartridge.getROM()[cartridge.getROM().size() - 0x4000];
first_bank_prg = &cartridge->getROM()[0x4000 * register_prg];
second_bank_prg = &cartridge->getROM()[cartridge->getROM().size() - 0x4000];
}
}

Expand Down
12 changes: 6 additions & 6 deletions nes_py/nes/src/mappers/mapper_UxROM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@

namespace NES {

MapperUxROM::MapperUxROM(Cartridge &cart) :
MapperUxROM::MapperUxROM(Cartridge* cart) :
Mapper(cart),
select_prg(0) {
if (cart.getVROM().size() == 0) {
if (cart->getVROM().size() == 0) {
has_character_ram = true;
character_ram.resize(0x2000);
LOG(Info) << "Uses character RAM" << std::endl;
Expand All @@ -22,19 +22,19 @@ MapperUxROM::MapperUxROM(Cartridge &cart) :
}

// last - 16KB
last_bank_pointer = &cart.getROM()[cart.getROM().size() - 0x4000];
last_bank_pointer = &cart->getROM()[cart->getROM().size() - 0x4000];
}

NES_Byte MapperUxROM::readPRG(NES_Address address) {
if (address < 0xc000)
return cartridge.getROM()[((address - 0x8000) & 0x3fff) | (select_prg << 14)];
return cartridge->getROM()[((address - 0x8000) & 0x3fff) | (select_prg << 14)];
else
return *(last_bank_pointer + (address & 0x3fff));
}

const NES_Byte* MapperUxROM::getPagePtr(NES_Address address) {
if (address < 0xc000)
return &cartridge.getROM()[((address - 0x8000) & 0x3fff) | (select_prg << 14)];
return &cartridge->getROM()[((address - 0x8000) & 0x3fff) | (select_prg << 14)];
else
return last_bank_pointer + (address & 0x3fff);
}
Expand All @@ -43,7 +43,7 @@ NES_Byte MapperUxROM::readCHR(NES_Address address) {
if (has_character_ram)
return character_ram[address];
else
return cartridge.getVROM()[address];
return cartridge->getVROM()[address];
}

void MapperUxROM::writeCHR(NES_Address address, NES_Byte value) {
Expand Down

0 comments on commit cc9e9ca

Please sign in to comment.