Add GraphicsEditor class

Super donkey proto graphics import experiment

removed snes_spc and asar_static because of macOS M1 build issues.

music player using snes_spc disabled

included macOS build configuration as it currently is.
This commit is contained in:
scawful
2023-07-08 09:03:27 -04:00
parent 3ada9988aa
commit 931560cfb1
16 changed files with 267 additions and 92 deletions

View File

@@ -0,0 +1,89 @@
#include "app/editor/graphics_editor.h"
#include <ImGuiFileDialog/ImGuiFileDialog.h>
#include <imgui/imgui.h>
#include <imgui/misc/cpp/imgui_stdlib.h>
#include <imgui_memory_editor.h>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "app/gfx/bitmap.h"
#include "app/gui/canvas.h"
#include "app/gui/input.h"
#include "app/rom.h"
namespace yaze {
namespace app {
namespace editor {
absl::Status GraphicsEditor::Update() {
DrawImport();
return absl::OkStatus();
}
absl::Status GraphicsEditor::DrawImport() {
static int offset = 0;
static int size = 0;
static char filePath[256] = "";
ImGui::InputText("File", filePath, sizeof(filePath));
// Open the file dialog when the user clicks the "Browse" button
if (ImGui::Button("Browse")) {
ImGuiFileDialog::Instance()->OpenDialog("ImportDlgKey", "Choose File",
".bin\0", ".");
}
// Draw the file dialog
if (ImGuiFileDialog::Instance()->Display("ImportDlgKey")) {
// If the user made a selection, copy the filename to the filePath buffer
if (ImGuiFileDialog::Instance()->IsOk()) {
strncpy(filePath, ImGuiFileDialog::Instance()->GetFilePathName().c_str(),
sizeof(filePath));
}
// Close the modal
ImGuiFileDialog::Instance()->Close();
}
gui::InputHex("Offset", &offset);
gui::InputHex("Size ", &size);
if (ImGui::Button("Import")) {
if (strlen(filePath) > 0) {
// Add your importing code here, using filePath and offset as parameters
RETURN_IF_ERROR(DecompressImportData(filePath, offset, size))
} else {
// Show an error message if no file has been selected
ImGui::Text("Please select a file before importing.");
}
}
import_canvas_.DrawBackground(ImVec2(0x100 + 1, (8192 * 2) + 1));
import_canvas_.DrawContextMenu();
import_canvas_.DrawBitmap(bitmap_, 2, gfx_loaded_);
import_canvas_.DrawTileSelector(32);
import_canvas_.DrawGrid(32.0f);
import_canvas_.DrawOverlay();
return absl::OkStatus();
}
absl::Status GraphicsEditor::DecompressImportData(char *filePath, int offset,
int size) {
RETURN_IF_ERROR(temp_rom.LoadFromFile(filePath))
ASSIGN_OR_RETURN(import_data_, temp_rom.DecompressGraphics(offset, size))
bitmap_.Create(core::kTilesheetWidth, core::kTilesheetHeight * 0x10,
core::kTilesheetDepth, import_data_.data());
rom_.RenderBitmap(&bitmap_);
gfx_loaded_ = true;
return absl::OkStatus();
}
} // namespace editor
} // namespace app
} // namespace yaze

View File

@@ -0,0 +1,45 @@
#ifndef YAZE_APP_EDITOR_GRAPHICS_EDITOR_H
#define YAZE_APP_EDITOR_GRAPHICS_EDITOR_H
#include <ImGuiFileDialog/ImGuiFileDialog.h>
#include <imgui/imgui.h>
#include <imgui/misc/cpp/imgui_stdlib.h>
#include <imgui_memory_editor.h>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "app/gfx/bitmap.h"
#include "app/gui/canvas.h"
#include "app/gui/input.h"
#include "app/rom.h"
namespace yaze {
namespace app {
namespace editor {
class GraphicsEditor {
public:
absl::Status Update();
void SetupROM(ROM &rom) { rom_ = rom; }
private:
absl::Status DrawImport();
absl::Status DecompressImportData(char *filePath, int offset, int size);
ROM rom_;
ROM temp_rom;
gfx::Bitmap bitmap_;
gui::Canvas import_canvas_;
Bytes import_data_;
bool gfx_loaded_ = false;
};
} // namespace editor
} // namespace app
} // namespace yaze
#endif // YAZE_APP_EDITOR_GRAPHICS_EDITOR_H

View File

@@ -73,6 +73,7 @@ void MasterEditor::UpdateScreen() {
TAB_BAR("##TabBar")
DrawOverworldEditor();
DrawDungeonEditor();
DrawGraphicsEditor();
DrawMusicEditor();
DrawSpriteEditor();
DrawScreenEditor();
@@ -88,6 +89,7 @@ void MasterEditor::DrawFileDialog() {
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
status_ = rom_.LoadFromFile(filePathName);
overworld_editor_.SetupROM(rom_);
graphics_editor_.SetupROM(rom_);
screen_editor_.SetupROM(rom_);
palette_editor_.SetupROM(rom_);
music_editor_.SetupROM(rom_);
@@ -162,6 +164,8 @@ void MasterEditor::DrawYazeMenu() {
}
void MasterEditor::DrawFileMenu() {
static bool save_as_menu = false;
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("Open", "Ctrl+O")) {
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Open ROM",
@@ -169,7 +173,7 @@ void MasterEditor::DrawFileMenu() {
}
MENU_ITEM2("Save", "Ctrl+S") { status_ = rom_.SaveToFile(backup_rom_); }
MENU_ITEM("Save As..") {}
MENU_ITEM("Save As..") { save_as_menu = true; }
ImGui::Separator();
@@ -179,6 +183,19 @@ void MasterEditor::DrawFileMenu() {
}
ImGui::EndMenu();
}
if (save_as_menu) {
static std::string save_as_filename = "";
ImGui::Begin("Save As..", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
ImGui::InputText("Filename", &save_as_filename);
if (ImGui::Button("Save", ImVec2(200, 0))) {
status_ = rom_.SaveToFile(backup_rom_, save_as_filename);
}
if (ImGui::Button("Cancel", ImVec2(200, 0))) {
save_as_menu = false;
}
ImGui::End();
}
}
void MasterEditor::DrawEditMenu() {
@@ -294,6 +311,12 @@ void MasterEditor::DrawDungeonEditor() {
END_TAB_ITEM()
}
void MasterEditor::DrawGraphicsEditor() {
TAB_ITEM("Graphics")
graphics_editor_.Update();
END_TAB_ITEM()
}
void MasterEditor::DrawPaletteEditor() {
TAB_ITEM("Palettes")
status_ = palette_editor_.Update();

View File

@@ -11,16 +11,17 @@
#include "app/core/constants.h"
#include "app/editor/assembly_editor.h"
#include "app/editor/dungeon_editor.h"
#include "app/editor/graphics_editor.h"
#include "app/editor/music_editor.h"
#include "app/editor/overworld_editor.h"
#include "app/editor/palette_editor.h"
#include "app/editor/screen_editor.h"
#include "app/gfx/snes_palette.h"
#include "app/gfx/snes_tile.h"
#include "app/rom.h"
#include "app/gui/canvas.h"
#include "app/gui/icons.h"
#include "app/gui/input.h"
#include "app/rom.h"
namespace yaze {
namespace app {
@@ -45,6 +46,7 @@ class MasterEditor {
void DrawOverworldEditor();
void DrawDungeonEditor();
void DrawGraphicsEditor();
void DrawPaletteEditor();
void DrawMusicEditor();
void DrawScreenEditor();
@@ -61,6 +63,7 @@ class MasterEditor {
AssemblyEditor assembly_editor_;
DungeonEditor dungeon_editor_;
GraphicsEditor graphics_editor_;
OverworldEditor overworld_editor_;
PaletteEditor palette_editor_;
ScreenEditor screen_editor_;

View File

@@ -8,9 +8,9 @@
#include "app/gui/canvas.h"
#include "app/gui/icons.h"
#include "app/gui/input.h"
#include "snes_spc/demo/demo_util.h"
#include "snes_spc/demo/wave_writer.h"
#include "snes_spc/snes_spc/spc.h"
// #include "snes_spc/demo/demo_util.h"
// #include "snes_spc/demo/wave_writer.h"
// #include "snes_spc/snes_spc/spc.h"
namespace yaze {
namespace app {
@@ -21,46 +21,46 @@ namespace {
#define BUF_SIZE 2048
void PlaySPC() {
/* Create emulator and filter */
SNES_SPC* snes_spc = spc_new();
SPC_Filter* filter = spc_filter_new();
if (!snes_spc || !filter) error("Out of memory");
// /* Create emulator and filter */
// SNES_SPC* snes_spc = spc_new();
// SPC_Filter* filter = spc_filter_new();
// if (!snes_spc || !filter) error("Out of memory");
/* Load SPC */
{
/* Load file into memory */
long spc_size;
void* spc = load_file("assets/music/hyrule_field.spc", &spc_size);
// /* Load SPC */
// {
// /* Load file into memory */
// long spc_size;
// void* spc = load_file("assets/music/hyrule_field.spc", &spc_size);
/* Load SPC data into emulator */
error(spc_load_spc(snes_spc, spc, spc_size));
free(spc); /* emulator makes copy of data */
// /* Load SPC data into emulator */
// error(spc_load_spc(snes_spc, spc, spc_size));
// free(spc); /* emulator makes copy of data */
/* Most SPC files have garbage data in the echo buffer, so clear that */
spc_clear_echo(snes_spc);
// /* Most SPC files have garbage data in the echo buffer, so clear that */
// spc_clear_echo(snes_spc);
/* Clear filter before playing */
spc_filter_clear(filter);
}
// /* Clear filter before playing */
// spc_filter_clear(filter);
// }
/* Record 20 seconds to wave file */
wave_open(spc_sample_rate, "out.wav");
wave_enable_stereo();
while (wave_sample_count() < 30 * spc_sample_rate * 2) {
/* Play into buffer */
short buf[BUF_SIZE];
error(spc_play(snes_spc, BUF_SIZE, buf));
// /* Record 20 seconds to wave file */
// wave_open(spc_sample_rate, "out.wav");
// wave_enable_stereo();
// while (wave_sample_count() < 30 * spc_sample_rate * 2) {
// /* Play into buffer */
// short buf[BUF_SIZE];
// error(spc_play(snes_spc, BUF_SIZE, buf));
/* Filter samples */
spc_filter_run(filter, buf, BUF_SIZE);
// /* Filter samples */
// spc_filter_run(filter, buf, BUF_SIZE);
wave_write(buf, BUF_SIZE);
}
// wave_write(buf, BUF_SIZE);
// }
/* Cleanup */
spc_filter_delete(filter);
spc_delete(snes_spc);
wave_close();
// /* Cleanup */
// spc_filter_delete(filter);
// spc_delete(snes_spc);
// wave_close();
}
} // namespace
@@ -223,10 +223,10 @@ void MusicEditor::DrawToolset() {
if (is_playing) {
if (!has_loaded_song) {
PlaySPC();
current_song_ = Mix_LoadMUS("out.wav");
Mix_PlayMusic(current_song_, -1);
has_loaded_song = true;
// PlaySPC();
// current_song_ = Mix_LoadMUS("out.wav");
// Mix_PlayMusic(current_song_, -1);
// has_loaded_song = true;
}
// // If there is no music playing

View File

@@ -11,9 +11,9 @@
#include "app/gui/input.h"
#include "app/rom.h"
#include "app/zelda3/music/tracker.h"
#include "snes_spc/demo/demo_util.h"
#include "snes_spc/demo/wave_writer.h"
#include "snes_spc/snes_spc/spc.h"
// #include "snes_spc/demo/demo_util.h"
// #include "snes_spc/demo/wave_writer.h"
// #include "snes_spc/snes_spc/spc.h"
namespace yaze {
namespace app {
@@ -69,7 +69,7 @@ class MusicEditor {
zelda3::Tracker music_tracker_;
ROM rom_;
Mix_Music* current_song_ = NULL;
// Mix_Music* current_song_ = NULL;
AssemblyEditor assembly_editor_;
ImGuiTableFlags toolset_table_flags_ = ImGuiTableFlags_SizingFixedFit;

View File

@@ -185,7 +185,7 @@ void OverworldEditor::DrawOverworldSprites() {
// ----------------------------------------------------------------------------
void OverworldEditor::DrawOverworldEdits() {
void OverworldEditor::DrawOverworldEdits() const {
auto mouse_position = ow_map_canvas_.GetCurrentDrawnTilePosition();
auto canvas_size = ow_map_canvas_.GetCanvasSize();
int x = mouse_position.x / canvas_size.x;
@@ -379,16 +379,16 @@ absl::Status OverworldEditor::LoadGraphics() {
}
// Render the sprites for each Overworld map
// for (int i = 0; i < 3; i++)
// for (auto &sprite : overworld_.Sprites(i)) {
// int width = sprite.Width();
// int height = sprite.Height();
// int depth = 0x40;
// auto spr_gfx = sprite.PreviewGraphics().data();
// sprite_previews_[sprite.id()].Create(width, height, depth, spr_gfx);
// sprite_previews_[sprite.id()].ApplyPalette(palette_);
// rom_.RenderBitmap(&(sprite_previews_[sprite.id()]));
// }
for (int i = 0; i < 3; i++)
for (auto &sprite : overworld_.Sprites(i)) {
int width = sprite.Width();
int height = sprite.Height();
int depth = 0x40;
auto spr_gfx = sprite.PreviewGraphics().data();
sprite_previews_[sprite.id()].Create(width, height, depth, spr_gfx);
sprite_previews_[sprite.id()].ApplyPalette(palette_);
rom_.RenderBitmap(&(sprite_previews_[sprite.id()]));
}
return absl::OkStatus();
}

View File

@@ -58,7 +58,7 @@ class OverworldEditor {
void DrawOverworldEntrances();
void DrawOverworldMaps();
void DrawOverworldSprites();
void DrawOverworldEdits();
void DrawOverworldEdits() const;
void DrawOverworldCanvas();
void DrawTile16Selector();