housekeeping and inventory

This commit is contained in:
Justin Scofield
2022-09-13 00:24:24 -05:00
parent 56ef315028
commit 67a5f6bf68
5 changed files with 144 additions and 121 deletions

View File

@@ -86,7 +86,7 @@ void ScreenEditor::DrawInventoryMenuEditor() {
tilesheet_canvas_.DrawBackground(ImVec2(128 * 2 + 2, 192 * 2 + 2)); tilesheet_canvas_.DrawBackground(ImVec2(128 * 2 + 2, 192 * 2 + 2));
tilesheet_canvas_.DrawContextMenu(); tilesheet_canvas_.DrawContextMenu();
tilesheet_canvas_.DrawBitmap(inventory_.Tilesheet(), 2, create); tilesheet_canvas_.DrawBitmap(inventory_.Tilesheet(), 2, create);
tilesheet_canvas_.DrawGrid(); tilesheet_canvas_.DrawGrid(16.0f);
tilesheet_canvas_.DrawOverlay(); tilesheet_canvas_.DrawOverlay();
ImGui::EndTable(); ImGui::EndTable();

View File

@@ -20,67 +20,10 @@
#include "app/core/constants.h" #include "app/core/constants.h"
#include "app/gfx/bitmap.h" #include "app/gfx/bitmap.h"
#define COMPRESSION_STRING_MOD 7 << 5
namespace yaze { namespace yaze {
namespace app { namespace app {
namespace { namespace lc_lz2 {
int GetGraphicsAddress(const uchar* data, uint8_t offset) {
auto part_one = data[kOverworldGraphicsPos1 + offset] << 16;
auto part_two = data[kOverworldGraphicsPos2 + offset] << 8;
auto part_three = data[kOverworldGraphicsPos3 + offset];
auto snes_addr = (part_one | part_two | part_three);
return core::SnesToPc(snes_addr);
}
Bytes SNES3bppTo8bppSheet(Bytes sheet, int bpp) {
Bytes sheet_buffer_out(0x1000);
int xx = 0; // positions where we are at on the sheet
int yy = 0;
int pos = 0;
int ypos = 0;
if (bpp == 2) {
bpp = 16;
} else if (bpp == 3) {
bpp = 24;
}
// for each tiles, 16 per line
for (int i = 0; i < 64; i++) {
// for each line
for (int y = 0; y < 8; y++) {
//[0] + [1] + [16]
for (int x = 0; x < 8; x++) {
auto b1 = ((sheet[(y * 2) + (bpp * pos)] & (kGraphicsBitmap[x])));
auto b2 = (sheet[((y * 2) + (bpp * pos)) + 1] & (kGraphicsBitmap[x]));
auto b3 = (sheet[(16 + y) + (bpp * pos)] & (kGraphicsBitmap[x]));
unsigned char b = 0;
if (b1 != 0) {
b |= 1;
}
if (b2 != 0) {
b |= 2;
}
if (b3 != 0 && bpp != 16) {
b |= 4;
}
sheet_buffer_out[x + (xx) + (y * 128) + (yy * 1024)] = b;
}
}
pos++;
ypos++;
xx += 8;
if (ypos >= 16) {
yy++;
xx = 0;
ypos = 0;
}
}
return sheet_buffer_out;
}
void PrintCompressionPiece(const std::shared_ptr<CompressionPiece>& piece) { void PrintCompressionPiece(const std::shared_ptr<CompressionPiece>& piece) {
printf("Command: %d\n", piece->command); printf("Command: %d\n", piece->command);
@@ -304,8 +247,7 @@ Bytes CreateCompressionString(std::shared_ptr<CompressionPiece>& start,
pos++; pos++;
} else { } else {
if (piece->length <= kMaxLengthCompression) { if (piece->length <= kMaxLengthCompression) {
output.push_back((COMPRESSION_STRING_MOD) | output.push_back(kCompressionStringMod | ((uchar)piece->command << 2) |
((uchar)piece->command << 2) |
(((piece->length - 1) & 0xFF00) >> 8)); (((piece->length - 1) & 0xFF00) >> 8));
pos++; pos++;
printf("Building extended header : cmd: %d, length: %d - %02X\n", printf("Building extended header : cmd: %d, length: %d - %02X\n",
@@ -398,6 +340,68 @@ std::shared_ptr<CompressionPiece> MergeCopy(
return start; return start;
} }
} // namespace lc_lz2
namespace {
int GetGraphicsAddress(const uchar* data, uint8_t offset) {
auto part_one = data[kOverworldGraphicsPos1 + offset] << 16;
auto part_two = data[kOverworldGraphicsPos2 + offset] << 8;
auto part_three = data[kOverworldGraphicsPos3 + offset];
auto snes_addr = (part_one | part_two | part_three);
return core::SnesToPc(snes_addr);
}
Bytes SNES3bppTo8bppSheet(Bytes sheet, int bpp) {
int xx = 0; // positions where we are at on the sheet
int yy = 0;
int pos = 0;
int ypos = 0;
int num_tiles = 64;
int buffer_size = 0x1000;
if (bpp == 2) {
bpp = 16;
num_tiles = 128;
buffer_size = 0x2000;
} else if (bpp == 3) {
bpp = 24;
}
Bytes sheet_buffer_out(buffer_size);
// for each tiles, 16 per line
for (int i = 0; i < num_tiles; i++) {
// for each line
for (int y = 0; y < 8; y++) {
//[0] + [1] + [16]
for (int x = 0; x < 8; x++) {
auto b1 = ((sheet[(y * 2) + (bpp * pos)] & (kGraphicsBitmap[x])));
auto b2 = (sheet[((y * 2) + (bpp * pos)) + 1] & (kGraphicsBitmap[x]));
auto b3 = (sheet[(16 + y) + (bpp * pos)] & (kGraphicsBitmap[x]));
unsigned char b = 0;
if (b1 != 0) {
b |= 1;
}
if (b2 != 0) {
b |= 2;
}
if (b3 != 0 && bpp != 16) {
b |= 4;
}
sheet_buffer_out[x + (xx) + (y * 128) + (yy * 1024)] = b;
}
}
pos++;
ypos++;
xx += 8;
if (ypos >= 16) {
yy++;
xx = 0;
ypos = 0;
}
}
return sheet_buffer_out;
}
} // namespace } // namespace
// TODO TEST compressed data border for each cmd // TODO TEST compressed data border for each cmd
@@ -419,18 +423,19 @@ absl::StatusOr<Bytes> ROM::Compress(const int start, const int length, int mode,
data_size_taken.fill({}); data_size_taken.fill({});
cmd_args.fill({{}}); cmd_args.fill({{}});
CheckByteRepeat(rom_data_.data(), data_size_taken, cmd_args, src_data_pos, lc_lz2::CheckByteRepeat(rom_data_.data(), data_size_taken, cmd_args,
last_pos); src_data_pos, last_pos);
CheckWordRepeat(rom_data_.data(), data_size_taken, cmd_args, src_data_pos, lc_lz2::CheckWordRepeat(rom_data_.data(), data_size_taken, cmd_args,
last_pos); src_data_pos, last_pos);
CheckIncByte(rom_data_.data(), data_size_taken, cmd_args, src_data_pos, lc_lz2::CheckIncByte(rom_data_.data(), data_size_taken, cmd_args,
last_pos); src_data_pos, last_pos);
CheckIntraCopy(rom_data_.data(), data_size_taken, cmd_args, src_data_pos, lc_lz2::CheckIntraCopy(rom_data_.data(), data_size_taken, cmd_args,
last_pos, start); src_data_pos, last_pos, start);
uint max_win = 2; uint max_win = 2;
uint cmd_with_max = kCommandDirectCopy; uint cmd_with_max = kCommandDirectCopy;
ValidateForByteGain(data_size_taken, cmd_size, max_win, cmd_with_max); lc_lz2::ValidateForByteGain(data_size_taken, cmd_size, max_win,
cmd_with_max);
if (cmd_with_max == kCommandDirectCopy) { if (cmd_with_max == kCommandDirectCopy) {
// This is the worst case scenario // This is the worst case scenario
@@ -453,9 +458,9 @@ absl::StatusOr<Bytes> ROM::Compress(const int start, const int length, int mode,
} }
} else { } else {
// Anything is better than directly copying bytes... // Anything is better than directly copying bytes...
CompressionCommandAlternative(rom_data_.data(), compressed_chain, lc_lz2::CompressionCommandAlternative(
cmd_size, cmd_args, src_data_pos, rom_data_.data(), compressed_chain, cmd_size, cmd_args, src_data_pos,
comp_accumulator, cmd_with_max, max_win); comp_accumulator, cmd_with_max, max_win);
} }
if (src_data_pos > last_pos) { if (src_data_pos > last_pos) {
@@ -464,14 +469,15 @@ absl::StatusOr<Bytes> ROM::Compress(const int start, const int length, int mode,
} }
if (check) { if (check) {
RETURN_IF_ERROR(ValidateCompressionResult(compressed_chain_start, mode, RETURN_IF_ERROR(lc_lz2::ValidateCompressionResult(
start, src_data_pos)) compressed_chain_start, mode, start, src_data_pos))
} }
} }
MergeCopy(compressed_chain_start->next); // Skipping compression chain header lc_lz2::MergeCopy(
PrintCompressionChain(compressed_chain_start); compressed_chain_start->next); // Skipping compression chain header
return CreateCompressionString(compressed_chain_start->next, mode); lc_lz2::PrintCompressionChain(compressed_chain_start);
return lc_lz2::CreateCompressionString(compressed_chain_start->next, mode);
} }
absl::StatusOr<Bytes> ROM::CompressGraphics(const int pos, const int length) { absl::StatusOr<Bytes> ROM::CompressGraphics(const int pos, const int length) {
@@ -544,8 +550,8 @@ absl::StatusOr<Bytes> ROM::Decompress(int offset, int size, int mode) {
((rom_data_[offset] & kSnesByteMax) << 8); ((rom_data_[offset] & kSnesByteMax) << 8);
if (addr > offset) { if (addr > offset) {
return absl::InternalError(absl::StrFormat( return absl::InternalError(absl::StrFormat(
"DecompressOverworld: Offset for command copy exceeds " "Decompress: Offset for command copy exceeds current position "
"current position (Offset : %#04x | Pos : %#06x)\n", "(Offset : %#04x | Pos : %#06x)\n",
addr, offset)); addr, offset));
} }
@@ -569,8 +575,7 @@ absl::StatusOr<Bytes> ROM::Decompress(int offset, int size, int mode) {
} break; } break;
default: { default: {
std::cout << absl::StrFormat( std::cout << absl::StrFormat(
"DecompressGraphics: Invalid command in header (Offset : %#06x, " "Decompress: Invalid header (Offset : %#06x, Command: %#04x)\n",
"Command: %#04x)\n",
offset, command); offset, command);
} break; } break;
} }
@@ -589,6 +594,21 @@ absl::StatusOr<Bytes> ROM::DecompressOverworld(int pos, int size) {
return Decompress(pos, size, kNintendoMode1); return Decompress(pos, size, kNintendoMode1);
} }
absl::StatusOr<Bytes> ROM::Load2bppGraphics() {
Bytes sheet;
const uint8_t sheets[] = {113, 114, 218, 219, 220, 221};
for (int i = 0; i < 6; i++) {
auto offset = GetGraphicsAddress(rom_data_.data(), sheets[i]);
ASSIGN_OR_RETURN(auto decomp_sheet, Decompress(offset))
auto converted_sheet = SNES3bppTo8bppSheet(decomp_sheet, 2);
for (int j = 0; j < converted_sheet.size(); ++j) {
sheet.push_back(converted_sheet.at(j));
}
}
return sheet;
}
// 0-112 -> compressed 3bpp bgr -> (decompressed each) 0x600 chars // 0-112 -> compressed 3bpp bgr -> (decompressed each) 0x600 chars
// 113-114 -> compressed 2bpp -> (decompressed each) 0x800 chars // 113-114 -> compressed 2bpp -> (decompressed each) 0x800 chars
// 115-126 -> uncompressed 3bpp sprites -> (each) 0x600 chars // 115-126 -> uncompressed 3bpp sprites -> (each) 0x600 chars
@@ -607,8 +627,8 @@ absl::Status ROM::LoadAllGraphicsData() {
} }
bpp3 = true; bpp3 = true;
} else if (i == 113 || i == 114 || i >= 218) { } else if (i == 113 || i == 114 || i >= 218) {
auto offset = GetGraphicsAddress(rom_data_.data(), i); // auto offset = GetGraphicsAddress(rom_data_.data(), i);
ASSIGN_OR_RETURN(sheet, Decompress(offset, 0x800)) // ASSIGN_OR_RETURN(sheet, Decompress(offset))
bpp3 = false; bpp3 = false;
} else { } else {
auto offset = GetGraphicsAddress(rom_data_.data(), i); auto offset = GetGraphicsAddress(rom_data_.data(), i);
@@ -627,14 +647,15 @@ absl::Status ROM::LoadAllGraphicsData() {
graphics_buffer_.push_back(graphics_bin_.at(i).GetByte(j)); graphics_buffer_.push_back(graphics_bin_.at(i).GetByte(j));
} }
} else { } else {
auto converted_sheet = SNES3bppTo8bppSheet(sheet, 2); // auto converted_sheet = SNES3bppTo8bppSheet(sheet, 2);
graphics_bin_[i] = // graphics_bin_[i] =
gfx::Bitmap(core::kTilesheetWidth, core::kTilesheetHeight, // gfx::Bitmap(core::kTilesheetWidth, core::kTilesheetHeight,
core::kTilesheetDepth, converted_sheet.data(), 0x1000); // core::kTilesheetDepth, converted_sheet.data(), 0x1000);
graphics_bin_.at(i).CreateTexture(renderer_); // graphics_bin_.at(i).CreateTexture(renderer_);
for (int j = 0; j < graphics_bin_.at(i).GetSize(); ++j) { for (int j = 0; j < graphics_bin_.at(0).GetSize(); ++j) {
graphics_buffer_.push_back(graphics_bin_.at(i).GetByte(j)); graphics_buffer_.push_back(0xFF);
// graphics_buffer_.push_back(graphics_bin_.at(i).GetByte(j));
} }
} }
} }

View File

@@ -17,6 +17,7 @@
#include "absl/status/statusor.h" #include "absl/status/statusor.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h" #include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "app/core/common.h" #include "app/core/common.h"
#include "app/core/constants.h" #include "app/core/constants.h"
#include "app/gfx/bitmap.h" #include "app/gfx/bitmap.h"
@@ -47,6 +48,7 @@ constexpr int kCommandMod = 0x07;
constexpr int kExpandedMod = 0xE0; constexpr int kExpandedMod = 0xE0;
constexpr int kExpandedLengthMod = 0x3FF; constexpr int kExpandedLengthMod = 0x3FF;
constexpr int kNormalLengthMod = 0x1F; constexpr int kNormalLengthMod = 0x1F;
constexpr int kCompressionStringMod = 7 << 5;
constexpr uchar kGraphicsBitmap[8] = {0x80, 0x40, 0x20, 0x10, constexpr uchar kGraphicsBitmap[8] = {0x80, 0x40, 0x20, 0x10,
0x08, 0x04, 0x02, 0x01}; 0x08, 0x04, 0x02, 0x01};
@@ -76,6 +78,8 @@ class ROM {
absl::StatusOr<Bytes> DecompressGraphics(int pos, int size); absl::StatusOr<Bytes> DecompressGraphics(int pos, int size);
absl::StatusOr<Bytes> DecompressOverworld(int pos, int size); absl::StatusOr<Bytes> DecompressOverworld(int pos, int size);
absl::StatusOr<Bytes> Load2bppGraphics();
absl::Status LoadAllGraphicsData(); absl::Status LoadAllGraphicsData();
absl::Status LoadFromFile(const absl::string_view& filename); absl::Status LoadFromFile(const absl::string_view& filename);
absl::Status LoadFromPointer(uchar* data, size_t length); absl::Status LoadFromPointer(uchar* data, size_t length);

View File

@@ -13,9 +13,18 @@ void Inventory::Create(Bytes& all_gfx) {
for (int i = 0; i < 256 * 256; i++) { for (int i = 0; i < 256 * 256; i++) {
data_.push_back(0xFF); data_.push_back(0xFF);
} }
BuildTileset(all_gfx); PRINT_IF_ERROR(BuildTileset(all_gfx))
//tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kInventoryStart)));
tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kBowItemPos))); tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kBowItemPos)));
const int offsets[] = {0x00, 0x08, 0x200, 0x208}; tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kBowItemPos + 0x02)));
tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kBowItemPos + 0x04)));
tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kBowItemPos + 0x08)));
// tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kLampItemPos)));
// tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kLampItemPos + 0x02)));
// tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kLampItemPos + 0x04)));
// tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kLampItemPos + 0x08)));
const int offsets[] = {0x00, 0x08, 0x800, 0x808};
auto xx = 0; auto xx = 0;
auto yy = 0; auto yy = 0;
@@ -36,7 +45,7 @@ void Inventory::Create(Bytes& all_gfx) {
} }
int xpos = ((tile.id_ % 0x10) * 0x08); int xpos = ((tile.id_ % 0x10) * 0x08);
int ypos = (((tile.id_ / 0x10)) * 0x200); int ypos = (((tile.id_ / 0x10)) * 0x400);
int source = ypos + xpos + (x + (y * 0x80)); int source = ypos + xpos + (x + (y * 0x80));
auto destination = xx + yy + offset + (mx + (my * 0x100)); auto destination = xx + yy + offset + (mx + (my * 0x100));
@@ -44,39 +53,29 @@ void Inventory::Create(Bytes& all_gfx) {
} }
} }
xx += 0x10;
if (xx >= 0x80) {
yy += 0x800;
xx = 0;
}
if (i == 4) { if (i == 4) {
i = 0; i = 0;
xx += 0x10;
if (xx >= 0x80) {
yy += 0x800;
xx = 0;
}
} else {
i++;
} }
i++;
} }
bitmap_.Create(256, 256, 128, data_); bitmap_.Create(256, 256, 128, data_);
// bitmap_.ApplyPalette(rom_.GetPaletteGroup("hud")[0]); // bitmap_.ApplyPalette(rom_.GetPaletteGroup("hud")[0]);
rom_.RenderBitmap(&bitmap_); rom_.RenderBitmap(&bitmap_);
} }
void Inventory::BuildTileset(Bytes& all_gfx) { absl::Status Inventory::BuildTileset(Bytes& all_gfx) {
//const int offsets[] = {0xDC000, 0x6D900, 0x6EF00, 0x6F000, 0xD8000, 0xD9000}; tilesheets_.reserve(6 * 0x2000);
const int offsets[] = {0xDC000, 0x6D900, 0x6EF00, 0x6F000, 0xD8000, 0xD9000}; for (int i = 0; i < 6 * 0x2000; i++) tilesheets_.push_back(0xFF);
tilesheets_.reserve(6 * 0x1000); ASSIGN_OR_RETURN(tilesheets_, rom_.Load2bppGraphics())
for (int i = 0; i < 6 * 0x1000; i++) { tilesheets_bmp_.Create(128, 192 + 96 + 48 - 16, 64, tilesheets_);
tilesheets_.push_back(0xFF);
}
for (int y = 0; y < 6; y++) {
int offset = offsets[y];
for (int x = 0; x < 0x1000; x++) {
tilesheets_[x + (y * 0x1000)] = all_gfx[offset + x + (y * 0x1000)];
}
}
tilesheets_bmp_.Create(128, 192, 64, tilesheets_);
rom_.RenderBitmap(&tilesheets_bmp_); rom_.RenderBitmap(&tilesheets_bmp_);
return absl::OkStatus();
} }
} // namespace zelda3 } // namespace zelda3

View File

@@ -10,8 +10,8 @@ namespace yaze {
namespace app { namespace app {
namespace zelda3 { namespace zelda3 {
constexpr int kMenuGfxStart = 0xE000; constexpr int kInventoryStart = 0x6564A;
constexpr int kLampItemPos = 0x6F6F0; constexpr int kLampItemPos = 0x6F6F9;
constexpr int kBowItemPos = 0x6F631; constexpr int kBowItemPos = 0x6F631;
class Inventory { class Inventory {
@@ -23,8 +23,7 @@ class Inventory {
void Create(Bytes& all_gfx); void Create(Bytes& all_gfx);
private: private:
void BuildTileset(Bytes& all_gfx); absl::Status BuildTileset(Bytes& all_gfx);
ROM rom_; ROM rom_;