build current overworld graphics from 8bpp buffer
This commit is contained in:
@@ -44,7 +44,7 @@ absl::Status OverworldEditor::Update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (overworld_debug_menu_) {
|
if (overworld_debug_menu_) {
|
||||||
DrawOverworldDebugMenu();
|
RETURN_IF_ERROR(DrawOverworldDebugMenu())
|
||||||
}
|
}
|
||||||
|
|
||||||
auto toolset_status = DrawToolset();
|
auto toolset_status = DrawToolset();
|
||||||
@@ -179,8 +179,22 @@ void OverworldEditor::DrawOverworldCanvas() {
|
|||||||
if (overworld_.isLoaded()) {
|
if (overworld_.isLoaded()) {
|
||||||
auto map = overworld_.GetOverworldMap(0);
|
auto map = overworld_.GetOverworldMap(0);
|
||||||
if (map.IsInitialized() && map.IsBuilt()) {
|
if (map.IsInitialized() && map.IsBuilt()) {
|
||||||
overworld_map_canvas_.DrawBitmap(map.GetBitmap(), 2);
|
if (map.IsLargeMap()) {
|
||||||
|
//g.FillRectangle(new SolidBrush(Palettes.overworld_GrassPalettes[0]), new RectangleF(x * 512, y * 512, 1024, 1024));
|
||||||
|
// g.DrawImage(ow.allmaps[ow.allmaps[selectedMap].parent].gfxBitmap, new PointF(x * 512, y * 512));
|
||||||
|
// g.DrawImage(ow.allmaps[ow.allmaps[selectedMap].parent + 1].gfxBitmap, new PointF((x + 1) * 512, y * 512));
|
||||||
|
// g.DrawImage(ow.allmaps[ow.allmaps[selectedMap].parent + 8].gfxBitmap, new PointF((x) * 512, (y+1) * 512));
|
||||||
|
// g.DrawImage(ow.allmaps[ow.allmaps[selectedMap].parent + 9].gfxBitmap, new PointF((x + 1) * 512, (y+1) * 512));
|
||||||
|
|
||||||
|
overworld_map_canvas_.DrawBitmap(map.GetBitmap(), 2);
|
||||||
|
} else {
|
||||||
|
// g.FillRectangle(new SolidBrush(Palettes.overworld_GrassPalettes[0]), new RectangleF(x * 512, y * 512, 512, 512));
|
||||||
|
//g.DrawImage(ow.allmaps[ow.allmaps[selectedMap].parent].gfxBitmap, new PointF(x * 512, y * 512));
|
||||||
|
|
||||||
|
overworld_map_canvas_.DrawBitmap(map.GetBitmap(), 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
overworld_map_canvas_.DrawGrid(64.f);
|
overworld_map_canvas_.DrawGrid(64.f);
|
||||||
overworld_map_canvas_.DrawOverlay();
|
overworld_map_canvas_.DrawOverlay();
|
||||||
@@ -279,21 +293,17 @@ void OverworldEditor::DrawAreaGraphics() {
|
|||||||
|
|
||||||
absl::Status OverworldEditor::DrawOverworldDebugMenu() {
|
absl::Status OverworldEditor::DrawOverworldDebugMenu() {
|
||||||
ImGui::Begin("Overworld Debug Menu");
|
ImGui::Begin("Overworld Debug Menu");
|
||||||
|
|
||||||
if (ImGui::Button("Load Overworld")) {
|
if (ImGui::Button("Load Overworld")) {
|
||||||
RETURN_IF_ERROR(overworld_.Load(rom_))
|
RETURN_IF_ERROR(overworld_.Load(rom_))
|
||||||
}
|
current_gfx_bmp_.Create(128, 512, 64,
|
||||||
if (ImGui::Button("Current Graphics Bitmap")) {
|
overworld_.GetCurrentGraphics().data());
|
||||||
current_gfx_bmp_.Create(128, 512, 8, overworld_.GetCurrentGraphics().data(),
|
|
||||||
32768);
|
|
||||||
rom_.RenderBitmap(¤t_gfx_bmp_);
|
rom_.RenderBitmap(¤t_gfx_bmp_);
|
||||||
}
|
tile16_blockset_bmp_.Create(128, 8192, 128,
|
||||||
if (ImGui::Button("Tile16 Blockset Bitmap")) {
|
overworld_.GetCurrentBlockset().data());
|
||||||
tile16_blockset_bmp_.Create(
|
|
||||||
512, 16384, 8, overworld_.GetCurrentBlockset().data(), 1048576);
|
|
||||||
rom_.RenderBitmap(&tile16_blockset_bmp_);
|
rom_.RenderBitmap(&tile16_blockset_bmp_);
|
||||||
}
|
overworld_map_bmp_.Create(512, 512, 8,
|
||||||
if (ImGui::Button("Overworld Map Bitmap")) {
|
overworld_.GetCurrentBitmapData().data());
|
||||||
overworld_map_bmp_.Create(1024, 1024, 8, overworld_.GetCurrentBitmapData().data());
|
|
||||||
rom_.RenderBitmap(&overworld_map_bmp_);
|
rom_.RenderBitmap(&overworld_map_bmp_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,8 +319,10 @@ void OverworldEditor::LoadGraphics() {
|
|||||||
current_palette_[i].w = 1.f;
|
current_palette_[i].w = 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRINT_IF_ERROR(rom_.LoadAllGraphicsData());
|
PRINT_IF_ERROR(rom_.LoadAllGraphicsData())
|
||||||
graphics_bin_ = rom_.GetGraphicsBin();
|
graphics_bin_ = rom_.GetGraphicsBin();
|
||||||
|
|
||||||
|
PRINT_IF_ERROR(rom_.CreateAllGraphicsData())
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace editor
|
} // namespace editor
|
||||||
|
|||||||
166
src/app/rom.cc
166
src/app/rom.cc
@@ -281,7 +281,7 @@ absl::StatusOr<std::shared_ptr<CompressionPiece>> SplitCompressionPiece(
|
|||||||
default: {
|
default: {
|
||||||
return absl::InvalidArgumentError(
|
return absl::InvalidArgumentError(
|
||||||
"SplitCompressionCommand: Invalid Command");
|
"SplitCompressionCommand: Invalid Command");
|
||||||
} break;
|
}
|
||||||
}
|
}
|
||||||
return new_piece;
|
return new_piece;
|
||||||
}
|
}
|
||||||
@@ -578,6 +578,166 @@ absl::StatusOr<Bytes> ROM::DecompressOverworld(int pos, int size) {
|
|||||||
return Decompress(pos, size, kNintendoMode1);
|
return Decompress(pos, size, kNintendoMode1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<Bytes> ROM::CreateAllGfxDataRaw() {
|
||||||
|
// 0-112 -> compressed 3bpp bgr -> (decompressed each) 0x600 bytes
|
||||||
|
// 113-114 -> compressed 2bpp -> (decompressed each) 0x800 bytes
|
||||||
|
// 115-126 -> uncompressed 3bpp sprites -> (each) 0x600 bytes
|
||||||
|
// 127-217 -> compressed 3bpp sprites -> (decompressed each) 0x600 bytes
|
||||||
|
// 218-222 -> compressed 2bpp -> (decompressed each) 0x800 bytes
|
||||||
|
Bytes buffer(0x54A00);
|
||||||
|
for (int i = 0; i < 0x54A00; ++i) {
|
||||||
|
buffer.push_back(0x00);
|
||||||
|
}
|
||||||
|
int bufferPos = 0;
|
||||||
|
Bytes data(0x600);
|
||||||
|
for (int i = 0; i < 0x600; ++i) {
|
||||||
|
buffer.push_back(0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 223; i++) {
|
||||||
|
bool c = true;
|
||||||
|
if (i >= 0 && i <= 112) // compressed 3bpp bgr
|
||||||
|
{
|
||||||
|
isbpp3[i] = true;
|
||||||
|
} else if (i >= 113 && i <= 114) // compressed 2bpp
|
||||||
|
{
|
||||||
|
isbpp3[i] = false;
|
||||||
|
} else if (i >= 115 && i <= 126) // uncompressed 3bpp sprites
|
||||||
|
{
|
||||||
|
isbpp3[i] = true;
|
||||||
|
c = false;
|
||||||
|
} else if (i >= 127 && i <= 217) // compressed 3bpp sprites
|
||||||
|
{
|
||||||
|
isbpp3[i] = true;
|
||||||
|
} else if (i >= 218 && i <= 222) // compressed 2bpp
|
||||||
|
{
|
||||||
|
isbpp3[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c) // if data is compressed decompress it
|
||||||
|
{
|
||||||
|
auto offset = GetGraphicsAddress(rom_data_.data(), i);
|
||||||
|
ASSIGN_OR_RETURN(data, Decompress(offset))
|
||||||
|
} else {
|
||||||
|
data.resize(core::Uncompressed3BPPSize);
|
||||||
|
auto offset = GetGraphicsAddress(rom_data_.data(), i);
|
||||||
|
for (int j = 0; j < core::Uncompressed3BPPSize; j++) {
|
||||||
|
data[j] = rom_data_[j + offset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < data.size(); j++) {
|
||||||
|
buffer[j + bufferPos] = data[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferPos += data.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::Status ROM::CreateAllGraphicsData() {
|
||||||
|
ASSIGN_OR_RETURN(Bytes data, CreateAllGfxDataRaw())
|
||||||
|
Bytes newData(0x6F800);
|
||||||
|
for (int i = 0; i < 0x6F800; i++) {
|
||||||
|
newData.push_back(0x00);
|
||||||
|
}
|
||||||
|
Bytes mask{0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
|
||||||
|
int sheetPosition = 0;
|
||||||
|
|
||||||
|
// 8x8 tile
|
||||||
|
// Per Sheet
|
||||||
|
for (int s = 0; s < 223; s++) {
|
||||||
|
// Per Tile Line Y
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
// Per Tile Line X
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
// Per Pixel Line
|
||||||
|
for (int y = 0; y < 8; y++) {
|
||||||
|
if (isbpp3[s]) {
|
||||||
|
auto lineBits0 =
|
||||||
|
data[(y * 2) + (i * 24) + (j * 384) + sheetPosition];
|
||||||
|
auto lineBits1 =
|
||||||
|
data[(y * 2) + (i * 24) + (j * 384) + 1 + sheetPosition];
|
||||||
|
auto lineBits2 =
|
||||||
|
data[(y) + (i * 24) + (j * 384) + 16 + sheetPosition];
|
||||||
|
|
||||||
|
// Per Pixel X
|
||||||
|
for (int x = 0; x < 4; x++) {
|
||||||
|
auto pixdata = 0;
|
||||||
|
auto pixdata2 = 0;
|
||||||
|
|
||||||
|
if ((lineBits0 & mask[(x * 2)]) == mask[(x * 2)]) {
|
||||||
|
pixdata += 1;
|
||||||
|
}
|
||||||
|
if ((lineBits1 & mask[(x * 2)]) == mask[(x * 2)]) {
|
||||||
|
pixdata += 2;
|
||||||
|
}
|
||||||
|
if ((lineBits2 & mask[(x * 2)]) == mask[(x * 2)]) {
|
||||||
|
pixdata += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((lineBits0 & mask[(x * 2) + 1]) == mask[(x * 2) + 1]) {
|
||||||
|
pixdata2 += 1;
|
||||||
|
}
|
||||||
|
if ((lineBits1 & mask[(x * 2) + 1]) == mask[(x * 2) + 1]) {
|
||||||
|
pixdata2 += 2;
|
||||||
|
}
|
||||||
|
if ((lineBits2 & mask[(x * 2) + 1]) == mask[(x * 2) + 1]) {
|
||||||
|
pixdata2 += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
newData[(y * 64) + (x) + (i * 4) + (j * 512) + (s * 2048)] =
|
||||||
|
((pixdata << 4) | pixdata2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto lineBits0 =
|
||||||
|
data[(y * 2) + (i * 16) + (j * 256) + sheetPosition];
|
||||||
|
auto lineBits1 =
|
||||||
|
data[(y * 2) + (i * 16) + (j * 256) + 1 + sheetPosition];
|
||||||
|
|
||||||
|
// Per Pixel X
|
||||||
|
for (int x = 0; x < 4; x++) {
|
||||||
|
auto pixdata = 0;
|
||||||
|
auto pixdata2 = 0;
|
||||||
|
|
||||||
|
if ((lineBits0 & mask[(x * 2)]) == mask[(x * 2)]) {
|
||||||
|
pixdata += 1;
|
||||||
|
}
|
||||||
|
if ((lineBits1 & mask[(x * 2)]) == mask[(x * 2)]) {
|
||||||
|
pixdata += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((lineBits0 & mask[(x * 2) + 1]) == mask[(x * 2) + 1]) {
|
||||||
|
pixdata2 += 1;
|
||||||
|
}
|
||||||
|
if ((lineBits1 & mask[(x * 2) + 1]) == mask[(x * 2) + 1]) {
|
||||||
|
pixdata2 += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
newData[(y * 64) + (x) + (i * 4) + (j * 512) + (s * 2048)] =
|
||||||
|
((pixdata << 4) | pixdata2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isbpp3[s]) {
|
||||||
|
sheetPosition += 0x600;
|
||||||
|
} else {
|
||||||
|
sheetPosition += 0x800;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics_buffer_.reserve(0x6F800);
|
||||||
|
for (int i = 0; i < 0x6F800; i++) {
|
||||||
|
graphics_buffer_.push_back(newData[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
||||||
@@ -611,11 +771,11 @@ absl::Status ROM::LoadAllGraphicsData() {
|
|||||||
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(i).GetSize(); ++j) {
|
||||||
graphics_buffer_.push_back(graphics_bin_.at(i).GetByte(j));
|
graphics_8bpp_buffer_.push_back(graphics_bin_.at(i).GetByte(j));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int j = 0; j < 0x1000; ++j) {
|
for (int j = 0; j < 0x1000; ++j) {
|
||||||
graphics_buffer_.push_back(0xFF);
|
graphics_8bpp_buffer_.push_back(0xFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ 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 uchar kGraphicsBitmap[8] = {0x80, 0x40, 0x20, 0x10,
|
constexpr uchar kGraphicsBitmap[8] = {0x80, 0x40, 0x20, 0x10,
|
||||||
0x08, 0x04, 0x02, 0x01};
|
0x08, 0x04, 0x02, 0x01};
|
||||||
|
|
||||||
@@ -78,6 +77,10 @@ class ROM {
|
|||||||
absl::StatusOr<Bytes> DecompressOverworld(int pos, int size);
|
absl::StatusOr<Bytes> DecompressOverworld(int pos, int size);
|
||||||
|
|
||||||
absl::Status LoadAllGraphicsData();
|
absl::Status LoadAllGraphicsData();
|
||||||
|
|
||||||
|
absl::StatusOr<Bytes> CreateAllGfxDataRaw();
|
||||||
|
absl::Status CreateAllGraphicsData();
|
||||||
|
|
||||||
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);
|
||||||
absl::Status LoadFromBytes(const Bytes& data);
|
absl::Status LoadFromBytes(const Bytes& data);
|
||||||
@@ -89,6 +92,7 @@ class ROM {
|
|||||||
auto GetTitle() const { return title; }
|
auto GetTitle() const { return title; }
|
||||||
auto GetGraphicsBin() const { return graphics_bin_; }
|
auto GetGraphicsBin() const { return graphics_bin_; }
|
||||||
auto GetGraphicsBuffer() const { return graphics_buffer_; }
|
auto GetGraphicsBuffer() const { return graphics_buffer_; }
|
||||||
|
auto GetGraphics8BPP() const { return graphics_8bpp_buffer_; }
|
||||||
void SetupRenderer(std::shared_ptr<SDL_Renderer> renderer) {
|
void SetupRenderer(std::shared_ptr<SDL_Renderer> renderer) {
|
||||||
renderer_ = renderer;
|
renderer_ = renderer;
|
||||||
}
|
}
|
||||||
@@ -117,10 +121,12 @@ class ROM {
|
|||||||
long size_ = 0;
|
long size_ = 0;
|
||||||
uchar title[21] = "ROM Not Loaded";
|
uchar title[21] = "ROM Not Loaded";
|
||||||
bool is_loaded_ = false;
|
bool is_loaded_ = false;
|
||||||
|
bool isbpp3[223];
|
||||||
std::string filename_;
|
std::string filename_;
|
||||||
|
|
||||||
Bytes rom_data_;
|
Bytes rom_data_;
|
||||||
Bytes graphics_buffer_;
|
Bytes graphics_buffer_;
|
||||||
|
Bytes graphics_8bpp_buffer_;
|
||||||
std::shared_ptr<SDL_Renderer> renderer_;
|
std::shared_ptr<SDL_Renderer> renderer_;
|
||||||
std::unordered_map<int, gfx::Bitmap> graphics_bin_;
|
std::unordered_map<int, gfx::Bitmap> graphics_bin_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ class Overworld {
|
|||||||
int &ttpos);
|
int &ttpos);
|
||||||
absl::Status DecompressAllMapTiles();
|
absl::Status DecompressAllMapTiles();
|
||||||
void FetchLargeMaps();
|
void FetchLargeMaps();
|
||||||
|
void LoadOverworldMap();
|
||||||
|
|
||||||
int game_state_ = 1;
|
int game_state_ = 1;
|
||||||
int current_map_ = 0;
|
int current_map_ = 0;
|
||||||
|
|||||||
@@ -233,26 +233,16 @@ absl::Status OverworldMap::BuildTileset() {
|
|||||||
current_graphics_sheet_set[i] = sheet;
|
current_graphics_sheet_set[i] = sheet;
|
||||||
}
|
}
|
||||||
|
|
||||||
all_gfx_ = rom_.GetGraphicsBuffer();
|
all_gfx_ = rom_.GetGraphics8BPP();
|
||||||
|
|
||||||
current_gfx_.reserve(32768);
|
current_gfx_.reserve(32768);
|
||||||
for (int i = 0; i < 32768; i++) {
|
for (int i = 0; i < 32768; i++) {
|
||||||
current_gfx_.push_back(0x00);
|
current_gfx_.push_back(0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
for (int j = 0; j < 2048; j++) {
|
for (int j = 0; j < 4096; j++) {
|
||||||
auto mapByte = all_gfx_[j + (static_graphics_[i] * 2048)];
|
current_gfx_[(i * 4096) + j] = all_gfx_[j + (static_graphics_[i] * 4096)];
|
||||||
switch (i) {
|
|
||||||
case 0:
|
|
||||||
case 3:
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
mapByte += 0x88;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
current_gfx_[(i * 2048) + j] = mapByte;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
@@ -271,23 +261,7 @@ absl::Status OverworldMap::BuildTiles16Gfx(int count) {
|
|||||||
for (auto i = 0; i < count; i++) {
|
for (auto i = 0; i < count; i++) {
|
||||||
// 8x8 tile draw, gfx8 = 4bpp so everyting is /2F
|
// 8x8 tile draw, gfx8 = 4bpp so everyting is /2F
|
||||||
for (auto tile = 0; tile < 4; tile++) {
|
for (auto tile = 0; tile < 4; tile++) {
|
||||||
gfx::TileInfo info;
|
gfx::TileInfo info = tiles16_[i].tiles_info[tile];
|
||||||
switch (tile) {
|
|
||||||
case 0:
|
|
||||||
info = tiles16_[i].tile0_;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
info = tiles16_[i].tile1_;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
info = tiles16_[i].tile2_;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
info = tiles16_[i].tile3_;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return absl::InternalError("Invalid Tile");
|
|
||||||
}
|
|
||||||
int offset = offsets[tile];
|
int offset = offsets[tile];
|
||||||
|
|
||||||
for (auto y = 0; y < 8; y++) {
|
for (auto y = 0; y < 8; y++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user