add music editor gui elements

This commit is contained in:
scawful
2022-12-30 16:40:58 -06:00
parent c7f12e56a2
commit deaeedfc87
4 changed files with 473 additions and 49 deletions

View File

@@ -10,6 +10,7 @@ set(
app/editor/assembly_editor.cc
app/editor/dungeon_editor.cc
app/editor/master_editor.cc
app/editor/music_editor.cc
app/editor/overworld_editor.cc
app/editor/palette_editor.cc
app/editor/screen_editor.cc
@@ -45,6 +46,8 @@ set(
gui/color.cc
)
# executable creation ---------------------------------------------------------
add_executable(
yaze
app/yaze.cc
@@ -59,6 +62,8 @@ add_executable(
${ASAR_STATIC_SRC}
)
# including libraries ---------------------------------------------------------
target_include_directories(
yaze PUBLIC
lib/
@@ -78,6 +83,8 @@ if(WIN32 OR MINGW)
add_definitions(-DSDL_MAIN_HANDLED)
endif()
# linking libraries -----------------------------------------------------------
target_link_libraries(
yaze PUBLIC
${ABSL_TARGETS}
@@ -99,7 +106,17 @@ if (UNIX)
target_compile_definitions(yaze PRIVATE "stricmp=strcasecmp")
endif()
if(MACOS)
set(MACOSX_BUNDLE_ICON_FILE ${CMAKE_SOURCE_DIR}/yaze.ico)
set_target_properties(yaze
PROPERTIES
BUNDLE True
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
# MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/cmake/yaze.plist.in
)
else()
set_target_properties(yaze
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
@@ -107,56 +124,57 @@ set_target_properties(yaze
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
LINK_FLAGS "${CMAKE_CURRENT_SOURCE_DIR}/yaze.res"
)
endif()
add_subdirectory(app/delta)
# add_subdirectory(app/delta)
add_executable(
yaze_delta
app/delta/delta.cc
app/delta/viewer.cc
app/delta/service.cc
app/delta/client.cc
app/rom.cc
${YAZE_APP_ASM_SRC}
${YAZE_APP_CORE_SRC}
${YAZE_APP_EDITOR_SRC}
${YAZE_APP_GFX_SRC}
${YAZE_APP_ZELDA3_SRC}
${YAZE_GUI_SRC}
${IMGUI_SRC}
${ASAR_STATIC_SRC}
)
# add_executable(
# yaze_delta
# app/delta/delta.cc
# app/delta/viewer.cc
# app/delta/service.cc
# app/delta/client.cc
# app/rom.cc
# ${YAZE_APP_ASM_SRC}
# ${YAZE_APP_CORE_SRC}
# ${YAZE_APP_EDITOR_SRC}
# ${YAZE_APP_GFX_SRC}
# ${YAZE_APP_ZELDA3_SRC}
# ${YAZE_GUI_SRC}
# ${IMGUI_SRC}
# ${ASAR_STATIC_SRC}
# )
target_include_directories(
yaze_delta PUBLIC
lib/
app/
lib/asar/src/
${ASAR_INCLUDE_DIR}
${CMAKE_SOURCE_DIR}/src/
${PNG_INCLUDE_DIRS}
${SDL2_INCLUDE_DIR}
${GLEW_INCLUDE_DIRS}
)
# target_include_directories(
# yaze_delta PUBLIC
# lib/
# app/
# lib/asar/src/
# ${ASAR_INCLUDE_DIR}
# ${CMAKE_SOURCE_DIR}/src/
# ${PNG_INCLUDE_DIRS}
# ${SDL2_INCLUDE_DIR}
# ${GLEW_INCLUDE_DIRS}
# )
target_link_libraries(
yaze_delta PUBLIC
${ABSL_TARGETS}
${SDL_TARGETS}
${PNG_LIBRARIES}
${GLEW_LIBRARIES}
${OPENGL_LIBRARIES}
${CMAKE_DL_LIBS}
delta-service
asar-static
ImGui
)
target_compile_definitions(yaze_delta PRIVATE "linux")
target_compile_definitions(yaze_delta PRIVATE "stricmp=strcasecmp")
# target_link_libraries(
# yaze_delta PUBLIC
# ${ABSL_TARGETS}
# ${SDL_TARGETS}
# ${PNG_LIBRARIES}
# ${GLEW_LIBRARIES}
# ${OPENGL_LIBRARIES}
# ${CMAKE_DL_LIBS}
# delta-service
# asar-static
# ImGui
# )
# target_compile_definitions(yaze_delta PRIVATE "linux")
# target_compile_definitions(yaze_delta PRIVATE "stricmp=strcasecmp")
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}")
# 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}")

View File

@@ -0,0 +1,177 @@
#include "music_editor.h"
#include "gui/icons.h"
#include "imgui.h"
namespace yaze {
namespace app {
namespace editor {
void MusicEditor::Update() {
ImGui::Text("Preview:");
DrawToolset();
if (ImGuiID child_id = ImGui::GetID((void*)(intptr_t)9);
ImGui::BeginChild(child_id, ImVec2(0, 90), false)) {
DrawPianoStaff();
}
ImGui::EndChild();
ImGui::Separator();
if (ImGui::BeginTable("MusicEditorColumns", 2, toolset_table_flags_,
ImVec2(0, 0))) {
ImGui::TableSetupColumn("#SongList");
ImGui::TableSetupColumn("#EditorArea");
ImGui::TableNextColumn();
DrawSongList();
ImGui::TableNextColumn();
assembly_editor_.InlineUpdate();
DrawPianoRoll();
ImGui::EndTable();
}
}
static const int NUM_KEYS = 25;
static bool keys[NUM_KEYS];
void MusicEditor::DrawPianoStaff() {
const int NUM_LINES = 5;
const int LINE_THICKNESS = 1;
const int LINE_SPACING = 20;
// Get the draw list for the current window
ImDrawList* draw_list = ImGui::GetWindowDrawList();
// Draw the staff lines
ImVec2 canvas_p0 =
ImVec2(ImGui::GetCursorScreenPos().x, ImGui::GetCursorScreenPos().y);
for (int i = 0; i < NUM_LINES; i++) {
auto line_start = ImVec2(canvas_p0.x, canvas_p0.y + i * LINE_SPACING);
auto line_end = ImVec2(ImGui::GetContentRegionAvail().x, canvas_p0.y + i * LINE_SPACING);
draw_list->AddLine(line_start, line_end, IM_COL32(255, 255, 255, 255),
LINE_THICKNESS);
}
// Draw the ledger lines
const int NUM_LEDGER_LINES = 3;
for (int i = -NUM_LEDGER_LINES; i <= NUM_LINES + NUM_LEDGER_LINES; i++) {
if (i % 2 == 0) continue; // skip every other line
auto line_start = ImVec2(canvas_p0.x, canvas_p0.y + i * LINE_SPACING / 2);
auto line_end =
ImVec2(ImGui::GetContentRegionAvail().x, canvas_p0.y + i * LINE_SPACING / 2);
draw_list->AddLine(line_start, line_end, IM_COL32(150, 150, 150, 255),
LINE_THICKNESS);
}
}
void MusicEditor::DrawPianoRoll() {
// Render the piano roll
float key_width = ImGui::GetContentRegionAvail().x / NUM_KEYS;
float white_key_height = ImGui::GetContentRegionAvail().y * 0.8f;
float black_key_height = ImGui::GetContentRegionAvail().y * 0.5f;
ImGui::Text("Click on the keys to toggle notes");
ImGui::Separator();
// Get the draw list for the current window
// ImDrawList* draw_list = ImGui::GetWindowDrawList();
// draw_list->AddRectFilled(ImVec2(0, 0), ImGui::GetContentRegionAvail(),
// IM_COL32(35, 35, 35, 255));
// // Iterate through the keys and draw them
// for (int i = 0; i < NUM_KEYS; i++) {
// // Calculate the position and size of the key
// ImVec2 key_pos = ImVec2(i * key_width, 0.0f);
// ImVec2 key_size;
// if (i % 12 == 1 || i % 12 == 3 || i % 12 == 6 || i % 12 == 8 ||
// i % 12 == 10) {
// // This is a black key
// key_size = ImVec2(key_width * 0.6f, black_key_height);
// ImVec2 dest;
// dest.x = key_pos.x + key_size.x;
// dest.y = key_pos.y + key_size.y;
// draw_list->AddRectFilled(key_pos, dest, IM_COL32(0, 0, 0, 255));
// } else {
// // This is a white key
// ImVec2 dest;
// dest.x = key_pos.x + key_size.x;
// dest.y = key_pos.y + key_size.y;
// key_size = ImVec2(key_width, white_key_height);
// draw_list->AddRectFilled(key_pos, dest, IM_COL32(255, 255, 255,
// 255));
// }
// }
for (int i = 0; i < NUM_KEYS; i++) {
// Calculate the position and size of the key
ImVec2 key_pos = ImVec2(i * key_width, 0.0f);
ImVec2 key_size;
if (i % 12 == 1 || i % 12 == 3 || i % 12 == 6 || i % 12 == 8 ||
i % 12 == 10) {
// This is a black key
key_size = ImVec2(key_width * 0.6f, black_key_height);
} else {
// This is a white key
key_size = ImVec2(key_width, white_key_height);
}
ImGui::PushID(i);
if (ImGui::Button(kSongNotes[i].data(), key_size)) {
keys[i] ^= 1;
}
ImVec2 button_pos = ImGui::GetItemRectMin();
ImVec2 button_size = ImGui::GetItemRectSize();
if (keys[i]) {
ImVec2 dest;
dest.x = button_pos.x + button_size.x;
dest.y = button_pos.y + button_size.y;
ImGui::GetWindowDrawList()->AddRectFilled(button_pos, dest,
IM_COL32(200, 200, 255, 255));
}
ImGui::PopID();
ImGui::SameLine();
}
}
void MusicEditor::DrawSongList() const {
static int current_song = 0;
ImGui::BeginChild("Song List", ImVec2(250, 0));
ImGui::Text("Select a song to edit:");
ImGui::ListBox(
"##songs", &current_song,
[](void* data, int idx, const char** out_text) {
*out_text = kGameSongs[idx].data();
return true;
},
nullptr, 30, 30);
ImGui::EndChild();
}
void MusicEditor::DrawToolset() {
static bool is_playing = false;
if (ImGui::BeginTable("DWToolset", 3, toolset_table_flags_, ImVec2(0, 0))) {
ImGui::TableSetupColumn("#play");
ImGui::TableSetupColumn("#rewind");
ImGui::TableSetupColumn("#fastforward");
ImGui::TableNextColumn();
if (ImGui::Button(is_playing ? ICON_MD_STOP : ICON_MD_PLAY_ARROW)) {
is_playing = !is_playing;
}
ImGui::TableNextColumn();
ImGui::Button(ICON_MD_FAST_REWIND);
ImGui::TableNextColumn();
ImGui::Button(ICON_MD_FAST_FORWARD);
ImGui::EndTable();
}
}
} // namespace editor
} // namespace app
} // namespace yaze

View File

@@ -0,0 +1,69 @@
#ifndef YAZE_APP_EDITOR_MUSIC_EDITOR_H
#define YAZE_APP_EDITOR_MUSIC_EDITOR_H
#include <imgui/imgui.h>
#include "absl/strings/str_format.h"
#include "app/editor/assembly_editor.h"
#include "gui/canvas.h"
#include "gui/icons.h"
namespace yaze {
namespace app {
namespace editor {
static constexpr absl::string_view kGameSongs[] = {"Title",
"Light World",
"Beginning",
"Rabbit",
"Forest",
"Intro",
"Town",
"Warp",
"Dark world",
"Master sword",
"File select",
"Soldier",
"Mountain",
"Shop",
"Fanfare",
"Castle",
"Palace (Pendant)",
"Cave (Same as Secret Way)",
"Clear (Dungeon end)",
"Church",
"Boss",
"Dungeon (Crystal)",
"Psychic",
"Secret Way (Same as Cave)",
"Rescue",
"Crystal",
"Fountain",
"Pyramid",
"Kill Agahnim",
"Ganon Room",
"Last Boss"};
static constexpr absl::string_view kSongNotes[] = {
"C", "D", "E", "F", "G", "A", "B", "C", "D", "E", "F", "G", "A",
"B", "C", "D", "E", "F", "G", "A", "B", "C", "D", "E", "F"};
class MusicEditor {
public:
void Update();
private:
void DrawPianoStaff();
void DrawPianoRoll();
void DrawSongList() const;
void DrawToolset();
AssemblyEditor assembly_editor_;
ImGuiTableFlags toolset_table_flags_ =
ImGuiTableFlags_SizingFixedFit;
};
} // namespace editor
} // namespace app
} // namespace yaze
#endif