GUI Improvements with fonts and some underlying palette and bitmap code stuff
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1 +1,3 @@
|
|||||||
build/
|
build/
|
||||||
|
.cache/
|
||||||
|
.vscode/
|
||||||
BIN
assets/Fonts/Cousine-Regular.ttf
Normal file
BIN
assets/Fonts/Cousine-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/Fonts/DroidSans.ttf
Normal file
BIN
assets/Fonts/DroidSans.ttf
Normal file
Binary file not shown.
BIN
assets/Fonts/Karla-Regular.ttf
Normal file
BIN
assets/Fonts/Karla-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/Fonts/MaterialIcons-Regular.ttf
Normal file
BIN
assets/Fonts/MaterialIcons-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/Fonts/Roboto-Medium.ttf
Normal file
BIN
assets/Fonts/Roboto-Medium.ttf
Normal file
Binary file not shown.
@@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "Editor/Editor.h"
|
||||||
#include "Events/Event.h"
|
#include "Events/Event.h"
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "Editor/Editor.h"
|
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
#include "imgui/backends/imgui_impl_sdl.h"
|
#include "imgui/backends/imgui_impl_sdl.h"
|
||||||
#include "imgui/backends/imgui_impl_sdlrenderer.h"
|
#include "imgui/backends/imgui_impl_sdlrenderer.h"
|
||||||
@@ -37,7 +37,7 @@ class Controller {
|
|||||||
private:
|
private:
|
||||||
Window window;
|
Window window;
|
||||||
Renderer renderer;
|
Renderer renderer;
|
||||||
View::Editor editor;
|
Editor::Editor editor;
|
||||||
bool active = false;
|
bool active = false;
|
||||||
void quit() { active = false; }
|
void quit() { active = false; }
|
||||||
friend int ::main(int argc, char** argv);
|
friend int ::main(int argc, char** argv);
|
||||||
|
|||||||
2192
src/Application/Core/Icons.h
Normal file
2192
src/Application/Core/Icons.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -22,11 +22,31 @@ void Renderer::Create(SDL_Window* window) {
|
|||||||
|
|
||||||
// Create the ImGui and ImPlot contexts
|
// Create the ImGui and ImPlot contexts
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
|
|
||||||
// Initialize ImGui for SDL
|
// Initialize ImGui for SDL
|
||||||
ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
|
ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
|
||||||
ImGui_ImplSDLRenderer_Init(renderer);
|
ImGui_ImplSDLRenderer_Init(renderer);
|
||||||
|
|
||||||
|
// Load available fonts
|
||||||
|
const ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.Fonts->AddFontFromFileTTF("assets/Fonts/Karla-Regular.ttf", 14.0f);
|
||||||
|
|
||||||
|
// merge in icons from Google Material Design
|
||||||
|
static const ImWchar icons_ranges[] = {ICON_MIN_MD, 0xf900, 0};
|
||||||
|
ImFontConfig icons_config;
|
||||||
|
icons_config.MergeMode = true;
|
||||||
|
icons_config.GlyphOffset.y = 5.0f;
|
||||||
|
icons_config.GlyphMinAdvanceX = 13.0f;
|
||||||
|
icons_config.PixelSnapH = true;
|
||||||
|
io.Fonts->AddFontFromFileTTF(FONT_ICON_FILE_NAME_MD, 18.0f, &icons_config,
|
||||||
|
icons_ranges);
|
||||||
|
io.Fonts->AddFontFromFileTTF("assets/Fonts/Roboto-Medium.ttf", 14.0f);
|
||||||
|
io.Fonts->AddFontFromFileTTF("assets/Fonts/Cousine-Regular.ttf", 14.0f);
|
||||||
|
io.Fonts->AddFontFromFileTTF("assets/Fonts/DroidSans.ttf", 16.0f);
|
||||||
|
|
||||||
|
|
||||||
|
Style::StyleColorsYaze();
|
||||||
|
|
||||||
// Build a new ImGui frame
|
// Build a new ImGui frame
|
||||||
ImGui_ImplSDLRenderer_NewFrame();
|
ImGui_ImplSDLRenderer_NewFrame();
|
||||||
ImGui_ImplSDL2_NewFrame(window);
|
ImGui_ImplSDL2_NewFrame(window);
|
||||||
@@ -44,7 +64,6 @@ void Renderer::Destroy() {
|
|||||||
renderer = nullptr;
|
renderer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
} // namespace Application
|
} // namespace Application
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
@@ -3,25 +3,27 @@
|
|||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
#include "imgui/imgui.h"
|
#include "Icons.h"
|
||||||
#include "imgui/imgui_internal.h"
|
#include "Style.h"
|
||||||
#include "imgui/backends/imgui_impl_sdl.h"
|
#include "imgui/backends/imgui_impl_sdl.h"
|
||||||
#include "imgui/backends/imgui_impl_sdlrenderer.h"
|
#include "imgui/backends/imgui_impl_sdlrenderer.h"
|
||||||
|
#include "imgui/imgui.h"
|
||||||
|
#include "imgui/imgui_internal.h"
|
||||||
#include "imgui/misc/cpp/imgui_stdlib.h"
|
#include "imgui/misc/cpp/imgui_stdlib.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace Application {
|
namespace Application {
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
class Renderer {
|
class Renderer {
|
||||||
public:
|
public:
|
||||||
void Create(SDL_Window* window);
|
void Create(SDL_Window* window);
|
||||||
void Render();
|
void Render();
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_Renderer* renderer = nullptr;
|
SDL_Renderer* renderer = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
} // namespace Application
|
} // namespace Application
|
||||||
|
|||||||
120
src/Application/Core/Style.h
Normal file
120
src/Application/Core/Style.h
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
#ifndef YAZE_APPLICATION_CORE_STYLE_H
|
||||||
|
#define YAZE_APPLCIATION_CORE_STYLE_H
|
||||||
|
|
||||||
|
#include "imgui/imgui.h"
|
||||||
|
#include "imgui/imgui_internal.h"
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace Application {
|
||||||
|
namespace Core {
|
||||||
|
namespace Style {
|
||||||
|
|
||||||
|
inline static void StyleColorsYaze() {
|
||||||
|
ImGuiStyle *style = &ImGui::GetStyle();
|
||||||
|
ImVec4 *colors = style->Colors;
|
||||||
|
|
||||||
|
style->WindowPadding = ImVec2(10.f, 10.f);
|
||||||
|
style->FramePadding = ImVec2(10.f, 3.f);
|
||||||
|
style->CellPadding = ImVec2(4.f, 5.f);
|
||||||
|
style->ItemSpacing = ImVec2(10.f, 5.f);
|
||||||
|
style->ItemInnerSpacing = ImVec2(5.f, 5.f);
|
||||||
|
style->TouchExtraPadding = ImVec2(0.f, 0.f);
|
||||||
|
style->IndentSpacing = 20.f;
|
||||||
|
style->ScrollbarSize = 14.f;
|
||||||
|
style->GrabMinSize = 15.f;
|
||||||
|
|
||||||
|
style->WindowBorderSize = 0.f;
|
||||||
|
style->ChildBorderSize = 1.f;
|
||||||
|
style->PopupBorderSize = 1.f;
|
||||||
|
style->FrameBorderSize = 0.f;
|
||||||
|
style->TabBorderSize = 0.f;
|
||||||
|
|
||||||
|
style->WindowRounding = 0.f;
|
||||||
|
style->ChildRounding = 0.f;
|
||||||
|
style->FrameRounding = 5.4;
|
||||||
|
style->PopupRounding = 0.f;
|
||||||
|
style->ScrollbarRounding = 5.f;
|
||||||
|
|
||||||
|
ImVec4 alttpDarkGreen = ImVec4(0.18f, 0.26f, 0.18f, 1.0f);
|
||||||
|
ImVec4 alttpMidGreen = ImVec4(0.28f, 0.36f, 0.28f, 1.0f);
|
||||||
|
ImVec4 allttpLightGreen = ImVec4(0.36f, 0.45f, 0.36f, 1.0f);
|
||||||
|
ImVec4 allttpLightestGreen = ImVec4(0.49f, 0.57f, 0.49f, 1.0f);
|
||||||
|
|
||||||
|
ImVec4 alttpBlue = ImVec4(0.f, 0.f, 0.47f, 1.0f);
|
||||||
|
ImVec4 alttpBlueHover = ImVec4(0.f, 0.f, 0.57f, 1.0f);
|
||||||
|
ImVec4 alttpBlueActive = ImVec4(0.f, 0.f, 0.67f, 1.0f);
|
||||||
|
|
||||||
|
colors[ImGuiCol_MenuBarBg] = alttpDarkGreen;
|
||||||
|
colors[ImGuiCol_TitleBg] = alttpMidGreen;
|
||||||
|
|
||||||
|
colors[ImGuiCol_Header] = alttpDarkGreen;
|
||||||
|
colors[ImGuiCol_HeaderHovered] = allttpLightGreen;
|
||||||
|
colors[ImGuiCol_HeaderActive] = alttpMidGreen;
|
||||||
|
|
||||||
|
colors[ImGuiCol_TitleBgActive] = alttpDarkGreen;
|
||||||
|
colors[ImGuiCol_TitleBgCollapsed] = alttpMidGreen;
|
||||||
|
|
||||||
|
colors[ImGuiCol_Tab] = alttpDarkGreen;
|
||||||
|
colors[ImGuiCol_TabHovered] = alttpMidGreen;
|
||||||
|
colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive],
|
||||||
|
colors[ImGuiCol_TitleBgActive], 0.60f);
|
||||||
|
|
||||||
|
colors[ImGuiCol_Button] = alttpMidGreen;
|
||||||
|
colors[ImGuiCol_ButtonHovered] = allttpLightestGreen;
|
||||||
|
colors[ImGuiCol_ButtonActive] = allttpLightGreen;
|
||||||
|
|
||||||
|
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f);
|
||||||
|
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.36f, 0.45f, 0.36f, 0.30f);
|
||||||
|
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.36f, 0.45f, 0.36f, 0.40f);
|
||||||
|
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f);
|
||||||
|
|
||||||
|
colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f);
|
||||||
|
colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f);
|
||||||
|
colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.85f);
|
||||||
|
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||||
|
colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.14f, 0.92f);
|
||||||
|
colors[ImGuiCol_Border] = allttpLightGreen;
|
||||||
|
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||||
|
|
||||||
|
colors[ImGuiCol_FrameBg] = ImVec4(0.43f, 0.43f, 0.43f, 0.39f);
|
||||||
|
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.28f, 0.36f, 0.28f, 0.40f);
|
||||||
|
colors[ImGuiCol_FrameBgActive] = ImVec4(0.28f, 0.36f, 0.28f, 0.69f);
|
||||||
|
|
||||||
|
colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f);
|
||||||
|
colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f);
|
||||||
|
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f);
|
||||||
|
|
||||||
|
colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 0.60f);
|
||||||
|
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f);
|
||||||
|
colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f);
|
||||||
|
colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f);
|
||||||
|
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f);
|
||||||
|
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f);
|
||||||
|
|
||||||
|
colors[ImGuiCol_TabUnfocused] =
|
||||||
|
ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
|
||||||
|
colors[ImGuiCol_TabUnfocusedActive] =
|
||||||
|
ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f);
|
||||||
|
colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_TableHeaderBg] = alttpDarkGreen;
|
||||||
|
colors[ImGuiCol_TableBorderStrong] = alttpMidGreen;
|
||||||
|
colors[ImGuiCol_TableBorderLight] =
|
||||||
|
ImVec4(0.26f, 0.26f, 0.28f, 1.00f); // Prefer using Alpha=1.0 here
|
||||||
|
colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||||
|
colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.07f);
|
||||||
|
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f);
|
||||||
|
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
|
||||||
|
colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered];
|
||||||
|
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
|
||||||
|
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
|
||||||
|
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
|
||||||
|
}
|
||||||
|
} // namespace Style
|
||||||
|
} // namespace Core
|
||||||
|
} // namespace Application
|
||||||
|
} // namespace yaze
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -12,8 +12,8 @@ void Window::Create() {
|
|||||||
window = SDL_CreateWindow("Yet Another Zelda3 Editor", // window title
|
window = SDL_CreateWindow("Yet Another Zelda3 Editor", // window title
|
||||||
SDL_WINDOWPOS_UNDEFINED, // initial x position
|
SDL_WINDOWPOS_UNDEFINED, // initial x position
|
||||||
SDL_WINDOWPOS_UNDEFINED, // initial y position
|
SDL_WINDOWPOS_UNDEFINED, // initial y position
|
||||||
800, // width, in pixels
|
1200, // width, in pixels
|
||||||
600, // height, in pixels
|
800, // height, in pixels
|
||||||
SDL_WINDOW_RESIZABLE // window flags
|
SDL_WINDOW_RESIZABLE // window flags
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace Application {
|
namespace Application {
|
||||||
namespace View {
|
namespace Editor {
|
||||||
|
|
||||||
void Editor::UpdateScreen() {
|
void Editor::UpdateScreen() {
|
||||||
const ImGuiIO& io = ImGui::GetIO();
|
const ImGuiIO &io = ImGui::GetIO();
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
ImGui::SetNextWindowPos(ImVec2(0, 0));
|
ImGui::SetNextWindowPos(ImVec2(0, 0));
|
||||||
ImVec2 dimensions(io.DisplaySize.x, io.DisplaySize.y);
|
ImVec2 dimensions(io.DisplaySize.x, io.DisplaySize.y);
|
||||||
@@ -13,12 +13,13 @@ void Editor::UpdateScreen() {
|
|||||||
ImGuiWindowFlags flags =
|
ImGuiWindowFlags flags =
|
||||||
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse |
|
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse |
|
||||||
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoScrollbar |
|
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoScrollbar |
|
||||||
ImGuiWindowFlags_MenuBar;
|
ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoTitleBar;
|
||||||
|
|
||||||
if (!ImGui::Begin("Main", nullptr, flags)) {
|
if (!ImGui::Begin("#yaze", nullptr, flags)) {
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawYazeMenu();
|
DrawYazeMenu();
|
||||||
|
|
||||||
if (isLoaded) {
|
if (isLoaded) {
|
||||||
@@ -35,6 +36,7 @@ void Editor::UpdateScreen() {
|
|||||||
if (ImGui::BeginTabBar("##TabBar")) {
|
if (ImGui::BeginTabBar("##TabBar")) {
|
||||||
DrawOverworldEditor();
|
DrawOverworldEditor();
|
||||||
DrawDungeonEditor();
|
DrawDungeonEditor();
|
||||||
|
DrawScreenEditor();
|
||||||
DrawROMInfo();
|
DrawROMInfo();
|
||||||
ImGui::EndTabBar();
|
ImGui::EndTabBar();
|
||||||
}
|
}
|
||||||
@@ -45,15 +47,9 @@ void Editor::UpdateScreen() {
|
|||||||
|
|
||||||
void Editor::DrawYazeMenu() {
|
void Editor::DrawYazeMenu() {
|
||||||
if (ImGui::BeginMenuBar()) {
|
if (ImGui::BeginMenuBar()) {
|
||||||
if (ImGui::BeginMenu("File")) {
|
DrawFileMenu();
|
||||||
DrawFileMenu();
|
DrawEditMenu();
|
||||||
ImGui::EndMenu();
|
DrawViewMenu();
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Edit")) {
|
|
||||||
DrawEditMenu();
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
ImGui::EndMenuBar();
|
ImGui::EndMenuBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,180 +69,174 @@ void Editor::DrawYazeMenu() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Editor::DrawFileMenu() const {
|
void Editor::DrawFileMenu() const {
|
||||||
if (ImGui::MenuItem("Open", "Ctrl+O")) {
|
if (ImGui::BeginMenu("File")) {
|
||||||
// TODO: Add the ability to open ALTTP ROM
|
if (ImGui::MenuItem("Open", "Ctrl+O")) {
|
||||||
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Open ROM",
|
// TODO: Add the ability to open ALTTP ROM
|
||||||
".sfc,.smc", ".");
|
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Open ROM",
|
||||||
}
|
".sfc,.smc", ".");
|
||||||
if (ImGui::BeginMenu("Open Recent")) {
|
}
|
||||||
ImGui::MenuItem("alttp.sfc");
|
if (ImGui::BeginMenu("Open Recent")) {
|
||||||
// TODO: Display recently accessed files here
|
ImGui::MenuItem("alttp.sfc");
|
||||||
ImGui::EndMenu();
|
// TODO: Display recently accessed files here
|
||||||
}
|
ImGui::EndMenu();
|
||||||
if (ImGui::MenuItem("Save", "Ctrl+S")) {
|
}
|
||||||
// TODO: Implement this
|
if (ImGui::MenuItem("Save", "Ctrl+S")) {
|
||||||
}
|
// TODO: Implement this
|
||||||
if (ImGui::MenuItem("Save As..")) {
|
}
|
||||||
// TODO: Implement this
|
if (ImGui::MenuItem("Save As..")) {
|
||||||
}
|
// TODO: Implement this
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
// TODO: Make these options matter
|
// TODO: Make these options matter
|
||||||
if (ImGui::BeginMenu("Options")) {
|
if (ImGui::BeginMenu("Options")) {
|
||||||
static bool enabled = true;
|
static bool enabled = true;
|
||||||
ImGui::MenuItem("Enabled", "", &enabled);
|
ImGui::MenuItem("Enabled", "", &enabled);
|
||||||
ImGui::BeginChild("child", ImVec2(0, 60), true);
|
ImGui::BeginChild("child", ImVec2(0, 60), true);
|
||||||
for (int i = 0; i < 10; i++) ImGui::Text("Scrolling Text %d", i);
|
for (int i = 0; i < 10; i++)
|
||||||
ImGui::EndChild();
|
ImGui::Text("Scrolling Text %d", i);
|
||||||
static float f = 0.5f;
|
ImGui::EndChild();
|
||||||
static int n = 0;
|
static float f = 0.5f;
|
||||||
ImGui::SliderFloat("Value", &f, 0.0f, 1.0f);
|
static int n = 0;
|
||||||
ImGui::InputFloat("Input", &f, 0.1f);
|
ImGui::SliderFloat("Value", &f, 0.0f, 1.0f);
|
||||||
ImGui::Combo("Combo", &n, "Yes\0No\0Maybe\0\0");
|
ImGui::InputFloat("Input", &f, 0.1f);
|
||||||
|
ImGui::Combo("Combo", &n, "Yes\0No\0Maybe\0\0");
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::DrawEditMenu() const {
|
void Editor::DrawEditMenu() const {
|
||||||
if (ImGui::MenuItem("Undo", "Ctrl+O")) {
|
if (ImGui::BeginMenu("Edit")) {
|
||||||
// TODO: Implement this
|
if (ImGui::MenuItem("Undo", "Ctrl+Z")) {
|
||||||
|
// TODO: Implement this
|
||||||
|
}
|
||||||
|
if (ImGui::MenuItem("Undo", "Ctrl+Y")) {
|
||||||
|
// TODO: Implement this
|
||||||
|
}
|
||||||
|
ImGui::Separator();
|
||||||
|
if (ImGui::MenuItem("Cut", "Ctrl+X")) {
|
||||||
|
// TODO: Implement this
|
||||||
|
}
|
||||||
|
if (ImGui::MenuItem("Copy", "Ctrl+C")) {
|
||||||
|
// TODO: Implement this
|
||||||
|
}
|
||||||
|
if (ImGui::MenuItem("Paste", "Ctrl+V")) {
|
||||||
|
// TODO: Implement this
|
||||||
|
}
|
||||||
|
ImGui::Separator();
|
||||||
|
if (ImGui::MenuItem("Find", "Ctrl+F")) {
|
||||||
|
// TODO: Implement this
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
if (ImGui::MenuItem("Undo", "Ctrl+O")) {
|
}
|
||||||
// TODO: Implement this
|
|
||||||
|
void Editor::DrawViewMenu() const {
|
||||||
|
static bool show_imgui_metrics = false;
|
||||||
|
static bool show_imgui_style_editor = false;
|
||||||
|
if (show_imgui_metrics) {
|
||||||
|
ImGui::ShowMetricsWindow(&show_imgui_metrics);
|
||||||
}
|
}
|
||||||
ImGui::Separator();
|
|
||||||
if (ImGui::MenuItem("Cut", "Ctrl+X")) {
|
if (show_imgui_style_editor) {
|
||||||
// TODO: Implement this
|
ImGui::Begin("Style Editor (ImGui)", &show_imgui_style_editor);
|
||||||
|
ImGui::ShowStyleEditor();
|
||||||
|
ImGui::End();
|
||||||
}
|
}
|
||||||
if (ImGui::MenuItem("Copy", "Ctrl+C")) {
|
|
||||||
// TODO: Implement this
|
if (ImGui::BeginMenu("View")) {
|
||||||
}
|
if (ImGui::BeginMenu("Appearance")) {
|
||||||
if (ImGui::MenuItem("Paste", "Ctrl+V")) {
|
if (ImGui::MenuItem("Fullscreen")) {
|
||||||
// TODO: Implement this
|
}
|
||||||
}
|
ImGui::EndMenu();
|
||||||
ImGui::Separator();
|
}
|
||||||
if (ImGui::MenuItem("Find Tiles", "Ctrl+F")) {
|
|
||||||
// TODO: Implement this
|
ImGui::Separator();
|
||||||
|
if (ImGui::BeginMenu("GUI Tools")) {
|
||||||
|
ImGui::MenuItem("Metrics (ImGui)", nullptr, &show_imgui_metrics);
|
||||||
|
ImGui::MenuItem("Style Editor (ImGui)", nullptr,
|
||||||
|
&show_imgui_style_editor);
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// first step would be to decompress all graphics data from the game
|
// first step would be to decompress all graphics data from the game
|
||||||
// (in alttp that's easy they're all located in the same location all the same
|
// (in alttp that's easy they're all located in the same location all the
|
||||||
// sheet size 128x32) have a code that convert PC address to SNES and vice-versa
|
// same sheet size 128x32) have a code that convert PC address to SNES and
|
||||||
|
// vice-versa
|
||||||
|
|
||||||
// 1) find the gfx pointers (you could use ZS constant file)
|
// 1) find the gfx pointers (you could use ZS constant file)
|
||||||
// 2) decompress all the gfx with your lz2 decompressor
|
// 2) decompress all the gfx with your lz2 decompressor
|
||||||
// 3) convert the 3bpp snes data into PC 4bpp (probably the hardest part)
|
// 3) convert the 3bpp snes data into PC 4bpp (probably the hardest part)
|
||||||
// 4) get the tiles32 data
|
// 4) get the tiles32 data
|
||||||
// 5) get the tiles16 data
|
// 5) get the tiles16 data
|
||||||
// 6) get the map32 data (they must be decompressed as well with a lz2 variant
|
// 6) get the map32 data (they must be decompressed as well with a lz2
|
||||||
// not the same as gfx compression but pretty similar)
|
// variant not the same as gfx compression but pretty similar) 7) get the
|
||||||
// 7) get the gfx data of the map
|
// gfx data of the map yeah i forgot that one and load 4bpp in a pseudo vram
|
||||||
// yeah i forgot that one and load 4bpp in a pseudo vram and use that to
|
// and use that to render tiles on screen 8) try to render the tiles on the
|
||||||
// render tiles on screen
|
// bitmap in black & white to start 9) get the palettes data and try to find
|
||||||
// 8) try to render the tiles on the bitmap in black & white to start
|
// how they're loaded in the game that's a big puzzle to solve then 9 you'll
|
||||||
// 9) get the palettes data and try to find how they're loaded in
|
// have an overworld map viewer, in less than few hours if are able to
|
||||||
// the game that's a big puzzle to solve then 9 you'll have an overworld map
|
// understand the data quickly
|
||||||
// viewer, in less than few hours if are able to understand the data quickly
|
|
||||||
void Editor::DrawOverworldEditor() {
|
void Editor::DrawOverworldEditor() {
|
||||||
if (ImGui::BeginTabItem("Overworld")) {
|
if (ImGui::BeginTabItem("Overworld")) {
|
||||||
static ImVector<ImVec2> points;
|
owEditor.Update();
|
||||||
static ImVec2 scrolling(0.0f, 0.0f);
|
|
||||||
static bool opt_enable_grid = true;
|
|
||||||
static bool opt_enable_context_menu = true;
|
|
||||||
static bool adding_line = false;
|
|
||||||
|
|
||||||
ImGui::Checkbox("Enable grid", &opt_enable_grid);
|
|
||||||
|
|
||||||
ImVec2 canvas_p0 = ImGui::GetCursorScreenPos();
|
|
||||||
ImVec2 canvas_sz = ImGui::GetContentRegionAvail();
|
|
||||||
ImVec2 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(50, 50, 50, 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", NULL, false, points.Size > 0)) {
|
|
||||||
points.resize(points.size() - 2);
|
|
||||||
}
|
|
||||||
if (ImGui::MenuItem("Remove all", NULL, 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();
|
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void DrawDungeonEditor() {
|
|
||||||
|
void Editor::DrawDungeonEditor() {
|
||||||
if (ImGui::BeginTabItem("Dungeon")) {
|
if (ImGui::BeginTabItem("Dungeon")) {
|
||||||
|
if (ImGui::BeginTable("DWToolset", 9, toolset_table_flags, ImVec2(0, 0))) {
|
||||||
|
ImGui::TableSetupColumn("#undoTool");
|
||||||
|
ImGui::TableSetupColumn("#redoTool");
|
||||||
|
ImGui::TableSetupColumn("#history");
|
||||||
|
ImGui::TableSetupColumn("#separator");
|
||||||
|
ImGui::TableSetupColumn("#bg1Tool");
|
||||||
|
ImGui::TableSetupColumn("#bg2Tool");
|
||||||
|
ImGui::TableSetupColumn("#bg3Tool");
|
||||||
|
ImGui::TableSetupColumn("#itemTool");
|
||||||
|
ImGui::TableSetupColumn("#spriteTool");
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_UNDO);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_REDO);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_MANAGE_HISTORY);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text(ICON_MD_MORE_VERT);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_FILTER_1);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_FILTER_2);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_FILTER_3);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_GRASS);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_PEST_CONTROL_RODENT);
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::DrawScreenEditor() {
|
||||||
|
if (ImGui::BeginTabItem("Screens")) {
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -263,6 +253,6 @@ void Editor::DrawROMInfo() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace View
|
} // namespace Editor
|
||||||
} // namespace Application
|
} // namespace Application
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
@@ -3,7 +3,9 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "Core/Icons.h"
|
||||||
#include "Data/Overworld.h"
|
#include "Data/Overworld.h"
|
||||||
|
#include "OverworldEditor.h"
|
||||||
#include "ImGuiFileDialog/ImGuiFileDialog.h"
|
#include "ImGuiFileDialog/ImGuiFileDialog.h"
|
||||||
#include "Utils/ROM.h"
|
#include "Utils/ROM.h"
|
||||||
#include "imgui/backends/imgui_impl_sdl.h"
|
#include "imgui/backends/imgui_impl_sdl.h"
|
||||||
@@ -14,7 +16,7 @@
|
|||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace Application {
|
namespace Application {
|
||||||
namespace View {
|
namespace Editor {
|
||||||
|
|
||||||
class Editor {
|
class Editor {
|
||||||
public:
|
public:
|
||||||
@@ -24,16 +26,22 @@ class Editor {
|
|||||||
void DrawYazeMenu();
|
void DrawYazeMenu();
|
||||||
void DrawFileMenu() const;
|
void DrawFileMenu() const;
|
||||||
void DrawEditMenu() const;
|
void DrawEditMenu() const;
|
||||||
|
void DrawViewMenu() const;
|
||||||
|
|
||||||
void DrawOverworldEditor();
|
void DrawOverworldEditor();
|
||||||
void DrawDungeonEditor();
|
void DrawDungeonEditor();
|
||||||
|
void DrawScreenEditor();
|
||||||
void DrawROMInfo();
|
void DrawROMInfo();
|
||||||
|
|
||||||
bool isLoaded = false;
|
bool isLoaded = false;
|
||||||
bool doneLoaded = false;
|
bool doneLoaded = false;
|
||||||
GLuint *overworld_texture;
|
GLuint *overworld_texture;
|
||||||
Data::Overworld overworld;
|
Data::Overworld overworld;
|
||||||
|
::yaze::Application::Editor::OverworldEditor owEditor;
|
||||||
Utils::ROM rom;
|
Utils::ROM rom;
|
||||||
|
|
||||||
|
|
||||||
|
ImGuiTableFlags toolset_table_flags = ImGuiTableFlags_SizingFixedFit;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace View
|
} // namespace View
|
||||||
|
|||||||
239
src/Application/Editor/OverworldEditor.cc
Normal file
239
src/Application/Editor/OverworldEditor.cc
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
#include "OverworldEditor.h"
|
||||||
|
#include "Core/Icons.h"
|
||||||
|
#include "imgui.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace Application {
|
||||||
|
namespace Editor {
|
||||||
|
void OverworldEditor::Update() {
|
||||||
|
DrawToolset();
|
||||||
|
ImGui::Separator();
|
||||||
|
if (ImGui::BeginTable("#owEditTable", 2, ow_edit_flags, ImVec2(0, 0))) {
|
||||||
|
ImGui::TableSetupColumn("#overworldCanvas");
|
||||||
|
ImGui::TableSetupColumn("#tileSelector");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
DrawOverworldCanvas();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
DrawTileSelector();
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverworldEditor::DrawToolset() {
|
||||||
|
if (ImGui::BeginTable("Toolset", 12, toolset_table_flags, ImVec2(0, 0))) {
|
||||||
|
|
||||||
|
ImGui::TableSetupColumn("#undoTool");
|
||||||
|
ImGui::TableSetupColumn("#redoTool");
|
||||||
|
ImGui::TableSetupColumn("#drawTool");
|
||||||
|
ImGui::TableSetupColumn("#separator2");
|
||||||
|
ImGui::TableSetupColumn("#zoomOutTool");
|
||||||
|
ImGui::TableSetupColumn("#zoomInTool");
|
||||||
|
ImGui::TableSetupColumn("#separator");
|
||||||
|
ImGui::TableSetupColumn("#history");
|
||||||
|
ImGui::TableSetupColumn("#entranceExitTool");
|
||||||
|
ImGui::TableSetupColumn("#itemTool");
|
||||||
|
ImGui::TableSetupColumn("#spriteTool");
|
||||||
|
ImGui::TableSetupColumn("#transportTool");
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_UNDO);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_REDO);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_MANAGE_HISTORY);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text(ICON_MD_MORE_VERT);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_ZOOM_OUT);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_ZOOM_IN);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text(ICON_MD_MORE_VERT);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_DRAW);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_SENSOR_DOOR);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_GRASS);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_PEST_CONTROL_RODENT);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Button(ICON_MD_ADD_LOCATION);
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverworldEditor::DrawOverworldMapSettings() {
|
||||||
|
if (ImGui::BeginTable("#mapSettings", 7, ow_map_settings_flags, ImVec2(0, 0),
|
||||||
|
-1)) {
|
||||||
|
|
||||||
|
ImGui::TableSetupColumn("##1stCol");
|
||||||
|
ImGui::TableSetupColumn("##gfxCol");
|
||||||
|
ImGui::TableSetupColumn("##palCol");
|
||||||
|
ImGui::TableSetupColumn("##sprgfxCol");
|
||||||
|
ImGui::TableSetupColumn("##sprpalCol");
|
||||||
|
ImGui::TableSetupColumn("##msgidCol");
|
||||||
|
ImGui::TableSetupColumn("##2ndCol");
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(100.f);
|
||||||
|
ImGui::Combo("##world", ¤t_world_,
|
||||||
|
"Light World\0Dark World\0Extra World\0");
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("GFX");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetNextItemWidth(kInputFieldSize);
|
||||||
|
ImGui::InputText("##mapGFX", map_gfx_, kByteSize);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Palette");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetNextItemWidth(kInputFieldSize);
|
||||||
|
ImGui::InputText("##mapPal", map_palette_, kByteSize);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Spr GFX");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetNextItemWidth(kInputFieldSize);
|
||||||
|
ImGui::InputText("##sprGFX", spr_gfx_, kByteSize);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Spr Palette");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetNextItemWidth(kInputFieldSize);
|
||||||
|
ImGui::InputText("##sprPal", spr_palette_, kByteSize);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Msg ID");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetNextItemWidth(50.f);
|
||||||
|
ImGui::InputText("##msgid", spr_palette_, kMessageIdSize);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Checkbox("Show grid", &opt_enable_grid);
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverworldEditor::DrawOverworldCanvas() {
|
||||||
|
DrawOverworldMapSettings();
|
||||||
|
ImGui::Separator();
|
||||||
|
static ImVector<ImVec2> points;
|
||||||
|
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();
|
||||||
|
ImVec2 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", NULL, false, points.Size > 0)) {
|
||||||
|
points.resize(points.size() - 2);
|
||||||
|
}
|
||||||
|
if (ImGui::MenuItem("Remove all", NULL, 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() {
|
||||||
|
if (ImGui::BeginTabBar("##TabBar")) {
|
||||||
|
if (ImGui::BeginTabItem("Tile16")) {
|
||||||
|
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
if (ImGui::BeginTabItem("Tile8")) {
|
||||||
|
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
ImGui::EndTabBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Editor
|
||||||
|
} // namespace Application
|
||||||
|
} // namespace yaze
|
||||||
44
src/Application/Editor/OverworldEditor.h
Normal file
44
src/Application/Editor/OverworldEditor.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#ifndef YAZE_APPLICATION_EDITOR_OVERWORLDEDITOR_H
|
||||||
|
#define YAZE_APPLICATION_EDITOR_OVERWORLDEDITOR_H
|
||||||
|
|
||||||
|
#include "Core/Icons.h"
|
||||||
|
#include "imgui/imgui.h"
|
||||||
|
#include "imgui/misc/cpp/imgui_stdlib.h"
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace Application {
|
||||||
|
namespace Editor {
|
||||||
|
class OverworldEditor {
|
||||||
|
public:
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DrawToolset();
|
||||||
|
void DrawOverworldMapSettings();
|
||||||
|
void DrawOverworldCanvas();
|
||||||
|
void DrawTileSelector();
|
||||||
|
|
||||||
|
ImGuiTableFlags toolset_table_flags = ImGuiTableFlags_SizingFixedFit;
|
||||||
|
ImGuiTableFlags ow_map_settings_flags = ImGuiTableFlags_Borders;
|
||||||
|
ImGuiTableFlags ow_edit_flags = ImGuiTableFlags_Reorderable | ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingStretchSame;
|
||||||
|
|
||||||
|
float canvas_table_ratio = 30.f;
|
||||||
|
|
||||||
|
char map_gfx_[3] = "";
|
||||||
|
char map_palette_[3] = "";
|
||||||
|
char spr_gfx_[3] = "";
|
||||||
|
char spr_palette_[3] = "";
|
||||||
|
char message_id_[5] = "";
|
||||||
|
|
||||||
|
int current_world_ = 0;
|
||||||
|
|
||||||
|
constexpr static int kByteSize = 3;
|
||||||
|
constexpr static int kMessageIdSize = 5;
|
||||||
|
constexpr static float kInputFieldSize = 30.f;
|
||||||
|
bool opt_enable_grid = true;
|
||||||
|
};
|
||||||
|
} // namespace Editor
|
||||||
|
} // namespace Application
|
||||||
|
} // namespace yaze
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -16,25 +16,25 @@ namespace Graphics {
|
|||||||
using byte = unsigned char;
|
using byte = unsigned char;
|
||||||
|
|
||||||
class Bitmap {
|
class Bitmap {
|
||||||
public:
|
public:
|
||||||
Bitmap()=default;
|
Bitmap() = default;
|
||||||
Bitmap(int width, int height, byte* data);
|
Bitmap(int width, int height, byte *data);
|
||||||
|
|
||||||
void Create(GLuint* out_texture);
|
void Create(GLuint *out_texture);
|
||||||
int GetWidth();
|
int GetWidth();
|
||||||
int GetHeight();
|
int GetHeight();
|
||||||
|
|
||||||
bool LoadBitmapFromROM(unsigned char* texture_data, GLuint* out_texture,
|
bool LoadBitmapFromROM(unsigned char *texture_data, GLuint *out_texture,
|
||||||
int* out_width, int* out_height);
|
int *out_width, int *out_height);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int width_;
|
int width_;
|
||||||
int height_;
|
int height_;
|
||||||
byte* pixel_data_;
|
byte *pixel_data_;
|
||||||
SDL_PixelFormat pixel_format_;
|
SDL_PixelFormat pixel_format_;
|
||||||
};
|
};
|
||||||
} // namespace Graphics
|
} // namespace Graphics
|
||||||
} // namespace Application
|
} // namespace Application
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -7,42 +7,36 @@ namespace yaze {
|
|||||||
namespace Application {
|
namespace Application {
|
||||||
namespace Graphics {
|
namespace Graphics {
|
||||||
|
|
||||||
r_palette* palette_create(const unsigned int size, const unsigned int id)
|
r_palette* palette_create(const unsigned int size, const unsigned int id) {
|
||||||
{
|
r_palette* new_pal = (r_palette*)malloc(sizeof(r_palette));
|
||||||
r_palette *new_pal = (r_palette*) malloc(sizeof(r_palette));
|
new_pal->colors = (m_color*)malloc(sizeof(m_color) * size);
|
||||||
new_pal->colors = (m_color*) malloc(sizeof(m_color) * size);
|
|
||||||
new_pal->id = id;
|
new_pal->id = id;
|
||||||
new_pal->size = size;
|
new_pal->size = size;
|
||||||
return new_pal;
|
return new_pal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void palette_free(r_palette* tofree)
|
void palette_free(r_palette* tofree) {
|
||||||
{
|
|
||||||
free(tofree->colors);
|
free(tofree->colors);
|
||||||
free(tofree);
|
free(tofree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r_palette* palette_extract(const char* data, const unsigned int offset,
|
||||||
r_palette *palette_extract(const char* data, const unsigned int offset, const unsigned int palette_size)
|
const unsigned int palette_size) {
|
||||||
{
|
|
||||||
r_palette* toret = palette_create(palette_size, 0);
|
r_palette* toret = palette_create(palette_size, 0);
|
||||||
unsigned colnum = 0;
|
unsigned colnum = 0;
|
||||||
for (int i = 0; i < palette_size * 2; i += 2)
|
for (int i = 0; i < palette_size * 2; i += 2) {
|
||||||
{
|
|
||||||
unsigned short snes_color;
|
unsigned short snes_color;
|
||||||
snes_color = ((uchar) data[offset + i + 1]) << 8;
|
snes_color = ((uchar)data[offset + i + 1]) << 8;
|
||||||
snes_color = snes_color | ((uchar) data[offset + i]);
|
snes_color = snes_color | ((uchar)data[offset + i]);
|
||||||
toret->colors[colnum] = convertcolor_snes_to_rgb(snes_color);
|
toret->colors[colnum] = convertcolor_snes_to_rgb(snes_color);
|
||||||
colnum++;
|
colnum++;
|
||||||
}
|
}
|
||||||
return toret;
|
return toret;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* palette_convert(const r_palette pal)
|
char* palette_convert(const r_palette pal) {
|
||||||
{
|
char* toret = (char*)malloc(pal.size * 2);
|
||||||
char* toret = (char*) malloc(pal.size * 2);
|
for (unsigned int i = 0; i < pal.size; i++) {
|
||||||
for (unsigned int i = 0; i < pal.size; i++)
|
|
||||||
{
|
|
||||||
unsigned short snes_data = convertcolor_rgb_to_snes(pal.colors[i]);
|
unsigned short snes_data = convertcolor_rgb_to_snes(pal.colors[i]);
|
||||||
toret[i * 2] = snes_data & 0xFF;
|
toret[i * 2] = snes_data & 0xFF;
|
||||||
toret[i * 2 + 1] = snes_data >> 8;
|
toret[i * 2 + 1] = snes_data >> 8;
|
||||||
@@ -50,12 +44,11 @@ char* palette_convert(const r_palette pal)
|
|||||||
return toret;
|
return toret;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_color convertcolor_snes_to_rgb(const unsigned short snes_color)
|
m_color convertcolor_snes_to_rgb(const unsigned short snes_color) {
|
||||||
{
|
|
||||||
m_color toret;
|
m_color toret;
|
||||||
|
|
||||||
toret.red = ((snes_color ) % 32) * 8;
|
toret.red = ((snes_color) % 32) * 8;
|
||||||
toret.green = ((snes_color / 32) % 32) * 8;
|
toret.green = ((snes_color / 32) % 32) * 8;
|
||||||
toret.blue = ((snes_color / 1024) % 32) * 8;
|
toret.blue = ((snes_color / 1024) % 32) * 8;
|
||||||
|
|
||||||
toret.red = toret.red + toret.red / 32;
|
toret.red = toret.red + toret.red / 32;
|
||||||
@@ -64,13 +57,12 @@ m_color convertcolor_snes_to_rgb(const unsigned short snes_color)
|
|||||||
return toret;
|
return toret;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short convertcolor_rgb_to_snes(const m_color color)
|
unsigned short convertcolor_rgb_to_snes(const m_color color) {
|
||||||
{
|
|
||||||
return convertcolor_rgb_to_snes2(color.red, color.green, color.blue);
|
return convertcolor_rgb_to_snes2(color.red, color.green, color.blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short convertcolor_rgb_to_snes2(const uchar red, const uchar green, const uchar blue)
|
unsigned short convertcolor_rgb_to_snes2(const uchar red, const uchar green,
|
||||||
{
|
const uchar blue) {
|
||||||
uchar R = red / 8;
|
uchar R = red / 8;
|
||||||
uchar G = green / 8;
|
uchar G = green / 8;
|
||||||
uchar B = blue / 8;
|
uchar B = blue / 8;
|
||||||
@@ -78,6 +70,6 @@ unsigned short convertcolor_rgb_to_snes2(const uchar red, const uchar green, co
|
|||||||
return B * 1024 + G * 32 + R;
|
return B * 1024 + G * 32 + R;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace Graphics
|
||||||
}
|
} // namespace Application
|
||||||
}
|
} // namespace yaze
|
||||||
@@ -32,6 +32,7 @@ add_executable(
|
|||||||
Application/Graphics/Bitmap.cc
|
Application/Graphics/Bitmap.cc
|
||||||
Application/Graphics/Tile.cc
|
Application/Graphics/Tile.cc
|
||||||
Application/Editor/Editor.cc
|
Application/Editor/Editor.cc
|
||||||
|
Application/Editor/OverworldEditor.cc
|
||||||
Application/Events/Event.cc
|
Application/Events/Event.cc
|
||||||
Application/Utils/Compression.cc
|
Application/Utils/Compression.cc
|
||||||
Application/Utils/ROM.cc
|
Application/Utils/ROM.cc
|
||||||
@@ -50,6 +51,7 @@ target_include_directories(
|
|||||||
yaze PUBLIC
|
yaze PUBLIC
|
||||||
Library/
|
Library/
|
||||||
Application/
|
Application/
|
||||||
|
Resources/
|
||||||
${SDL2_INCLUDE_DIR}
|
${SDL2_INCLUDE_DIR}
|
||||||
${GLEW_INCLUDE_DIRS}
|
${GLEW_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
@@ -59,5 +61,13 @@ target_link_libraries(
|
|||||||
${SDL2_LIBRARIES}
|
${SDL2_LIBRARIES}
|
||||||
${GLEW_LIBRARIES}
|
${GLEW_LIBRARIES}
|
||||||
${OPENGL_LIBRARIES}
|
${OPENGL_LIBRARIES}
|
||||||
|
png
|
||||||
ImGui
|
ImGui
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set (source "${CMAKE_SOURCE_DIR}/assets")
|
||||||
|
set (destination "${CMAKE_CURRENT_BINARY_DIR}/assets")
|
||||||
|
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E create_symlink ${source} ${destination}
|
||||||
|
DEPENDS ${destination}
|
||||||
|
COMMENT "symbolic link resources folder from ${source} => ${destination}")
|
||||||
Reference in New Issue
Block a user