#ifndef YAZE_APP_ROM_H #define YAZE_APP_ROM_H #include #include #include #include #include #include #include #include #include #include "absl/container/flat_hash_map.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "app/core/common.h" #include "app/core/constants.h" #include "app/gfx/bitmap.h" #define BUILD_HEADER(command, length) (command << 5) + (length - 1) namespace yaze { namespace app { constexpr int kCommandDirectCopy = 0; constexpr int kCommandByteFill = 1; constexpr int kCommandWordFill = 2; constexpr int kCommandIncreasingFill = 3; constexpr int kCommandRepeatingBytes = 4; constexpr int kMaxLengthNormalHeader = 32; constexpr int kMaxLengthCompression = 1024; constexpr int kNintendoMode1 = 0; constexpr int kNintendoMode2 = 1; constexpr int kTile32Num = 4432; constexpr uchar kGraphicsBitmap[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; using OWBlockset = std::vector>; struct OWMapTiles { OWBlockset light_world; // 64 maps OWBlockset dark_world; // 64 maps OWBlockset special_world; // 32 maps } typedef OWMapTiles; using CommandArgumentArray = std::array, 5>; using CommandSizeArray = std::array; using DataSizeArray = std::array; struct CompressionPiece { char command; int length; // char* argument; int argument_length; // CompressionPiece* next; std::string argument; std::shared_ptr next; CompressionPiece() {} CompressionPiece(int cmd, int len, std::string args, int arg_len) : command(cmd), length(len), argument(args), argument_length(arg_len), next(nullptr) {} } typedef CompressionPiece; class ROM { public: absl::StatusOr Compress(const int start, const int length, int mode = 0); absl::StatusOr CompressGraphics(const int pos, const int length); absl::StatusOr CompressOverworld(const int pos, const int length); absl::StatusOr Decompress(int offset, int size = 0x800, bool reversed = false); absl::StatusOr DecompressGraphics(int pos, int size); absl::StatusOr DecompressOverworld(int pos, int size); absl::StatusOr SNES3bppTo8bppSheet(Bytes sheet, int size = 0x1000); absl::Status LoadAllGraphicsData(); absl::Status LoadFromFile(const absl::string_view& filename); absl::Status LoadFromPointer(uchar* data, size_t length); auto GetSize() const { return size_; } auto GetTitle() const { return title; } auto GetGraphicsBin() const { return graphics_bin_; } auto isLoaded() const { return is_loaded_; } auto Renderer() { return renderer_; } void SetupRenderer(std::shared_ptr renderer) { renderer_ = renderer; } uchar& operator[](int i) { if (i > size_) { std::cout << "ROM: Index out of bounds" << std::endl; return rom_data_[0]; } return rom_data_[i]; } uchar& operator+(int i) { if (i > size_) { std::cout << "ROM: Index out of bounds" << std::endl; return rom_data_[0]; } return rom_data_[i]; } const uchar* operator&() { return rom_data_.data(); } private: long size_ = 0; uchar title[21] = "ROM Not Loaded"; bool is_loaded_ = false; Bytes rom_data_; std::shared_ptr renderer_; absl::flat_hash_map graphics_bin_; }; } // namespace app } // namespace yaze #endif