diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 502d057d..c8dad48f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -139,6 +139,46 @@ set_target_properties(yaze LINK_FLAGS "${CMAKE_CURRENT_SOURCE_DIR}/yaze.res" ) +# + +add_executable( + yaze_delta + app/delta/delta.cc + app/delta/viewer.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} + lib/asar/src/asar-dll-bindings/c/asardll.c +) + +target_include_directories( + yaze_delta PUBLIC + lib/ + app/ + ${ASAR_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR}/src/ + ${PNG_INCLUDE_DIRS} + ${SDL2_INCLUDE_DIR} + ${GLEW_INCLUDE_DIRS} + lib/asar/src/asar-dll-bindings/c +) + +target_link_libraries( + yaze_delta PUBLIC + ${ABSL_TARGETS} + ${SDL_TARGETS} + ${PNG_LIBRARIES} + ${GLEW_LIBRARIES} + ${OPENGL_LIBRARIES} + ${CMAKE_DL_LIBS} + ImGui +) + set (source "${CMAKE_SOURCE_DIR}/assets") set (destination "${CMAKE_CURRENT_BINARY_DIR}/assets") add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD diff --git a/src/app/core/controller.h b/src/app/core/controller.h index d3bb255b..ba5af3e4 100644 --- a/src/app/core/controller.h +++ b/src/app/core/controller.h @@ -26,6 +26,7 @@ class Controller { absl::Status onEntry(); void onInput(); void onLoad(); + void onLoadDelta(); void doRender() const; void onExit() const; diff --git a/src/app/delta/delta.cc b/src/app/delta/delta.cc new file mode 100644 index 00000000..39e604d1 --- /dev/null +++ b/src/app/delta/delta.cc @@ -0,0 +1,33 @@ +#if defined(_WIN32) +#define main SDL_main +#endif + +#include "absl/debugging/failure_signal_handler.h" +#include "absl/debugging/symbolize.h" +#include "app/core/controller.h" +#include "app/delta/viewer.h" + +int main(int argc, char** argv) { + absl::InitializeSymbolizer(argv[0]); + + absl::FailureSignalHandlerOptions options; + absl::InstallFailureSignalHandler(options); + + yaze::app::core::Controller controller; + yaze::app::delta::Viewer viewer; + + auto entry_status = controller.onEntry(); + if (!entry_status.ok()) { + // TODO(@scawful): log the specific error + return EXIT_FAILURE; + } + + while (controller.isActive()) { + controller.onInput(); + viewer.Update(); + controller.doRender(); + } + controller.onExit(); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/src/app/delta/delta.proto b/src/app/delta/delta.proto new file mode 100644 index 00000000..fc67285d --- /dev/null +++ b/src/app/delta/delta.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; +option cc_enable_arenas = true; + +service YazeDelta { + rpc Init(InitRequest) returns (InitResponse) {} + + rpc Push(PushRequest) returns (PushResponse) {} + rpc Pull(PullRequest) returns (PullResponse) {} + + rpc CreateBranch(CreateBranchRequest) returns (CreateBranchResponse) {} + rpc DeleteBranch(DeleteBranchRequest) returns (DeleteBranchResponse) {} + + rpc Merge(MergeRequest) returns (MergeResponse) {} + rpc UndoMerge(UndoMergeRequest) returns (UndoMergeResponse) {} +} + +message InitRequest { + string project_name = 1; + repeated uint16_t bytes = 2; +} + +message PushRequest { + string username = 1; +} +message PushResponse {} + +message PullRequest {} +message PullResponse {} + +message CreateBranchRequest {} +message CreateBranchResponse {} + +message DeleteBranchRequest {} +message DeleteBranchResponse {} + +message MergeRequest {} +message MergeResponse {} + +message UndoMergeRequest {} +message UndoMergeResponse {} \ No newline at end of file diff --git a/src/app/delta/viewer.cc b/src/app/delta/viewer.cc new file mode 100644 index 00000000..79bbad6e --- /dev/null +++ b/src/app/delta/viewer.cc @@ -0,0 +1,146 @@ +#include "viewer.h" + +#include +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "app/core/constants.h" +#include "app/gfx/snes_palette.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" +#include "gui/canvas.h" +#include "gui/icons.h" +#include "gui/input.h" + +namespace yaze { +namespace app { +namespace delta { +namespace { + +constexpr ImGuiWindowFlags kMainEditorFlags = + ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_MenuBar | + ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar; + +void NewMasterFrame() { + const ImGuiIO& io = ImGui::GetIO(); + ImGui::NewFrame(); + ImGui::SetNextWindowPos(ImVec2(0, 0)); + ImVec2 dimensions(io.DisplaySize.x, io.DisplaySize.y); + ImGui::SetNextWindowSize(dimensions, ImGuiCond_Always); + + if (!ImGui::Begin("##YazeMain", nullptr, kMainEditorFlags)) { + ImGui::End(); + return; + } +} + +bool BeginCentered(const char* name) { + ImGuiIO const& io = ImGui::GetIO(); + ImVec2 pos(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f); + ImGui::SetNextWindowPos(pos, ImGuiCond_Always, ImVec2(0.5f, 0.5f)); + ImGuiWindowFlags flags = + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | + ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings; + return ImGui::Begin(name, nullptr, flags); +} + +void DisplayStatus(absl::Status& status) { + if (BeginCentered("StatusWindow")) { + ImGui::Text("%s", status.ToString().c_str()); + ImGui::Spacing(); + ImGui::NextColumn(); + ImGui::Columns(1); + ImGui::Separator(); + ImGui::NewLine(); + ImGui::SameLine(270); + if (ImGui::Button("OK", ImVec2(200, 0))) { + status = absl::OkStatus(); + } + ImGui::End(); + } +} + +} // namespace + +void Viewer::Update() { + NewMasterFrame(); + DrawBranchTree(); + ImGui::End(); +} + +void Viewer::DrawBranchTree() { + static ImGuiTableFlags flags = + ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | + ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | + ImGuiTableFlags_NoBordersInBody; + + if (ImGui::BeginTable("3ways", 3, flags)) { + // The first column will use the default _WidthStretch when ScrollX is Off + // and _WidthFixed when ScrollX is On + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_NoHide); + ImGui::TableSetupColumn("Size", ImGuiTableColumnFlags_WidthFixed, + 10 * 12.0f); + ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed, + 10 * 18.0f); + ImGui::TableHeadersRow(); + + // Simple storage to output a dummy file-system. + struct MyTreeNode { + const char* Name; + const char* Type; + int Size; + int ChildIdx; + int ChildCount; + static void DisplayNode(const MyTreeNode* node, + const MyTreeNode* all_nodes) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + const bool is_folder = (node->ChildCount > 0); + if (is_folder) { + bool open = + ImGui::TreeNodeEx(node->Name, ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::TableNextColumn(); + ImGui::TextDisabled("--"); + ImGui::TableNextColumn(); + ImGui::TextUnformatted(node->Type); + if (open) { + for (int child_n = 0; child_n < node->ChildCount; child_n++) + DisplayNode(&all_nodes[node->ChildIdx + child_n], all_nodes); + ImGui::TreePop(); + } + } else { + ImGui::TreeNodeEx( + node->Name, ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_Bullet | + ImGuiTreeNodeFlags_NoTreePushOnOpen | + ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::TableNextColumn(); + ImGui::Text("%d", node->Size); + ImGui::TableNextColumn(); + ImGui::TextUnformatted(node->Type); + } + } + }; + static const MyTreeNode nodes[] = { + {"Root", "Folder", -1, 1, 3}, // 0 + {"Music", "Folder", -1, 4, 2}, // 1 + {"Textures", "Folder", -1, 6, 3}, // 2 + {"desktop.ini", "System file", 1024, -1, -1}, // 3 + {"File1_a.wav", "Audio file", 123000, -1, -1}, // 4 + {"File1_b.wav", "Audio file", 456000, -1, -1}, // 5 + {"Image001.png", "Image file", 203128, -1, -1}, // 6 + {"Copy of Image001.png", "Image file", 203256, -1, -1}, // 7 + {"Copy of Image001 (Final2).png", "Image file", 203512, -1, -1}, // 8 + }; + + MyTreeNode::DisplayNode(&nodes[0], nodes); + + ImGui::EndTable(); + } +} +} // namespace delta +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/delta/viewer.h b/src/app/delta/viewer.h new file mode 100644 index 00000000..6cd7903b --- /dev/null +++ b/src/app/delta/viewer.h @@ -0,0 +1,33 @@ +#ifndef YAZE_APP_DELTA_VIEWER_H +#define YAZE_APP_DELTA_VIEWER_H + +#include +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "app/core/constants.h" +#include "app/gfx/snes_palette.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" +#include "gui/canvas.h" +#include "gui/icons.h" +#include "gui/input.h" + +namespace yaze { +namespace app { +namespace delta { +class Viewer { + public: + void Update(); + + private: + void DrawBranchTree(); +}; +} // namespace delta +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file