Update PaletteEditor, remove Delta experiment
This commit is contained in:
@@ -129,57 +129,4 @@ set_target_properties(yaze
|
|||||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||||
LINK_FLAGS "${CMAKE_CURRENT_SOURCE_DIR}/yaze.res"
|
LINK_FLAGS "${CMAKE_CURRENT_SOURCE_DIR}/yaze.res"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# 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}
|
|
||||||
# )
|
|
||||||
|
|
||||||
# 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")
|
|
||||||
|
|
||||||
# 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}")
|
|
||||||
@@ -65,6 +65,10 @@
|
|||||||
|
|
||||||
#define APPEND_NUMBER_INNER(expression, number) expression##number
|
#define APPEND_NUMBER_INNER(expression, number) expression##number
|
||||||
|
|
||||||
|
#define TEXT_WITH_SEPARATOR(text) \
|
||||||
|
ImGui::Text(text); \
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
using ushort = unsigned short;
|
using ushort = unsigned short;
|
||||||
using uint = unsigned int;
|
using uint = unsigned int;
|
||||||
using uchar = unsigned char;
|
using uchar = unsigned char;
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
|
|
||||||
add_library(delta-service delta.proto)
|
|
||||||
target_link_libraries(delta-service
|
|
||||||
PUBLIC
|
|
||||||
protobuf::libprotobuf
|
|
||||||
gRPC::grpc
|
|
||||||
gRPC::grpc++
|
|
||||||
)
|
|
||||||
|
|
||||||
target_include_directories(delta-service
|
|
||||||
PUBLIC
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
${PROTOBUF_INCLUDE_PATH}
|
|
||||||
)
|
|
||||||
|
|
||||||
get_target_property(grpc_cpp_plugin_location gRPC::grpc_cpp_plugin LOCATION)
|
|
||||||
|
|
||||||
# compile the message types
|
|
||||||
protobuf_generate(TARGET delta-service LANGUAGE cpp)
|
|
||||||
|
|
||||||
# compile the GRPC services
|
|
||||||
protobuf_generate(
|
|
||||||
TARGET
|
|
||||||
delta-service
|
|
||||||
LANGUAGE
|
|
||||||
grpc
|
|
||||||
GENERATE_EXTENSIONS
|
|
||||||
.grpc.pb.h
|
|
||||||
.grpc.pb.cc
|
|
||||||
PLUGIN
|
|
||||||
"protoc-gen-grpc=${grpc_cpp_plugin_location}"
|
|
||||||
)
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
#include "client.h"
|
|
||||||
|
|
||||||
#include <google/protobuf/message.h>
|
|
||||||
#include <grpc/support/log.h>
|
|
||||||
#include <grpcpp/ext/proto_server_reflection_plugin.h>
|
|
||||||
#include <grpcpp/grpcpp.h>
|
|
||||||
#include <grpcpp/health_check_service_interface.h>
|
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
|
||||||
#include "src/app/delta/delta.grpc.pb.h"
|
|
||||||
#include "src/app/delta/delta.pb.h"
|
|
||||||
|
|
||||||
namespace yaze {
|
|
||||||
namespace app {
|
|
||||||
namespace delta {
|
|
||||||
|
|
||||||
using grpc::Channel;
|
|
||||||
using grpc::ClientAsyncResponseReader;
|
|
||||||
using grpc::ClientContext;
|
|
||||||
using grpc::CompletionQueue;
|
|
||||||
using grpc::Server;
|
|
||||||
using grpc::ServerBuilder;
|
|
||||||
using grpc::Status;
|
|
||||||
|
|
||||||
void Client::CreateChannel() {
|
|
||||||
auto channel = grpc::CreateChannel("localhost:50051",
|
|
||||||
grpc::InsecureChannelCredentials());
|
|
||||||
stub_ = ::YazeDelta::NewStub(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
absl::Status Client::InitRepo(std::string author_name,
|
|
||||||
std::string project_name) {
|
|
||||||
Repository new_repo;
|
|
||||||
new_repo.set_author_name(author_name);
|
|
||||||
new_repo.set_project_name(project_name);
|
|
||||||
new_repo.mutable_tree()->Add();
|
|
||||||
|
|
||||||
InitRequest request;
|
|
||||||
request.set_allocated_repo(&new_repo);
|
|
||||||
|
|
||||||
InitResponse response;
|
|
||||||
Status status = stub_->Init(&rpc_context, request, &response);
|
|
||||||
|
|
||||||
if (!status.ok()) {
|
|
||||||
std::cerr << status.error_code() << ": " << status.error_message()
|
|
||||||
<< std::endl;
|
|
||||||
return absl::InternalError(status.error_message());
|
|
||||||
}
|
|
||||||
return absl::OkStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace delta
|
|
||||||
} // namespace app
|
|
||||||
} // namespace yaze
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
#ifndef YAZE_APP_DELTA_CLIENT_H
|
|
||||||
#define YAZE_APP_DELTA_CLIENT_H
|
|
||||||
|
|
||||||
#include <google/protobuf/message.h>
|
|
||||||
#include <grpc/support/log.h>
|
|
||||||
#include <grpcpp/ext/proto_server_reflection_plugin.h>
|
|
||||||
#include <grpcpp/grpcpp.h>
|
|
||||||
#include <grpcpp/health_check_service_interface.h>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
|
||||||
#include "src/app/delta/delta.grpc.pb.h"
|
|
||||||
#include "src/app/delta/delta.pb.h"
|
|
||||||
|
|
||||||
namespace yaze {
|
|
||||||
namespace app {
|
|
||||||
namespace delta {
|
|
||||||
|
|
||||||
using grpc::Channel;
|
|
||||||
using grpc::ClientAsyncResponseReader;
|
|
||||||
using grpc::ClientContext;
|
|
||||||
using grpc::CompletionQueue;
|
|
||||||
using grpc::Server;
|
|
||||||
using grpc::ServerBuilder;
|
|
||||||
using grpc::Status;
|
|
||||||
|
|
||||||
class Client {
|
|
||||||
public:
|
|
||||||
Client() = default;
|
|
||||||
void CreateChannel();
|
|
||||||
absl::Status InitRepo(std::string author_name, std::string project_name);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ClientContext rpc_context;
|
|
||||||
std::vector<Repository> repos_;
|
|
||||||
std::unique_ptr<YazeDelta::Stub> stub_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace delta
|
|
||||||
} // namespace app
|
|
||||||
} // namespace yaze
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#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()) {
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (controller.isActive()) {
|
|
||||||
controller.onInput();
|
|
||||||
viewer.Update();
|
|
||||||
controller.doRender();
|
|
||||||
}
|
|
||||||
controller.onExit();
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
option cc_enable_arenas = true;
|
|
||||||
|
|
||||||
service YazeDelta {
|
|
||||||
rpc Init(InitRequest) returns (InitResponse) {}
|
|
||||||
|
|
||||||
rpc Clone(CloneRequest) returns (CloneResponse) {}
|
|
||||||
|
|
||||||
rpc Push(PushRequest) returns (PushResponse) {}
|
|
||||||
rpc Pull(PullRequest) returns (PullResponse) {}
|
|
||||||
|
|
||||||
rpc Sync(stream SyncRequest) returns (stream SyncResponse) {}
|
|
||||||
|
|
||||||
rpc CreateBranch(CreateBranchRequest) returns (CreateBranchResponse) {}
|
|
||||||
rpc DeleteBranch(DeleteBranchRequest) returns (DeleteBranchResponse) {}
|
|
||||||
|
|
||||||
rpc Merge(MergeRequest) returns (MergeResponse) {}
|
|
||||||
rpc UndoMerge(UndoMergeRequest) returns (UndoMergeResponse) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ChangeType {
|
|
||||||
OVERWORLD_MAP = 0;
|
|
||||||
DUNGEON_MAP = 1;
|
|
||||||
MONOLOGUE = 2;
|
|
||||||
PALETTE = 3;
|
|
||||||
OBJECT = 4;
|
|
||||||
ASSEMBLY = 5;
|
|
||||||
MISC = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Delta {
|
|
||||||
int64 offset = 1;
|
|
||||||
int64 length = 2;
|
|
||||||
bytes data = 3;
|
|
||||||
ChangeType type = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Commit {
|
|
||||||
int64 commit_id = 1;
|
|
||||||
int64 parent_commit_id = 2;
|
|
||||||
string author_name = 3;
|
|
||||||
string message_header = 4;
|
|
||||||
optional string message_body = 5;
|
|
||||||
repeated Delta delta = 6;
|
|
||||||
int64 signature = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Branch {
|
|
||||||
string branch_name = 1;
|
|
||||||
optional string parent_name = 2;
|
|
||||||
repeated Commit commits = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Repository {
|
|
||||||
string project_name = 1;
|
|
||||||
string author_name = 2;
|
|
||||||
int64 signature = 3;
|
|
||||||
optional bool locked = 4;
|
|
||||||
optional string password = 5;
|
|
||||||
repeated Branch tree = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
message InitRequest {
|
|
||||||
Repository repo = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message InitResponse {
|
|
||||||
int32 response = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message CloneRequest {}
|
|
||||||
|
|
||||||
message CloneResponse {}
|
|
||||||
|
|
||||||
message PushRequest {
|
|
||||||
string author_name = 1;
|
|
||||||
string repository_name= 2;
|
|
||||||
string branch_name = 3;
|
|
||||||
repeated Commit commits = 4;
|
|
||||||
}
|
|
||||||
message PushResponse {}
|
|
||||||
|
|
||||||
message PullRequest {
|
|
||||||
string repository_name = 1;
|
|
||||||
string branch_name = 2;
|
|
||||||
repeated Commit commits = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message PullResponse {}
|
|
||||||
|
|
||||||
message SyncRequest {}
|
|
||||||
|
|
||||||
message SyncResponse {}
|
|
||||||
|
|
||||||
message CreateBranchRequest {}
|
|
||||||
message CreateBranchResponse {}
|
|
||||||
|
|
||||||
message DeleteBranchRequest {}
|
|
||||||
message DeleteBranchResponse {}
|
|
||||||
|
|
||||||
message MergeRequest {}
|
|
||||||
message MergeResponse {}
|
|
||||||
|
|
||||||
message UndoMergeRequest {}
|
|
||||||
message UndoMergeResponse {}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
#include "service.h"
|
|
||||||
|
|
||||||
#include <google/protobuf/message.h>
|
|
||||||
#include <grpc/support/log.h>
|
|
||||||
#include <grpcpp/ext/proto_server_reflection_plugin.h>
|
|
||||||
#include <grpcpp/grpcpp.h>
|
|
||||||
#include <grpcpp/health_check_service_interface.h>
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
|
||||||
#include "absl/status/statusor.h"
|
|
||||||
#include "src/app/delta/delta.grpc.pb.h"
|
|
||||||
#include "src/app/delta/delta.pb.h"
|
|
||||||
|
|
||||||
namespace yaze {
|
|
||||||
namespace app {
|
|
||||||
namespace delta {
|
|
||||||
|
|
||||||
using grpc::Channel;
|
|
||||||
using grpc::ClientAsyncResponseReader;
|
|
||||||
using grpc::ClientContext;
|
|
||||||
using grpc::CompletionQueue;
|
|
||||||
using grpc::Server;
|
|
||||||
using grpc::ServerBuilder;
|
|
||||||
using grpc::Status;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
auto FindRepository(std::vector<Repository>& repos, const std::string& name) {
|
|
||||||
for (auto& repo : repos) {
|
|
||||||
if (repo.project_name() == name) {
|
|
||||||
return repo.mutable_tree();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto FindBranch(google::protobuf::RepeatedPtrField<Branch>* repo,
|
|
||||||
const std::string& branch_name) {
|
|
||||||
for (auto it = repo->begin(); it != repo->end(); ++it) {
|
|
||||||
if (it->branch_name() == branch_name) {
|
|
||||||
return it->mutable_commits();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
Status DeltaService::Init(grpc::ServerContext* context,
|
|
||||||
const InitRequest* request, InitResponse* reply) {
|
|
||||||
std::filesystem::create_directories("./.yaze");
|
|
||||||
repos_.push_back(request->repo());
|
|
||||||
// std::ofstream commit_stream("./.yaze/commits");
|
|
||||||
// for (const auto& repo : repos_) {
|
|
||||||
// for (const auto& branch : repo.tree()) {
|
|
||||||
// for (const auto& commit : branch.commits()) {
|
|
||||||
// commit_stream << commit.DebugString();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
return Status::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status DeltaService::Push(grpc::ServerContext* context,
|
|
||||||
const PushRequest* request, PushResponse* reply) {
|
|
||||||
const auto& repository_name = request->repository_name();
|
|
||||||
const auto& branch_name = request->branch_name();
|
|
||||||
auto repo = FindRepository(repos_, repository_name);
|
|
||||||
auto mutable_commits = FindBranch(repo, branch_name);
|
|
||||||
auto size = request->commits().size();
|
|
||||||
for (int i = 1; i < size; ++i) {
|
|
||||||
*mutable_commits->Add() = request->commits().at(i);
|
|
||||||
}
|
|
||||||
return Status::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status DeltaService::Pull(grpc::ServerContext* context,
|
|
||||||
const PullRequest* request, PullResponse* reply) {
|
|
||||||
return Status::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status DeltaService::Clone(grpc::ServerContext* context,
|
|
||||||
const CloneRequest* request, CloneResponse* reply) {
|
|
||||||
return Status::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace delta
|
|
||||||
} // namespace app
|
|
||||||
} // namespace yaze
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
#ifndef YAZE_APP_DELTA_SERVICE_H
|
|
||||||
#define YAZE_APP_DELTA_SERVICE_H
|
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
#include <google/protobuf/message.h>
|
|
||||||
#include <grpc/support/log.h>
|
|
||||||
#include <grpcpp/ext/proto_server_reflection_plugin.h>
|
|
||||||
#include <grpcpp/grpcpp.h>
|
|
||||||
#include <grpcpp/health_check_service_interface.h>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
|
||||||
#include "src/app/delta/delta.grpc.pb.h"
|
|
||||||
#include "src/app/delta/delta.pb.h"
|
|
||||||
|
|
||||||
namespace yaze {
|
|
||||||
namespace app {
|
|
||||||
namespace delta {
|
|
||||||
|
|
||||||
using grpc::Status;
|
|
||||||
|
|
||||||
class DeltaService final : public ::YazeDelta::Service {
|
|
||||||
public:
|
|
||||||
Status Init(grpc::ServerContext* context, const InitRequest* request,
|
|
||||||
InitResponse* reply) override;
|
|
||||||
|
|
||||||
Status Push(grpc::ServerContext* context, const PushRequest* request,
|
|
||||||
PushResponse* reply) override;
|
|
||||||
|
|
||||||
Status Pull(grpc::ServerContext* context, const PullRequest* request,
|
|
||||||
PullResponse* reply) override;
|
|
||||||
|
|
||||||
Status Clone(grpc::ServerContext* context, const CloneRequest* request,
|
|
||||||
CloneResponse* reply) override;
|
|
||||||
|
|
||||||
auto Repos() const { return repos_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<Repository> repos_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace delta
|
|
||||||
} // namespace app
|
|
||||||
} // namespace yaze
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,229 +0,0 @@
|
|||||||
#include "viewer.h"
|
|
||||||
|
|
||||||
#include <ImGuiColorTextEdit/TextEditor.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 "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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void Viewer::Update() {
|
|
||||||
NewMasterFrame();
|
|
||||||
DrawYazeMenu();
|
|
||||||
DrawFileDialog();
|
|
||||||
|
|
||||||
ImGui::Text(ICON_MD_CHANGE_HISTORY);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::Text("%s", rom_.GetTitle());
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
ImGui::Button(ICON_MD_SYNC);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::Button(ICON_MD_ARROW_UPWARD);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::Button(ICON_MD_ARROW_DOWNWARD);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::Button(ICON_MD_MERGE);
|
|
||||||
ImGui::SameLine();
|
|
||||||
|
|
||||||
ImGui::Button(ICON_MD_MANAGE_HISTORY);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::Button(ICON_MD_LAN);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::Button(ICON_MD_COMMIT);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::Button(ICON_MD_DIFFERENCE);
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(75.f);
|
|
||||||
ImGui::Button(ICON_MD_SEND);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::InputText("Server Address", &client_address_);
|
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(75.f);
|
|
||||||
ImGui::Button(ICON_MD_DOWNLOAD);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::InputText("Repository Source", &client_address_);
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
DrawBranchTree();
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Viewer::DrawFileDialog() {
|
|
||||||
if (ImGuiFileDialog::Instance()->Display("ChooseFileDlgKey")) {
|
|
||||||
if (ImGuiFileDialog::Instance()->IsOk()) {
|
|
||||||
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
|
|
||||||
rom_.LoadFromFile(filePathName);
|
|
||||||
}
|
|
||||||
ImGuiFileDialog::Instance()->Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Viewer::DrawYazeMenu() {
|
|
||||||
MENU_BAR()
|
|
||||||
DrawFileMenu();
|
|
||||||
DrawViewMenu();
|
|
||||||
END_MENU_BAR()
|
|
||||||
}
|
|
||||||
|
|
||||||
void Viewer::DrawFileMenu() const {
|
|
||||||
if (ImGui::BeginMenu("File")) {
|
|
||||||
if (ImGui::MenuItem("Open", "Ctrl+O")) {
|
|
||||||
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Open ROM",
|
|
||||||
".sfc,.smc", ".");
|
|
||||||
}
|
|
||||||
|
|
||||||
MENU_ITEM2("Save", "Ctrl+S") {}
|
|
||||||
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Viewer::DrawViewMenu() {
|
|
||||||
static bool show_imgui_metrics = false;
|
|
||||||
static bool show_imgui_style_editor = false;
|
|
||||||
static bool show_memory_editor = false;
|
|
||||||
static bool show_imgui_demo = false;
|
|
||||||
|
|
||||||
if (show_imgui_metrics) {
|
|
||||||
ImGui::ShowMetricsWindow(&show_imgui_metrics);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (show_memory_editor) {
|
|
||||||
static MemoryEditor mem_edit;
|
|
||||||
mem_edit.DrawWindow("Memory Editor", (void*)&rom_, rom_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (show_imgui_demo) {
|
|
||||||
ImGui::ShowDemoWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (show_imgui_style_editor) {
|
|
||||||
ImGui::Begin("Style Editor (ImGui)", &show_imgui_style_editor);
|
|
||||||
ImGui::ShowStyleEditor();
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginMenu("View")) {
|
|
||||||
ImGui::MenuItem("HEX Editor", nullptr, &show_memory_editor);
|
|
||||||
ImGui::MenuItem("ImGui Demo", nullptr, &show_imgui_demo);
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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[] = {
|
|
||||||
{"lttp-redux", "Repository", -1, 1, 3},
|
|
||||||
{"main", "Branch", -1, 4, 2},
|
|
||||||
{"hyrule-castle", "Branch", -1, 4, 2},
|
|
||||||
{"lost-woods", "Branch", -1, 6, 3},
|
|
||||||
{"Added some bushes", "Commit", 1024, -1, -1},
|
|
||||||
{"Constructed a new house", "Commit", 123000, -1, -1},
|
|
||||||
{"File1_b.wav", "Commit", 456000, -1, -1},
|
|
||||||
{"Image001.png", "Commit", 203128, -1, -1},
|
|
||||||
{"Copy of Image001.png", "Commit", 203256, -1, -1},
|
|
||||||
{"Copy of Image001 (Final2).png", "Commit", 203512, -1, -1},
|
|
||||||
};
|
|
||||||
|
|
||||||
MyTreeNode::DisplayNode(&nodes[0], nodes);
|
|
||||||
|
|
||||||
ImGui::EndTable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace delta
|
|
||||||
} // namespace app
|
|
||||||
} // namespace yaze
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
#ifndef YAZE_APP_DELTA_VIEWER_H
|
|
||||||
#define YAZE_APP_DELTA_VIEWER_H
|
|
||||||
|
|
||||||
#include <ImGuiColorTextEdit/TextEditor.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 "app/core/constants.h"
|
|
||||||
#include "app/delta/client.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 DrawFileDialog();
|
|
||||||
|
|
||||||
void DrawYazeMenu();
|
|
||||||
void DrawFileMenu() const;
|
|
||||||
void DrawViewMenu();
|
|
||||||
|
|
||||||
void DrawBranchTree();
|
|
||||||
|
|
||||||
std::string client_address_;
|
|
||||||
|
|
||||||
ROM rom_;
|
|
||||||
Client client_;
|
|
||||||
};
|
|
||||||
} // namespace delta
|
|
||||||
} // namespace app
|
|
||||||
} // namespace yaze
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -7,34 +7,113 @@
|
|||||||
#include "gui/canvas.h"
|
#include "gui/canvas.h"
|
||||||
#include "gui/icons.h"
|
#include "gui/icons.h"
|
||||||
|
|
||||||
|
static inline float ImSaturate(float f) {
|
||||||
|
return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IM_F32_TO_INT8_SAT(_VAL) \
|
||||||
|
((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
|
||||||
|
|
||||||
|
int CustomFormatString(char* buf, size_t buf_size, const char* fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
#ifdef IMGUI_USE_STB_SPRINTF
|
||||||
|
int w = stbsp_vsnprintf(buf, (int)buf_size, fmt, args);
|
||||||
|
#else
|
||||||
|
int w = vsnprintf(buf, buf_size, fmt, args);
|
||||||
|
#endif
|
||||||
|
va_end(args);
|
||||||
|
if (buf == NULL) return w;
|
||||||
|
if (w == -1 || w >= (int)buf_size) w = (int)buf_size - 1;
|
||||||
|
buf[w] = 0;
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace editor {
|
namespace editor {
|
||||||
|
|
||||||
absl::Status PaletteEditor::Update() {
|
namespace {
|
||||||
for (int i = 0; i < 11; ++i) {
|
void DrawPaletteTooltips(gfx::SNESPalette& palette, int size) {}
|
||||||
if (ImGui::TreeNode(kPaletteCategoryNames[i].data())) {
|
|
||||||
auto size = rom_.GetPaletteGroup(kPaletteGroupNames[i].data()).size;
|
|
||||||
auto palettes = rom_.GetPaletteGroup(kPaletteGroupNames[i].data());
|
|
||||||
for (int j = 0; j < size; j++) {
|
|
||||||
ImGui::Text("%d", j);
|
|
||||||
auto palette = palettes[j];
|
|
||||||
for (int n = 0; n < size; n++) {
|
|
||||||
ImGui::PushID(n);
|
|
||||||
if ((n % 8) != 0)
|
|
||||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
|
|
||||||
|
|
||||||
ImGuiColorEditFlags palette_button_flags =
|
using namespace ImGui;
|
||||||
ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker;
|
|
||||||
if (ImGui::ColorButton("##palette", palette[n].RGB(),
|
|
||||||
palette_button_flags, ImVec2(20, 20)))
|
|
||||||
current_color_ =
|
|
||||||
ImVec4(palette[n].rgb.x, palette[n].rgb.y, palette[n].rgb.z,
|
|
||||||
current_color_.w); // Preserve alpha!
|
|
||||||
|
|
||||||
ImGui::PopID();
|
} // namespace
|
||||||
}
|
|
||||||
|
void PaletteEditor::DrawPaletteGroup(int i) {
|
||||||
|
const int palettesPerRow = 4;
|
||||||
|
ImGui::BeginTable("palette_table", palettesPerRow,
|
||||||
|
ImGuiTableFlags_BordersOuter | ImGuiTableFlags_Resizable);
|
||||||
|
|
||||||
|
auto size = rom_.GetPaletteGroup(kPaletteGroupNames[i].data()).size();
|
||||||
|
auto palettes = rom_.GetPaletteGroup(kPaletteGroupNames[i].data());
|
||||||
|
for (int j = 0; j < size; j++) {
|
||||||
|
if (j % palettesPerRow == 0) {
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
}
|
||||||
|
ImGui::TableSetColumnIndex(j % palettesPerRow);
|
||||||
|
ImGui::Text("%d", j);
|
||||||
|
|
||||||
|
auto palette = palettes[j];
|
||||||
|
auto pal_size = palette.size_;
|
||||||
|
|
||||||
|
for (int n = 0; n < pal_size; n++) {
|
||||||
|
ImGui::PushID(n);
|
||||||
|
if ((n % 8) != 0) ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
|
||||||
|
|
||||||
|
std::string popupId = kPaletteCategoryNames[i].data() +
|
||||||
|
std::to_string(j) + "_" + std::to_string(n);
|
||||||
|
if (ImGui::ColorButton(popupId.c_str(), palette[n].RGB(),
|
||||||
|
palette_button_flags)) {
|
||||||
|
if (ImGui::ColorEdit4(popupId.c_str(), palette[n].ToFloatArray(),
|
||||||
|
palette_button_flags))
|
||||||
|
current_color_ =
|
||||||
|
ImVec4(palette[n].rgb.x, palette[n].rgb.y, palette[n].rgb.z,
|
||||||
|
palette[n].rgb.w); // Preserve alpha!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginPopupContextItem(popupId.c_str())) {
|
||||||
|
auto col = palette[n].ToFloatArray();
|
||||||
|
if (ImGui::ColorEdit4(
|
||||||
|
"Edit Color", col,
|
||||||
|
ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoAlpha)) {
|
||||||
|
// palette[n].rgb.x = current_color_rgba.x;
|
||||||
|
// palette[n].rgb.y = current_color_rgba.y;
|
||||||
|
// palette[n].rgb.z = current_color_rgba.z;
|
||||||
|
// rom_.UpdatePaletteColor(kPaletteGroupNames[groupIndex].data(), j,
|
||||||
|
// n, palette[n]);
|
||||||
|
}
|
||||||
|
if (Button("Copy as..", ImVec2(-1, 0))) OpenPopup("Copy");
|
||||||
|
if (BeginPopup("Copy")) {
|
||||||
|
int cr = IM_F32_TO_INT8_SAT(col[0]);
|
||||||
|
int cg = IM_F32_TO_INT8_SAT(col[1]);
|
||||||
|
int cb = IM_F32_TO_INT8_SAT(col[2]);
|
||||||
|
char buf[64];
|
||||||
|
CustomFormatString(buf, IM_ARRAYSIZE(buf), "(%.3ff, %.3ff, %.3ff)",
|
||||||
|
col[0], col[1], col[2]);
|
||||||
|
if (Selectable(buf)) SetClipboardText(buf);
|
||||||
|
CustomFormatString(buf, IM_ARRAYSIZE(buf), "(%d,%d,%d)", cr, cg, cb);
|
||||||
|
if (Selectable(buf)) SetClipboardText(buf);
|
||||||
|
CustomFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", cr, cg,
|
||||||
|
cb);
|
||||||
|
if (Selectable(buf)) SetClipboardText(buf);
|
||||||
|
EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::Status PaletteEditor::Update() {
|
||||||
|
for (int i = 0; i < kNumPalettes; ++i) {
|
||||||
|
if (ImGui::TreeNode(kPaletteCategoryNames[i].data())) {
|
||||||
|
DrawPaletteGroup(i);
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,13 +128,12 @@ void PaletteEditor::DisplayPalette(gfx::SNESPalette& palette, bool loaded) {
|
|||||||
|
|
||||||
// Generate a default palette. The palette will persist and can be edited.
|
// Generate a default palette. The palette will persist and can be edited.
|
||||||
static bool init = false;
|
static bool init = false;
|
||||||
static ImVec4 saved_palette[256] = {};
|
|
||||||
if (loaded && !init) {
|
if (loaded && !init) {
|
||||||
for (int n = 0; n < palette.size_; n++) {
|
for (int n = 0; n < palette.size_; n++) {
|
||||||
saved_palette[n].x = palette.GetColor(n).rgb.x / 255;
|
saved_palette_[n].x = palette.GetColor(n).rgb.x / 255;
|
||||||
saved_palette[n].y = palette.GetColor(n).rgb.y / 255;
|
saved_palette_[n].y = palette.GetColor(n).rgb.y / 255;
|
||||||
saved_palette[n].z = palette.GetColor(n).rgb.z / 255;
|
saved_palette_[n].z = palette.GetColor(n).rgb.z / 255;
|
||||||
saved_palette[n].w = 255; // Alpha
|
saved_palette_[n].w = 255; // Alpha
|
||||||
}
|
}
|
||||||
init = true;
|
init = true;
|
||||||
}
|
}
|
||||||
@@ -68,9 +146,9 @@ void PaletteEditor::DisplayPalette(gfx::SNESPalette& palette, bool loaded) {
|
|||||||
ImGui::OpenPopup("mypicker");
|
ImGui::OpenPopup("mypicker");
|
||||||
backup_color = color;
|
backup_color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::BeginPopup("mypicker")) {
|
if (ImGui::BeginPopup("mypicker")) {
|
||||||
ImGui::Text("Current Overworld Palette");
|
TEXT_WITH_SEPARATOR("Current Overworld Palette");
|
||||||
ImGui::Separator();
|
|
||||||
ImGui::ColorPicker4("##picker", (float*)&color,
|
ImGui::ColorPicker4("##picker", (float*)&color,
|
||||||
misc_flags | ImGuiColorEditFlags_NoSidePreview |
|
misc_flags | ImGuiColorEditFlags_NoSidePreview |
|
||||||
ImGuiColorEditFlags_NoSmallPreview);
|
ImGuiColorEditFlags_NoSmallPreview);
|
||||||
@@ -94,25 +172,22 @@ void PaletteEditor::DisplayPalette(gfx::SNESPalette& palette, bool loaded) {
|
|||||||
color = backup_color;
|
color = backup_color;
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Text("Palette");
|
ImGui::Text("Palette");
|
||||||
for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) {
|
for (int n = 0; n < IM_ARRAYSIZE(saved_palette_); n++) {
|
||||||
ImGui::PushID(n);
|
ImGui::PushID(n);
|
||||||
if ((n % 8) != 0) ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
|
if ((n % 8) != 0) ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
|
||||||
|
|
||||||
ImGuiColorEditFlags palette_button_flags = ImGuiColorEditFlags_NoAlpha |
|
if (ImGui::ColorButton("##palette", saved_palette_[n],
|
||||||
ImGuiColorEditFlags_NoPicker |
|
palette_button_flags_2, ImVec2(20, 20)))
|
||||||
ImGuiColorEditFlags_NoTooltip;
|
color = ImVec4(saved_palette_[n].x, saved_palette_[n].y,
|
||||||
if (ImGui::ColorButton("##palette", saved_palette[n],
|
saved_palette_[n].z, color.w); // Preserve alpha!
|
||||||
palette_button_flags, ImVec2(20, 20)))
|
|
||||||
color = ImVec4(saved_palette[n].x, saved_palette[n].y,
|
|
||||||
saved_palette[n].z, color.w); // Preserve alpha!
|
|
||||||
|
|
||||||
if (ImGui::BeginDragDropTarget()) {
|
if (ImGui::BeginDragDropTarget()) {
|
||||||
if (const ImGuiPayload* payload =
|
if (const ImGuiPayload* payload =
|
||||||
ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
|
ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
|
||||||
memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 3);
|
memcpy((float*)&saved_palette_[n], payload->Data, sizeof(float) * 3);
|
||||||
if (const ImGuiPayload* payload =
|
if (const ImGuiPayload* payload =
|
||||||
ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F))
|
ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F))
|
||||||
memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 4);
|
memcpy((float*)&saved_palette_[n], payload->Data, sizeof(float) * 4);
|
||||||
ImGui::EndDragDropTarget();
|
ImGui::EndDragDropTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,15 +13,18 @@ namespace yaze {
|
|||||||
namespace app {
|
namespace app {
|
||||||
namespace editor {
|
namespace editor {
|
||||||
|
|
||||||
|
constexpr int kNumPalettes = 11;
|
||||||
|
|
||||||
static constexpr absl::string_view kPaletteCategoryNames[] = {
|
static constexpr absl::string_view kPaletteCategoryNames[] = {
|
||||||
"Sword", "Shield", "Clothes", "World Colors",
|
"Sword", "Shield", "Clothes", "World Colors",
|
||||||
"Area Colors", "Enemies", "Dungeons", "World Map",
|
"Area Colors", "Enemies", "Dungeons", "World Map",
|
||||||
"Dungeon Map", "Triforce", "Crystal"};
|
"Dungeon Map", "Triforce", "Crystal"};
|
||||||
|
|
||||||
static constexpr absl::string_view kPaletteGroupNames[] = {
|
static constexpr absl::string_view kPaletteGroupNames[] = {
|
||||||
"swords", "shields", "armors", "ow_main",
|
"swords", "shields", "armors", "ow_main",
|
||||||
"ow_aux", "global_sprites", "dungeon_main", "ow_mini_map",
|
"ow_aux", "global_sprites", "dungeon_main", "ow_mini_map",
|
||||||
"ow_mini_map", "3d_object", "3d_object"};
|
"ow_mini_map", "3d_object", "3d_object"};
|
||||||
|
|
||||||
|
|
||||||
class PaletteEditor {
|
class PaletteEditor {
|
||||||
public:
|
public:
|
||||||
@@ -31,8 +34,17 @@ class PaletteEditor {
|
|||||||
auto SetupROM(ROM& rom) { rom_ = rom; }
|
auto SetupROM(ROM& rom) { rom_ = rom; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void DrawPaletteGroup(int i);
|
||||||
|
|
||||||
|
ImVec4 saved_palette_[256] = {};
|
||||||
ImVec4 current_color_;
|
ImVec4 current_color_;
|
||||||
ROM rom_;
|
ROM rom_;
|
||||||
|
|
||||||
|
ImGuiColorEditFlags palette_button_flags =
|
||||||
|
ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoTooltip;
|
||||||
|
ImGuiColorEditFlags palette_button_flags_2 = ImGuiColorEditFlags_NoAlpha |
|
||||||
|
ImGuiColorEditFlags_NoPicker |
|
||||||
|
ImGuiColorEditFlags_NoTooltip;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace editor
|
} // namespace editor
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ SDL_Palette* SNESPalette::GetSDL_Palette() {
|
|||||||
return sdl_palette.get();
|
return sdl_palette.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
PaletteGroup::PaletteGroup(uint8_t mSize) : size(mSize) {}
|
PaletteGroup::PaletteGroup(uint8_t mSize) : size_(mSize) {}
|
||||||
|
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
|||||||
@@ -47,10 +47,18 @@ struct SNESColor {
|
|||||||
void setSNES(uint16_t);
|
void setSNES(uint16_t);
|
||||||
void setTransparent(bool t) { transparent = t; }
|
void setTransparent(bool t) { transparent = t; }
|
||||||
|
|
||||||
auto RGB() {
|
auto RGB() { return ImVec4(rgb.x / 255, rgb.y / 255, rgb.z / 255, rgb.w); }
|
||||||
return ImVec4(rgb.x / 255, rgb.y / 255, rgb.z / 255, rgb.w);
|
|
||||||
|
float* ToFloatArray() const {
|
||||||
|
static std::vector<float> colorArray(4);
|
||||||
|
colorArray[0] = rgb.x / 255.0f;
|
||||||
|
colorArray[1] = rgb.y / 255.0f;
|
||||||
|
colorArray[2] = rgb.z / 255.0f;
|
||||||
|
colorArray[3] = rgb.w;
|
||||||
|
return colorArray.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool modified = false;
|
||||||
bool transparent = false;
|
bool transparent = false;
|
||||||
uint16_t snes = 0;
|
uint16_t snes = 0;
|
||||||
ImVec4 rgb;
|
ImVec4 rgb;
|
||||||
@@ -82,6 +90,7 @@ class SNESPalette {
|
|||||||
SDL_Palette* GetSDL_Palette();
|
SDL_Palette* GetSDL_Palette();
|
||||||
|
|
||||||
int size_ = 0;
|
int size_ = 0;
|
||||||
|
auto size() const { return colors.size(); }
|
||||||
std::vector<SNESColor> colors;
|
std::vector<SNESColor> colors;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -90,23 +99,24 @@ struct PaletteGroup {
|
|||||||
explicit PaletteGroup(uint8_t mSize);
|
explicit PaletteGroup(uint8_t mSize);
|
||||||
void AddPalette(SNESPalette pal) {
|
void AddPalette(SNESPalette pal) {
|
||||||
palettes.emplace_back(pal);
|
palettes.emplace_back(pal);
|
||||||
size = palettes.size();
|
size_ = palettes.size();
|
||||||
}
|
}
|
||||||
void AddColor(SNESColor color) {
|
void AddColor(SNESColor color) {
|
||||||
if (size == 0) {
|
if (size_ == 0) {
|
||||||
SNESPalette empty_pal;
|
SNESPalette empty_pal;
|
||||||
palettes.emplace_back(empty_pal);
|
palettes.emplace_back(empty_pal);
|
||||||
}
|
}
|
||||||
palettes[0].AddColor(color);
|
palettes[0].AddColor(color);
|
||||||
}
|
}
|
||||||
SNESPalette operator[](int i) {
|
SNESPalette operator[](int i) {
|
||||||
if (i > size) {
|
if (i > size_) {
|
||||||
std::cout << "PaletteGroup: Index out of bounds" << std::endl;
|
std::cout << "PaletteGroup: Index out of bounds" << std::endl;
|
||||||
return palettes[0];
|
return palettes[0];
|
||||||
}
|
}
|
||||||
return palettes[i];
|
return palettes[i];
|
||||||
}
|
}
|
||||||
int size = 0;
|
int size_ = 0;
|
||||||
|
auto size() const { return palettes.size(); }
|
||||||
std::vector<SNESPalette> palettes;
|
std::vector<SNESPalette> palettes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -816,6 +816,54 @@ void ROM::LoadAllPalettes() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ROM::SaveAllPalettes() {
|
||||||
|
// Iterate through all palette_groups_
|
||||||
|
for (auto& group : palette_groups_) {
|
||||||
|
const std::string& groupName = group.first;
|
||||||
|
auto& palettes = group.second;
|
||||||
|
|
||||||
|
// Iterate through all palettes in the group
|
||||||
|
for (size_t i = 0; i < palettes.size(); ++i) {
|
||||||
|
auto palette = palettes[i];
|
||||||
|
|
||||||
|
// Iterate through all colors in the palette
|
||||||
|
for (size_t j = 0; j < palette.size(); ++j) {
|
||||||
|
gfx::SNESColor color = palette[j];
|
||||||
|
|
||||||
|
// If the color is modified, save the color to the ROM
|
||||||
|
if (color.modified) {
|
||||||
|
WriteColor(GetPaletteAddress(groupName, i, j), color);
|
||||||
|
color.modified = false; // Reset the modified flag after saving
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ROM::WriteColor(uint32_t address, const gfx::SNESColor& color) {
|
||||||
|
uint16_t bgr = ((color.snes >> 10) & 0x1F) | ((color.snes & 0x1F) << 10) |
|
||||||
|
(color.snes & 0x7C00);
|
||||||
|
|
||||||
|
// Write the 16-bit color value to the ROM at the specified address
|
||||||
|
rom_data_[address] = static_cast<uint8_t>(bgr & 0xFF);
|
||||||
|
rom_data_[address + 1] = static_cast<uint8_t>((bgr >> 8) & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ROM::GetPaletteAddress(const std::string& groupName,
|
||||||
|
size_t paletteIndex, size_t colorIndex) const {
|
||||||
|
// Retrieve the base address for the palette group
|
||||||
|
uint32_t baseAddress = paletteGroupBaseAddresses.at(groupName);
|
||||||
|
|
||||||
|
// Retrieve the number of colors for each palette in the group
|
||||||
|
size_t colorsPerPalette = paletteGroupColorCounts.at(groupName);
|
||||||
|
|
||||||
|
// Calculate the address for the specified color in the ROM
|
||||||
|
uint32_t address =
|
||||||
|
baseAddress + (paletteIndex * colorsPerPalette * 2) + (colorIndex * 2);
|
||||||
|
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
absl::Status ROM::ApplyAssembly(const absl::string_view& filename,
|
absl::Status ROM::ApplyAssembly(const absl::string_view& filename,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@@ -72,6 +73,48 @@ struct CompressionPiece {
|
|||||||
using CompressionPiece = struct CompressionPiece;
|
using CompressionPiece = struct CompressionPiece;
|
||||||
using CompressionPiecePointer = std::shared_ptr<CompressionPiece>;
|
using CompressionPiecePointer = std::shared_ptr<CompressionPiece>;
|
||||||
|
|
||||||
|
const std::map<std::string, uint32_t> paletteGroupBaseAddresses = {
|
||||||
|
{"ow_main", core::overworldPaletteMain},
|
||||||
|
{"ow_aux", core::overworldPaletteAuxialiary},
|
||||||
|
{"ow_animated", core::overworldPaletteAnimated},
|
||||||
|
{"hud", core::hudPalettes},
|
||||||
|
{"global_sprites",
|
||||||
|
core::globalSpritePalettesLW}, // Assuming LW is the first palette
|
||||||
|
{"armors", core::armorPalettes},
|
||||||
|
{"swords", core::swordPalettes},
|
||||||
|
{"shields", core::shieldPalettes},
|
||||||
|
{"sprites_aux1", core::spritePalettesAux1},
|
||||||
|
{"sprites_aux2", core::spritePalettesAux2},
|
||||||
|
{"sprites_aux3", core::spritePalettesAux3},
|
||||||
|
{"dungeon_main", core::dungeonMainPalettes},
|
||||||
|
{"grass", core::hardcodedGrassLW}, // Assuming LW is the first color
|
||||||
|
{"3d_object",
|
||||||
|
core::triforcePalette}, // Assuming triforcePalette is the first palette
|
||||||
|
{"ow_mini_map", core::overworldMiniMapPalettes},
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::map<std::string, size_t> paletteGroupColorCounts = {
|
||||||
|
{"ow_main", 35},
|
||||||
|
{"ow_aux", 21},
|
||||||
|
{"ow_animated", 7},
|
||||||
|
{"hud", 32},
|
||||||
|
{"global_sprites", 60}, // Assuming both LW and DW
|
||||||
|
// palettes have the same
|
||||||
|
// color count
|
||||||
|
{"armors", 15},
|
||||||
|
{"swords", 3},
|
||||||
|
{"shields", 4},
|
||||||
|
{"sprites_aux1", 7},
|
||||||
|
{"sprites_aux2", 7},
|
||||||
|
{"sprites_aux3", 7},
|
||||||
|
{"dungeon_main", 90},
|
||||||
|
{"grass", 1}, // Assuming grass palettes are
|
||||||
|
// individual colors
|
||||||
|
{"3d_object", 8}, // Assuming both triforcePalette and crystalPalette have
|
||||||
|
// the same color count
|
||||||
|
{"ow_mini_map", 128},
|
||||||
|
};
|
||||||
|
|
||||||
class ROM {
|
class ROM {
|
||||||
public:
|
public:
|
||||||
absl::StatusOr<Bytes> Compress(const int start, const int length,
|
absl::StatusOr<Bytes> Compress(const int start, const int length,
|
||||||
@@ -91,6 +134,11 @@ class ROM {
|
|||||||
absl::Status LoadFromBytes(const Bytes& data);
|
absl::Status LoadFromBytes(const Bytes& data);
|
||||||
void LoadAllPalettes();
|
void LoadAllPalettes();
|
||||||
|
|
||||||
|
void SaveAllPalettes();
|
||||||
|
|
||||||
|
uint32_t GetPaletteAddress(const std::string& groupName, size_t paletteIndex,
|
||||||
|
size_t colorIndex) const;
|
||||||
|
|
||||||
absl::Status SaveToFile();
|
absl::Status SaveToFile();
|
||||||
|
|
||||||
gfx::SNESColor ReadColor(int offset);
|
gfx::SNESColor ReadColor(int offset);
|
||||||
@@ -98,6 +146,7 @@ class ROM {
|
|||||||
|
|
||||||
void Write(int addr, int value);
|
void Write(int addr, int value);
|
||||||
void WriteShort(int addr, int value);
|
void WriteShort(int addr, int value);
|
||||||
|
void WriteColor(uint32_t address, const gfx::SNESColor& color);
|
||||||
|
|
||||||
absl::Status ApplyAssembly(const absl::string_view& filename,
|
absl::Status ApplyAssembly(const absl::string_view& filename,
|
||||||
size_t patch_size);
|
size_t patch_size);
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
#include <asar/interface-lib.h>
|
|
||||||
#include <gmock/gmock.h>
|
|
||||||
#include <google/protobuf/repeated_field.h>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
|
||||||
#include "absl/status/statusor.h"
|
|
||||||
#include "absl/strings/str_cat.h"
|
|
||||||
#include "absl/strings/string_view.h"
|
|
||||||
#include "app/core/constants.h"
|
|
||||||
#include "app/delta/client.h"
|
|
||||||
#include "app/delta/service.h"
|
|
||||||
#include "app/rom.h"
|
|
||||||
#include "src/app/delta/delta.grpc.pb.h"
|
|
||||||
#include "src/app/delta/delta.pb.h"
|
|
||||||
|
|
||||||
namespace yaze_test {
|
|
||||||
namespace delta_test {
|
|
||||||
|
|
||||||
TEST(DeltaTest, InitRepoAndPushOk) {
|
|
||||||
yaze::app::delta::DeltaService service;
|
|
||||||
yaze::app::ROM rom;
|
|
||||||
Bytes test_bytes;
|
|
||||||
test_bytes.push_back(0x40);
|
|
||||||
EXPECT_TRUE(rom.LoadFromBytes(test_bytes).ok());
|
|
||||||
grpc::ServerContext* context;
|
|
||||||
InitRequest init_request;
|
|
||||||
auto repo = init_request.mutable_repo();
|
|
||||||
repo->set_project_name("test_repo");
|
|
||||||
Branch branch;
|
|
||||||
branch.set_branch_name("test_branch");
|
|
||||||
auto new_mutable_commits = branch.mutable_commits();
|
|
||||||
new_mutable_commits->Reserve(5);
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
auto new_commit = new Commit();
|
|
||||||
new_commit->set_commit_id(i);
|
|
||||||
new_mutable_commits->Add();
|
|
||||||
new_mutable_commits->at(i) = *new_commit;
|
|
||||||
}
|
|
||||||
auto mutable_tree = repo->mutable_tree();
|
|
||||||
mutable_tree->Add();
|
|
||||||
mutable_tree->at(0) = branch;
|
|
||||||
InitResponse init_response;
|
|
||||||
auto init_status = service.Init(context, &init_request, &init_response);
|
|
||||||
EXPECT_TRUE(init_status.ok());
|
|
||||||
|
|
||||||
PushRequest request;
|
|
||||||
request.set_branch_name("test_branch");
|
|
||||||
request.set_repository_name("test_repo");
|
|
||||||
auto mutable_commits = request.mutable_commits();
|
|
||||||
mutable_commits->Reserve(5);
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
auto new_commit = new Commit();
|
|
||||||
new_commit->set_commit_id(i * 2);
|
|
||||||
mutable_commits->Add();
|
|
||||||
mutable_commits->at(i) = *new_commit;
|
|
||||||
}
|
|
||||||
PushResponse reply;
|
|
||||||
auto status = service.Push(context, &request, &reply);
|
|
||||||
EXPECT_TRUE(status.ok());
|
|
||||||
|
|
||||||
auto repos = service.Repos();
|
|
||||||
auto result_branch = repos.at(0).tree();
|
|
||||||
std::cerr << result_branch.at(0).DebugString() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace delta_test
|
|
||||||
} // namespace yaze_test
|
|
||||||
Reference in New Issue
Block a user