diff --git a/CMakeLists.txt b/CMakeLists.txt index 885cc7c..195ea5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,7 +79,7 @@ add_executable(ComSquare sources/Renderer/SFRenderer.hpp sources/Renderer/SFRenderer.cpp sources/Exceptions/InvalidAction.hpp - sources/Cartridge/InterruptVectors.hpp) + sources/Cartridge/InterruptVectors.hpp sources/Memory/RectangleShadow.cpp sources/Memory/RectangleShadow.hpp) target_link_libraries(ComSquare sfml-graphics diff --git a/main.cpp b/main.cpp index b72a31d..daf9fa6 100644 --- a/main.cpp +++ b/main.cpp @@ -17,11 +17,10 @@ int main(int argc, char **argv) return 1; } Memory::MemoryBus bus; - SNES snes(std::make_shared(bus), argv[1]); + Renderer::SFRenderer renderer(600, 800, 60); + SNES snes(std::make_shared(bus), argv[1], renderer); bus.mapComponents(snes); - Renderer::SFRenderer renderer(600, 800, 60); - renderer.setWindowName("Fire Emblem : Three Houses"); while (!renderer.shouldExit) { renderer.getEvents(); } diff --git a/sources/Cartridge/Cartridge.cpp b/sources/Cartridge/Cartridge.cpp index 7954177..4b57ad3 100644 --- a/sources/Cartridge/Cartridge.cpp +++ b/sources/Cartridge/Cartridge.cpp @@ -173,7 +173,7 @@ namespace ComSquare::Cartridge this->header = this->_mapHeader(headerAddress); char name[22]; - std::memcpy(name, &this->_data[headerAddress + 0xC0u], 21); + std::memcpy(name, &this->_data[headerAddress], 21); name[21] = '\0'; this->header.gameName = std::string(name); if (headerAddress & 0x200u) { diff --git a/sources/Cartridge/Cartridge.hpp b/sources/Cartridge/Cartridge.hpp index a48d513..3b6abb2 100644 --- a/sources/Cartridge/Cartridge.hpp +++ b/sources/Cartridge/Cartridge.hpp @@ -67,7 +67,7 @@ namespace ComSquare::Cartridge //! @brief The size of the rom data. size_t _size; //! @brief Sometime the rom's data has an offset for a SMC header. This value indicate the start of the real rom discarding this header. - uint16_t _romStart; + uint16_t _romStart = 0; //! @brief Get the size of a rom from it's path. //! @param romPath The path of the rom to get info from. diff --git a/sources/Memory/MemoryBus.cpp b/sources/Memory/MemoryBus.cpp index 804c906..097da73 100644 --- a/sources/Memory/MemoryBus.cpp +++ b/sources/Memory/MemoryBus.cpp @@ -7,6 +7,7 @@ #include "MemoryBus.hpp" #include "../SNES.hpp" #include "MemoryShadow.hpp" +#include "RectangleShadow.hpp" namespace ComSquare::Memory { @@ -83,6 +84,7 @@ namespace ComSquare::Memory if (console.cartridge->header.mappingMode & Cartridge::LoRom) { console.cartridge->setMemoryRegion(0x80, 0xFF, 0x8000, 0xFFFF); this->_memoryAccessors.push_back(console.cartridge); + this->_memoryAccessors.push_back(Memory::RectangleShadow::createShadow(console.cartridge, 0x0, 0x7D, 0x8000, 0xFFFF)); } } } \ No newline at end of file diff --git a/sources/Memory/RectangleShadow.cpp b/sources/Memory/RectangleShadow.cpp new file mode 100644 index 0000000..b831fa2 --- /dev/null +++ b/sources/Memory/RectangleShadow.cpp @@ -0,0 +1,31 @@ +// +// Created by anonymus-raccoon on 2/4/20. +// + +#include "RectangleShadow.hpp" + +#include + +namespace ComSquare::Memory +{ + RectangleShadow::RectangleShadow(std::shared_ptr initial, uint8_t startBank, uint8_t endBank, uint16_t startPage, uint16_t endPage) + : _initial(std::move(initial)) + { + this->setMemoryRegion(startBank, endBank, startPage, endPage); + } + + std::shared_ptr RectangleShadow::createShadow(std::shared_ptr initial, uint8_t startBank, uint8_t endBank, uint16_t startPage, uint16_t endPage) + { + return static_cast>(new RectangleShadow(std::move(initial), startBank, endBank, startPage, endPage)); + } + + uint8_t RectangleShadow::read_internal(uint24_t addr) + { + return this->_initial->read_internal(addr); + } + + void RectangleShadow::write_internal(uint24_t addr, uint8_t data) + { + this->_initial->write_internal(addr, data); + } +} \ No newline at end of file diff --git a/sources/Memory/RectangleShadow.hpp b/sources/Memory/RectangleShadow.hpp new file mode 100644 index 0000000..95dcf42 --- /dev/null +++ b/sources/Memory/RectangleShadow.hpp @@ -0,0 +1,35 @@ +// +// Created by anonymus-raccoon on 2/4/20. +// + +#ifndef COMSQUARE_RECTANGLESHADOW_HPP +#define COMSQUARE_RECTANGLESHADOW_HPP + +#include +#include "IRectangleMemory.hpp" + +namespace ComSquare::Memory +{ + class RectangleShadow : public IRectangleMemory { + private: + //! @brief Memory to shadow from. + std::shared_ptr _initial; + public: + //! @brief Create a shadow for the memory given as parameter. + explicit RectangleShadow(std::shared_ptr initial, uint8_t startBank, uint8_t endBank, uint16_t startPage, uint16_t endPage); + + static std::shared_ptr createShadow(std::shared_ptr initial, uint8_t startBank, uint8_t endBank, uint16_t startPage, uint16_t endPage); + //! @brief Internal component read. Implement this as you would implement a basic IMemory's read. + //! @param addr The local address to read from. 0x0 refer to the first byte of your data and the address is in the component's space. That means that you can consider this address as continuous + //! @throw This function should thrown an InvalidAddress for address that are not mapped to the component. + //! @return Return the data at the address given as parameter. + uint8_t read_internal(uint24_t addr) override; + //! @brief Internal component write. Implement this as you would implement a basic IMemory's write. + //! @param addr The local address to write to. 0x0 refer to the first byte of your data and the address is in the component's space. That means that you can consider this address as continuous + //! @param data The new data to write. + //! @throw This function should thrown an InvalidAddress for address that are not mapped to the component. + void write_internal(uint24_t addr, uint8_t data) override; + }; +} + +#endif //COMSQUARE_RECTANGLESHADOW_HPP diff --git a/sources/SNES.cpp b/sources/SNES.cpp index 63bcb08..ed543fd 100644 --- a/sources/SNES.cpp +++ b/sources/SNES.cpp @@ -6,13 +6,15 @@ namespace ComSquare { - SNES::SNES(const std::shared_ptr &bus, const std::string &romPath) : + SNES::SNES(const std::shared_ptr &bus, const std::string &romPath, Renderer::IRenderer &renderer) : cpu(new CPU::CPU(bus)), ppu(new PPU::PPU()), apu(new APU::APU()), cartridge(new Cartridge::Cartridge(romPath)), - wram(new Ram::Ram(16384)) + wram(new Ram::Ram(16384)), + sram(new Ram::Ram(this->cartridge->header.sramSize)) { bus->mapComponents(*this); + renderer.setWindowName(this->cartridge->header.gameName); } } diff --git a/sources/SNES.hpp b/sources/SNES.hpp index 9557551..8bb865b 100644 --- a/sources/SNES.hpp +++ b/sources/SNES.hpp @@ -11,19 +11,27 @@ #include "Ram/Ram.hpp" #include "PPU/PPU.hpp" #include "APU/APU.hpp" +#include "Renderer/IRenderer.hpp" namespace ComSquare { //! @brief Container of all the components of the SNES. struct SNES { public: + //! @brief Central Processing Unit of the SNES. std::shared_ptr cpu; + //! @brief Picture Processing Unit of the SNES std::shared_ptr ppu; + //! @brief Audio Processing Unit if the SNES std::shared_ptr apu; + //! @brief Cartridge containing instructions (ROM). std::shared_ptr cartridge; + //! @brief Work Ram shared by all the components. std::shared_ptr wram; + //! @brief Save Ram residing inside the Cartridge in a real SNES. + std::shared_ptr sram; //! @brief Create all the components using a common memory bus for all of them. - SNES(const std::shared_ptr &bus, const std::string &ramPath); + SNES(const std::shared_ptr &bus, const std::string &ramPath, Renderer::IRenderer &renderer); }; }