Expand all graphics retrieval with bitmap and vram

This commit is contained in:
Justin Scofield
2022-07-17 18:09:12 -04:00
parent 5a62497110
commit 67e1e7ea0c
12 changed files with 165 additions and 115 deletions

View File

@@ -49,7 +49,7 @@ add_executable(
app/core/constants.cc app/core/constants.cc
app/core/controller.cc app/core/controller.cc
app/gfx/bitmap.cc app/gfx/bitmap.cc
app/gfx/psuedo_vram.cc app/gfx/pseudo_vram.cc
app/gfx/snes_tile.cc app/gfx/snes_tile.cc
app/gfx/snes_palette.cc app/gfx/snes_palette.cc
app/zelda3/overworld.cc app/zelda3/overworld.cc

View File

@@ -192,90 +192,7 @@ void OverworldEditor::DrawOverworldMapSettings() {
void OverworldEditor::DrawOverworldCanvas() { void OverworldEditor::DrawOverworldCanvas() {
DrawOverworldMapSettings(); DrawOverworldMapSettings();
ImGui::Separator(); ImGui::Separator();
static ImVector<ImVec2> points; overworld_map_canvas_.Update();
static ImVec2 scrolling(0.0f, 0.0f);
static bool opt_enable_context_menu = true;
static bool adding_line = false;
ImVec2 canvas_p0 = ImGui::GetCursorScreenPos();
ImVec2 canvas_sz = ImGui::GetContentRegionAvail();
auto canvas_p1 = ImVec2(canvas_p0.x + canvas_sz.x, canvas_p0.y + canvas_sz.y);
// Draw border and background color
const ImGuiIO &io = ImGui::GetIO();
ImDrawList *draw_list = ImGui::GetWindowDrawList();
draw_list->AddRectFilled(canvas_p0, canvas_p1, IM_COL32(32, 32, 32, 255));
draw_list->AddRect(canvas_p0, canvas_p1, IM_COL32(255, 255, 255, 255));
// This will catch our interactions
ImGui::InvisibleButton(
"canvas", canvas_sz,
ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight);
const bool is_hovered = ImGui::IsItemHovered(); // Hovered
const bool is_active = ImGui::IsItemActive(); // Held
const ImVec2 origin(canvas_p0.x + scrolling.x,
canvas_p0.y + scrolling.y); // Lock scrolled origin
const ImVec2 mouse_pos_in_canvas(io.MousePos.x - origin.x,
io.MousePos.y - origin.y);
// Add first and second point
if (is_hovered && !adding_line &&
ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
points.push_back(mouse_pos_in_canvas);
points.push_back(mouse_pos_in_canvas);
adding_line = true;
}
if (adding_line) {
points.back() = mouse_pos_in_canvas;
if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) adding_line = false;
}
// Pan (we use a zero mouse threshold when there's no context menu)
const float mouse_threshold_for_pan = opt_enable_context_menu ? -1.0f : 0.0f;
if (is_active &&
ImGui::IsMouseDragging(ImGuiMouseButton_Right, mouse_threshold_for_pan)) {
scrolling.x += io.MouseDelta.x;
scrolling.y += io.MouseDelta.y;
}
// Context menu (under default mouse threshold)
ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right);
if (opt_enable_context_menu && drag_delta.x == 0.0f && drag_delta.y == 0.0f)
ImGui::OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight);
if (ImGui::BeginPopup("context")) {
if (adding_line) points.resize(points.size() - 2);
adding_line = false;
if (ImGui::MenuItem("Remove one", nullptr, false, points.Size > 0)) {
points.resize(points.size() - 2);
}
if (ImGui::MenuItem("Remove all", nullptr, false, points.Size > 0)) {
points.clear();
}
ImGui::EndPopup();
}
// Draw grid + all lines in the canvas
draw_list->PushClipRect(canvas_p0, canvas_p1, true);
if (opt_enable_grid) {
const float GRID_STEP = 64.0f;
for (float x = fmodf(scrolling.x, GRID_STEP); x < canvas_sz.x;
x += GRID_STEP)
draw_list->AddLine(ImVec2(canvas_p0.x + x, canvas_p0.y),
ImVec2(canvas_p0.x + x, canvas_p1.y),
IM_COL32(200, 200, 200, 40));
for (float y = fmodf(scrolling.y, GRID_STEP); y < canvas_sz.y;
y += GRID_STEP)
draw_list->AddLine(ImVec2(canvas_p0.x, canvas_p0.y + y),
ImVec2(canvas_p1.x, canvas_p0.y + y),
IM_COL32(200, 200, 200, 40));
}
for (int n = 0; n < points.Size; n += 2)
draw_list->AddLine(
ImVec2(origin.x + points[n].x, origin.y + points[n].y),
ImVec2(origin.x + points[n + 1].x, origin.y + points[n + 1].y),
IM_COL32(255, 255, 0, 255), 2.0f);
draw_list->PopClipRect();
} }
void OverworldEditor::DrawTileSelector() { void OverworldEditor::DrawTileSelector() {
@@ -300,7 +217,10 @@ void OverworldEditor::DrawTileSelector() {
ImGui::EndChild(); ImGui::EndChild();
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (ImGui::BeginTabItem("VRAM")) {
DrawPseudoVRAM();
ImGui::EndTabItem();
}
ImGui::EndTabBar(); ImGui::EndTabBar();
} }
} }
@@ -392,13 +312,14 @@ void OverworldEditor::DrawTile8Selector() const {
} }
if (all_gfx_loaded_) { if (all_gfx_loaded_) {
for (const auto &[key, value] : all_texture_sheet_) { for (const auto &[key, value] : graphics_bin_) {
int offset = 64 * (key + 1); int offset = 64 * (key + 1);
int top_left_y = canvas_p0.y + 2; int top_left_y = canvas_p0.y + 2;
if (key >= 1) { if (key >= 1) {
top_left_y = canvas_p0.y + 64 * key; top_left_y = canvas_p0.y + 64 * key;
} }
draw_list->AddImage((void *)value, ImVec2(canvas_p0.x + 2, top_left_y), draw_list->AddImage((void *)value.GetTexture(),
ImVec2(canvas_p0.x + 2, top_left_y),
ImVec2(canvas_p0.x + 256, canvas_p0.y + offset)); ImVec2(canvas_p0.x + 256, canvas_p0.y + offset));
} }
} }
@@ -422,12 +343,20 @@ void OverworldEditor::DrawTile8Selector() const {
draw_list->PopClipRect(); draw_list->PopClipRect();
} }
void OverworldEditor::LoadGraphics() { void OverworldEditor::DrawPseudoVRAM() {
for (int i = 0; i < kNumSheetsToLoad; i++) { if (!vram_loaded_ && rom_.isLoaded()) {
all_texture_sheet_[i] = rom_.DrawGraphicsSheet(i); for (int tileset_index = 0; tileset_index < 16; tileset_index++) {
rom_.GetVRAM().GetTileset(tileset_index);
}
pseudo_vram_canvas_.Update();
} }
} }
void OverworldEditor::LoadGraphics() {
rom_.DrawAllGraphicsData();
graphics_bin_ = rom_.GetGraphicsBin();
}
} // namespace editor } // namespace editor
} // namespace app } // namespace app
} // namespace yaze } // namespace yaze

View File

@@ -10,6 +10,7 @@
#include "app/gfx/snes_palette.h" #include "app/gfx/snes_palette.h"
#include "app/gfx/snes_tile.h" #include "app/gfx/snes_tile.h"
#include "app/zelda3/overworld.h" #include "app/zelda3/overworld.h"
#include "gui/canvas.h"
#include "gui/icons.h" #include "gui/icons.h"
namespace yaze { namespace yaze {
@@ -30,6 +31,7 @@ class OverworldEditor {
void DrawTileSelector(); void DrawTileSelector();
void DrawTile16Selector() const; void DrawTile16Selector() const;
void DrawTile8Selector() const; void DrawTile8Selector() const;
void DrawPseudoVRAM();
void LoadBlockset(); void LoadBlockset();
void LoadGraphics(); void LoadGraphics();
@@ -38,6 +40,8 @@ class OverworldEditor {
zelda3::Overworld overworld_; zelda3::Overworld overworld_;
gfx::SNESPalette palette_; gfx::SNESPalette palette_;
gui::Canvas overworld_map_canvas_;
gui::Canvas pseudo_vram_canvas_;
// pointer size 1048576 // pointer size 1048576
gfx::Bitmap tile16_blockset_bmp_; gfx::Bitmap tile16_blockset_bmp_;
@@ -51,6 +55,7 @@ class OverworldEditor {
gfx::Bitmap mapblockset16Bitmap; gfx::Bitmap mapblockset16Bitmap;
std::unordered_map<unsigned int, SDL_Texture *> all_texture_sheet_; std::unordered_map<unsigned int, SDL_Texture *> all_texture_sheet_;
std::unordered_map<unsigned int, gfx::Bitmap> graphics_bin_;
int current_world_ = 0; int current_world_ = 0;
char map_gfx_[3] = ""; char map_gfx_[3] = "";
@@ -64,10 +69,11 @@ class OverworldEditor {
bool opt_enable_grid = true; bool opt_enable_grid = true;
bool all_gfx_loaded_ = false; bool all_gfx_loaded_ = false;
bool map_blockset_loaded_ = false; bool map_blockset_loaded_ = false;
bool vram_loaded_ = false;
constexpr static int kByteSize = 3; constexpr static int kByteSize = 3;
constexpr static int kMessageIdSize = 5; constexpr static int kMessageIdSize = 5;
constexpr static int kNumSheetsToLoad = 100; constexpr static int kNumSheetsToLoad = 223;
constexpr static int kTile8DisplayHeight = 64; constexpr static int kTile8DisplayHeight = 64;
constexpr static float kInputFieldSize = 30.f; constexpr static float kInputFieldSize = 30.f;

View File

@@ -1,4 +1,4 @@
#include "psuedo_vram.h" #include "pseudo_vram.h"
namespace yaze { namespace yaze {
namespace app { namespace app {

View File

@@ -1,5 +1,5 @@
#ifndef YAZE_APP_GFX_PSUEDO_VRAM_H #ifndef YAZE_APP_GFX_PSEUDO_VRAM_H
#define YAZE_APP_GFX_PSUEDO_VRAM_H #define YAZE_APP_GFX_PSEUDO_VRAM_H
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
@@ -21,22 +21,24 @@ namespace gfx {
// Palette: 256 entries; 15-Bit color (BGR555) for a total of 32,768 colors. // Palette: 256 entries; 15-Bit color (BGR555) for a total of 32,768 colors.
// Resolution: between 256x224 and 512x448. // Resolution: between 256x224 and 512x448.
class psuedo_vram { class pseudo_vram {
public: public:
void ChangeGraphicsSet(const std::vector<Bitmap>& graphics_set); void ChangeGraphicsTileset(const std::vector<Bitmap>& graphics_set);
void ChangeGraphicsPalette(const SNESPalette& graphics_pal); void ChangeGraphicsPalette(const SNESPalette& graphics_pal);
void ChangeSpriteSet(const std::vector<Bitmap>& sprite_set); void ChangeSpriteTileset(const std::vector<Bitmap>& sprite_set);
void ChangeSpritePalette(const SNESPalette& sprite_pal); void ChangeSpritePalette(const SNESPalette& sprite_pal);
auto GetTileset(int index) const { return m_vram.at(index); }
private: private:
std::unordered_map<uint32_t, Bitmap> m_vram; std::unordered_map<int, Bitmap> m_vram;
static const uint32_t REAL_VRAM_SIZE = 0x8000; static const uint32_t REAL_VRAM_SIZE = 0x8000;
}; };
std::vector<Bitmap> CreateGraphicsSet( std::vector<Bitmap> CreateGraphicsSet(
int id, const std::unordered_map<uint32_t, Bitmap>& all_graphics); int id, const std::unordered_map<int, Bitmap>& all_graphics);
std::vector<Bitmap> CreateSpriteSet( std::vector<Bitmap> CreateSpriteSet(
int id, const std::unordered_map<uint32_t, Bitmap>& all_graphics); int id, const std::unordered_map<int, Bitmap>& all_graphics);
} // namespace gfx } // namespace gfx
} // namespace app } // namespace app

View File

@@ -239,6 +239,10 @@ void ROM::DrawAllGraphicsData() {
data = Decompress(gfx_addr, core::constants::UncompressedSheetSize); data = Decompress(gfx_addr, core::constants::UncompressedSheetSize);
} }
gfx::Bitmap tilesheet_bmp(128, 32, 8, SNES3bppTo8bppSheet(data));
tilesheet_bmp.CreateTexture(sdl_renderer_);
graphics_bin_[i] = tilesheet_bmp;
for (int j = 0; j < sizeof(data); j++) { for (int j = 0; j < sizeof(data); j++) {
buffer[j + buffer_pos] = data[j]; buffer[j + buffer_pos] = data[j];
} }

View File

@@ -15,6 +15,7 @@
#include "app/core/common.h" #include "app/core/common.h"
#include "app/core/constants.h" #include "app/core/constants.h"
#include "app/gfx/pseudo_vram.h"
#include "app/gfx/snes_tile.h" #include "app/gfx/snes_tile.h"
namespace yaze { namespace yaze {
@@ -28,7 +29,7 @@ class ROM {
void Close(); void Close();
void SetupRenderer(std::shared_ptr<SDL_Renderer> renderer); void SetupRenderer(std::shared_ptr<SDL_Renderer> renderer);
void LoadFromFile(const std::string& path); void LoadFromFile(const std::string& path);
void LoadFromPointer(uchar *data); void LoadFromPointer(uchar* data);
uchar* DecompressGraphics(int pos, int size); uchar* DecompressGraphics(int pos, int size);
uchar* DecompressOverworld(int pos, int size); uchar* DecompressOverworld(int pos, int size);
@@ -43,25 +44,27 @@ class ROM {
gfx::SNESPalette ExtractPalette(uint addr, int bpp); gfx::SNESPalette ExtractPalette(uint addr, int bpp);
uchar* data() { return current_rom_; } uchar* data() { return current_rom_; }
auto Renderer() { return sdl_renderer_; }
const uchar* getTitle() const { return title; } const uchar* getTitle() const { return title; }
long getSize() const { return size_; } long getSize() const { return size_; }
bool isLoaded() const { return is_loaded_; } bool isLoaded() const { return is_loaded_; }
auto Renderer() { return sdl_renderer_; }
auto GetGraphicsBin() const { return graphics_bin_; }
auto GetVRAM() const { return pseudo_vram_; }
private: private:
bool is_loaded_ = false;
int num_sheets_ = 0; int num_sheets_ = 0;
long size_ = 0; long size_ = 0;
uchar* current_rom_; uchar* current_rom_;
uchar title[21] = "ROM Not Loaded"; uchar title[21] = "ROM Not Loaded";
enum rom_type type_ = LoROM; bool is_loaded_ = false;
bool isbpp3[core::constants::NumberOfSheets]; bool isbpp3[core::constants::NumberOfSheets];
enum rom_type type_ = LoROM;
std::shared_ptr<uchar> rom_ptr_; gfx::pseudo_vram pseudo_vram_;
std::vector<uchar*> decompressed_graphic_sheets_; std::vector<uchar*> decompressed_graphic_sheets_;
std::vector<uchar*> converted_graphic_sheets_; std::vector<uchar*> converted_graphic_sheets_;
std::vector<SDL_Surface> surfaces_;
std::shared_ptr<SDL_Renderer> sdl_renderer_; std::shared_ptr<SDL_Renderer> sdl_renderer_;
std::unordered_map<unsigned int, gfx::Bitmap> graphics_bin_;
}; };
} // namespace app } // namespace app

View File

@@ -9,7 +9,7 @@
#include "app/core/constants.h" #include "app/core/constants.h"
#include "app/gfx/bitmap.h" #include "app/gfx/bitmap.h"
#include "app/gfx/psuedo_vram.h" #include "app/gfx/pseudo_vram.h"
#include "app/gfx/snes_tile.h" #include "app/gfx/snes_tile.h"
#include "app/rom.h" #include "app/rom.h"
#include "app/zelda3/overworld_map.h" #include "app/zelda3/overworld_map.h"

View File

@@ -188,7 +188,7 @@ void OverworldMap::CopyTile8bpp16(int x, int y, int tile, uchar* destbmpPtr,
void OverworldMap::CopyTile8bpp16From8(int xP, int yP, int tileID, void OverworldMap::CopyTile8bpp16From8(int xP, int yP, int tileID,
uchar* destbmpPtr, uchar* sourcebmpPtr) { uchar* destbmpPtr, uchar* sourcebmpPtr) {
auto gfx16Data = destbmpPtr; auto gfx16Data = destbmpPtr;
// TODO: PSUEDO VRAM // TODO: PSEUDO VRAM
auto gfx8Data = currentOWgfx16Ptr_; auto gfx8Data = currentOWgfx16Ptr_;
int offsets[] = {0, 8, 4096, 4104}; int offsets[] = {0, 8, 4096, 4104};
@@ -342,7 +342,7 @@ void OverworldMap::BuildTileset(int gameState) {
staticgfx[7] = 91; staticgfx[7] = 91;
} }
// TODO: PSUEDO VRAM DATA HERE // TODO: PSEUDO VRAM DATA HERE
uchar* currentmapgfx8Data = currentOWgfx16Ptr_; uchar* currentmapgfx8Data = currentOWgfx16Ptr_;
// TODO: PUT GRAPHICS DATA HERE // TODO: PUT GRAPHICS DATA HERE
uchar const* allgfxData = allGfx16Ptr_; uchar const* allgfxData = allGfx16Ptr_;

View File

@@ -10,8 +10,10 @@ namespace gui {
void Canvas::Update() { void Canvas::Update() {
ImVec2 canvas_p0 = ImGui::GetCursorScreenPos(); ImVec2 canvas_p0 = ImGui::GetCursorScreenPos();
ImVec2 canvas_sz = ImGui::GetContentRegionAvail(); if (!custom_canvas_size_) canvas_sz_ = ImGui::GetContentRegionAvail();
auto canvas_p1 = ImVec2(canvas_p0.x + canvas_sz.x, canvas_p0.y + canvas_sz.y);
auto canvas_p1 =
ImVec2(canvas_p0.x + canvas_sz_.x, canvas_p0.y + canvas_sz_.y);
// Draw border and background color // Draw border and background color
const ImGuiIO &io = ImGui::GetIO(); const ImGuiIO &io = ImGui::GetIO();
@@ -21,7 +23,7 @@ void Canvas::Update() {
// This will catch our interactions // This will catch our interactions
ImGui::InvisibleButton( ImGui::InvisibleButton(
"canvas", canvas_sz, "canvas", canvas_sz_,
ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight); ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight);
const bool is_hovered = ImGui::IsItemHovered(); // Hovered const bool is_hovered = ImGui::IsItemHovered(); // Hovered
const bool is_active = ImGui::IsItemActive(); // Held const bool is_active = ImGui::IsItemActive(); // Held
@@ -67,12 +69,12 @@ void Canvas::Update() {
draw_list->PushClipRect(canvas_p0, canvas_p1, true); draw_list->PushClipRect(canvas_p0, canvas_p1, true);
if (enable_grid_) { if (enable_grid_) {
const float GRID_STEP = 64.0f; const float GRID_STEP = 64.0f;
for (float x = fmodf(scrolling_.x, GRID_STEP); x < canvas_sz.x; for (float x = fmodf(scrolling_.x, GRID_STEP); x < canvas_sz_.x;
x += GRID_STEP) x += GRID_STEP)
draw_list->AddLine(ImVec2(canvas_p0.x + x, canvas_p0.y), draw_list->AddLine(ImVec2(canvas_p0.x + x, canvas_p0.y),
ImVec2(canvas_p0.x + x, canvas_p1.y), ImVec2(canvas_p0.x + x, canvas_p1.y),
IM_COL32(200, 200, 200, 40)); IM_COL32(200, 200, 200, 40));
for (float y = fmodf(scrolling_.y, GRID_STEP); y < canvas_sz.y; for (float y = fmodf(scrolling_.y, GRID_STEP); y < canvas_sz_.y;
y += GRID_STEP) y += GRID_STEP)
draw_list->AddLine(ImVec2(canvas_p0.x, canvas_p0.y + y), draw_list->AddLine(ImVec2(canvas_p0.x, canvas_p0.y + y),
ImVec2(canvas_p1.x, canvas_p0.y + y), ImVec2(canvas_p1.x, canvas_p0.y + y),
@@ -89,5 +91,95 @@ void Canvas::Update() {
draw_list->PopClipRect(); draw_list->PopClipRect();
} }
void Canvas::DrawBackground() {
canvas_p0_ = ImGui::GetCursorScreenPos();
if (!custom_canvas_size_) canvas_sz_ = ImGui::GetContentRegionAvail();
canvas_p1_ = ImVec2(canvas_p0_.x + canvas_sz_.x, canvas_p0_.y + canvas_sz_.y);
// Draw border and background color
draw_list_ = ImGui::GetWindowDrawList();
draw_list_->AddRectFilled(canvas_p0_, canvas_p1_, IM_COL32(32, 32, 32, 255));
draw_list_->AddRect(canvas_p0_, canvas_p1_, IM_COL32(255, 255, 255, 255));
}
void Canvas::UpdateContext() {
// This will catch our interactions
const ImGuiIO &io = ImGui::GetIO();
ImGui::InvisibleButton(
"canvas", canvas_sz_,
ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight);
const bool is_hovered = ImGui::IsItemHovered(); // Hovered
const bool is_active = ImGui::IsItemActive(); // Held
const ImVec2 origin(canvas_p0_.x + scrolling_.x,
canvas_p0_.y + scrolling_.y); // Lock scrolled origin
const ImVec2 mouse_pos_in_canvas(io.MousePos.x - origin.x,
io.MousePos.y - origin.y);
// Add first and second point
if (is_hovered && !dragging_select_ &&
ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
points_.push_back(mouse_pos_in_canvas);
points_.push_back(mouse_pos_in_canvas);
dragging_select_ = true;
}
if (dragging_select_) {
points_.back() = mouse_pos_in_canvas;
if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) dragging_select_ = false;
}
// Pan (we use a zero mouse threshold when there's no context menu)
const float mouse_threshold_for_pan = enable_context_menu_ ? -1.0f : 0.0f;
if (is_active &&
ImGui::IsMouseDragging(ImGuiMouseButton_Right, mouse_threshold_for_pan)) {
scrolling_.x += io.MouseDelta.x;
scrolling_.y += io.MouseDelta.y;
}
// Context menu (under default mouse threshold)
ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right);
if (enable_context_menu_ && drag_delta.x == 0.0f && drag_delta.y == 0.0f)
ImGui::OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight);
if (ImGui::BeginPopup("context")) {
if (dragging_select_) points_.resize(points_.size() - 2);
dragging_select_ = false;
if (ImGui::MenuItem("Remove all", nullptr, false, points_.Size > 0)) {
points_.clear();
}
ImGui::EndPopup();
}
}
void Canvas::DrawGrid() {
// Draw grid + all lines in the canvas
draw_list_->PushClipRect(canvas_p0_, canvas_p1_, true);
if (enable_grid_) {
const float GRID_STEP = 64.0f;
for (float x = fmodf(scrolling_.x, GRID_STEP); x < canvas_sz_.x;
x += GRID_STEP)
draw_list_->AddLine(ImVec2(canvas_p0_.x + x, canvas_p0_.y),
ImVec2(canvas_p0_.x + x, canvas_p1_.y),
IM_COL32(200, 200, 200, 40));
for (float y = fmodf(scrolling_.y, GRID_STEP); y < canvas_sz_.y;
y += GRID_STEP)
draw_list_->AddLine(ImVec2(canvas_p0_.x, canvas_p0_.y + y),
ImVec2(canvas_p1_.x, canvas_p0_.y + y),
IM_COL32(200, 200, 200, 40));
}
}
void Canvas::DrawOverlay() {
const ImVec2 origin(canvas_p0_.x + scrolling_.x,
canvas_p0_.y + scrolling_.y); // Lock scrolled origin
for (int n = 0; n < points_.Size; n += 2) {
draw_list_->AddRect(
ImVec2(origin.x + points_[n].x, origin.y + points_[n].y),
ImVec2(origin.x + points_[n + 1].x, origin.y + points_[n + 1].y),
IM_COL32(255, 255, 255, 255), 1.0f);
}
draw_list_->PopClipRect();
}
} // namespace gui } // namespace gui
} // namespace yaze } // namespace yaze

View File

@@ -4,6 +4,7 @@
#include <imgui/imgui.h> #include <imgui/imgui.h>
#include <cmath> #include <cmath>
#include <memory>
#include <string> #include <string>
namespace yaze { namespace yaze {
@@ -11,18 +12,30 @@ namespace gui {
class Canvas { class Canvas {
public: public:
Canvas() = default; Canvas() = default;
Canvas(ImVec2 canvas_size)
: canvas_sz_(canvas_size), custom_canvas_size_(true) {}
void Update(); void Update();
void DrawBackground();
void UpdateContext();
void DrawGrid();
void DrawOverlay(); // last
private: private:
bool enable_grid_ = true; bool enable_grid_ = true;
bool enable_context_menu_ = true; bool enable_context_menu_ = true;
bool dragging_select_ = false; bool dragging_select_ = false;
bool custom_canvas_size_ = false;
std::string title_; std::string title_;
ImDrawList* draw_list_;
ImVector<ImVec2> points_; ImVector<ImVec2> points_;
ImVec2 scrolling_; ImVec2 scrolling_;
ImVec2 canvas_sz_;
ImVec2 canvas_p0_;
ImVec2 canvas_p1_;
}; };
} // namespace gui } // namespace gui
} // namespace yaze } // namespace yaze

View File

@@ -19,6 +19,7 @@ add_executable(
yaze_test.cc yaze_test.cc
rom_test.cc rom_test.cc
../src/app/rom.cc ../src/app/rom.cc
../src/app/gfx/bitmap.cc
../src/app/gfx/snes_tile.cc ../src/app/gfx/snes_tile.cc
../src/app/gfx/snes_palette.cc ../src/app/gfx/snes_palette.cc
../src/app/core/common.cc ../src/app/core/common.cc