Skip to content

Commit

Permalink
Merge branch 'Lighting' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Dregu committed Aug 10, 2024
2 parents f7950b6 + b5fdcdd commit e7b4a82
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 30 deletions.
22 changes: 14 additions & 8 deletions hook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,8 @@ void DestroyRenderTarget() {
// DEBUG("DestroyRenderTarget");
if (g_Initialized) {
g_Initialized = false;
ImGui_ImplWin32_Shutdown();
ImGui_ImplDX12_Shutdown();
ImGui_ImplWin32_Shutdown();
}
g_pD3DCommandQueue = nullptr;
g_FrameContext.clear();
Expand Down Expand Up @@ -253,7 +253,7 @@ long __fastcall HookPresent(IDXGISwapChain3 *pSwapChain, UINT SyncInterval,

auto *g = ImGui::CreateContext();
ImGuiIO &io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // has to be enabled at start for ImGui_ImplWin32_Init to load everything
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;

CreateDirectory(L"MAXWELL", NULL);
Expand Down Expand Up @@ -322,6 +322,13 @@ long __fastcall HookPresent(IDXGISwapChain3 *pSwapChain, UINT SyncInterval,

pD3DDevice->Release();

// set viewports back to value from options to prevent change mid frame
if (g_UI->GetOption("ui_viewports")) {
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
} else {
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_ViewportsEnable;
}

g_Initialized = true;
}

Expand All @@ -331,11 +338,10 @@ long __fastcall HookPresent(IDXGISwapChain3 *pSwapChain, UINT SyncInterval,
::DispatchMessage(&msg);
}

auto &g = *GImGui;
ImGuiIO &io = ImGui::GetIO();
auto g = ImGui::GetCurrentContext();

for (int i = 1; i < g.PlatformIO.Viewports.Size; i++) {
ImGuiViewport *viewport = g.PlatformIO.Viewports[i];
for (int i = 1; i < g->PlatformIO.Viewports.Size; i++) {
ImGuiViewport *viewport = g->PlatformIO.Viewports[i];
viewport->Flags |= ImGuiViewportFlags_NoFocusOnClick |
ImGuiViewportFlags_NoFocusOnAppearing |
ImGuiViewportFlags_OwnedByApp;
Expand Down Expand Up @@ -363,7 +369,7 @@ long __fastcall HookPresent(IDXGISwapChain3 *pSwapChain, UINT SyncInterval,
g_pD3DCommandList->ResourceBarrier(1, &barrier);
g_pD3DCommandList->OMSetRenderTargets(
1, &currentFrameContext.main_render_target_descriptor, FALSE, nullptr);
g_pD3DCommandList->SetDescriptorHeaps(1, &g_pD3DSrvDescHeap);
g_pD3DCommandList->SetDescriptorHeaps(1, &g_pD3DSrvDescHeap.p);
ImGui::Render();

if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
Expand All @@ -380,7 +386,7 @@ long __fastcall HookPresent(IDXGISwapChain3 *pSwapChain, UINT SyncInterval,
g_pD3DCommandList->Close();

g_pD3DCommandQueue->ExecuteCommandLists(
1, (ID3D12CommandList **)&g_pD3DCommandList);
1, (ID3D12CommandList **)&g_pD3DCommandList.p);

return OriginalPresent(pSwapChain, SyncInterval, Flags);
} // namespace D3D12
Expand Down
18 changes: 18 additions & 0 deletions max.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,24 @@ Room *Max::room(int m, int x, int y) {
return nullptr;
}

LightingData *Max::ambient(int id) {
static std::unique_ptr<std::array<LightingData, 32>> data = nullptr;

if (!data) { // the game does not copy the ambient data to memory so we have
// to sneak in our own pointer to be able to edit the data.
data = std::make_unique<std::array<LightingData, 32>>();

auto data_addr =
(LightingData **)(*(size_t *)get_address("layer_base") + 0x89d470);
memcpy(data->data(), *data_addr, data->size() * sizeof(LightingData));
*data_addr = data->data();
}

if (id >= 0 && id < 32)
return &(*data)[id];
return nullptr;
}

Tile *Max::tile(int m, int rx, int ry, int x, int y, int l) {
auto room = Max::room(m, rx, ry);
if (room)
Expand Down
17 changes: 17 additions & 0 deletions max.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ struct Room {
Tile tiles[2][22][40];
};

struct RoomData {
uint8_t bgId;
uint8_t waterLevel;
RoomParams params;
};

struct Map {
uint16_t roomCount;
uint8_t world_wrap_x_start;
Expand Down Expand Up @@ -179,6 +185,16 @@ struct uv_data {
};
static_assert(sizeof(uv_data) == 10);

struct LightingData {
uint8_t fg_ambient_multi[4]; // increases fg ambient light intensity
uint8_t bg_ambient_multi[4]; // increases bg ambient light intensity
uint8_t ambient_light[4];
uint8_t light_intensity[4];
float dividers[3]; // divides colors
float saturation; // global saturation
float bg_tex_light_multi; // amount lights affect background texture
};

// TODO: This is a horrible prototype still
struct Max {
static Max &get();
Expand Down Expand Up @@ -217,6 +233,7 @@ struct Max {
std::bitset<0xce40 * 8> *map_bits(int n = 0);
Map *map(int m = 0);
Room *room(int m, int x, int y);
LightingData *ambient(int id);
Tile *tile(int m, int rx, int ry, int x, int y, int l);
bool import_map(std::string file, int m = 0);
void load_custom_asset(uint32_t id, AssetInfo &asset);
Expand Down
112 changes: 92 additions & 20 deletions ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -813,13 +813,36 @@ void UI::DrawSelectedTileRow(SelectedTile &tile) {
}
}

void ColorEdit3(const char *label, uint8_t *col,
ImGuiColorEditFlags flags = 0) {
float col4[4]{col[0] / 255.0f, col[1] / 255.0f, col[2] / 255.0f, 1.0f};

ImGui::ColorEdit4(label, col4, flags | ImGuiColorEditFlags_NoAlpha);

col[0] = col4[0] * 255.f;
col[1] = col4[1] * 255.f;
col[2] = col4[2] * 255.f;
}

void ColorEdit4(const char *label, uint8_t *col,
ImGuiColorEditFlags flags = 0) {
float col4[4]{col[0] / 255.0f, col[1] / 255.0f, col[2] / 255.0f,
col[3] / 255.0f};

ImGui::ColorEdit4(label, col4, flags);

col[0] = col4[0] * 255.f;
col[1] = col4[1] * 255.f;
col[2] = col4[2] * 255.f;
col[3] = col4[3] * 255.f;
}

void UI::DrawLevel() {
ImGuiIO &io = ImGui::GetIO();
ImGuiContext &g = *GImGui;

ImGui::PushItemWidth(100.f * uiScale);

if (ImGui::CollapsingHeader("Room")) {
ImGui::PushItemWidth(140.f * uiScale);
static bool lockCurrentRoom{true};
ImGui::Checkbox("Select current room", &lockCurrentRoom);
if (lockCurrentRoom) {
Expand All @@ -828,29 +851,73 @@ void UI::DrawLevel() {
selectedRoom.room = Max::get().room(selectedRoom.map, selectedRoom.pos.x,
selectedRoom.pos.y);
}

ImGui::BeginDisabled(lockCurrentRoom);
if (ImGui::InputInt2("Position##RoomPosition", &selectedRoom.pos.x)) {
selectedRoom.room = Max::get().room(selectedRoom.map, selectedRoom.pos.x,
selectedRoom.pos.y);
}
ImGui::EndDisabled();

if (selectedRoom.room) {
ImGui::InputScalarN("Position##RoomPosition", ImGuiDataType_U8,
&selectedRoom.room->x, 2);
if (!defaultRoom.contains(selectedRoom.room))
defaultRoom[selectedRoom.room] = {selectedRoom.room->bgId,
selectedRoom.room->waterLevel,
selectedRoom.room->params};
ImGui::InputScalarN("BG##RoomBG", ImGuiDataType_U8,
&selectedRoom.room->bgId, 1, &u8_one);
ImGui::InputScalarN("Palette##RoomPalette", ImGuiDataType_U8,
ImGui::InputScalarN("Lighting##RoomLighting", ImGuiDataType_U8,
&selectedRoom.room->params.palette, 1, &u8_one);
ImGui::InputScalarN("???##UnknownRoomParams", ImGuiDataType_U8,
&selectedRoom.room->params.idk1, 3);
ImGui::DragScalar("Water level##RoomWaterLevel", ImGuiDataType_U8,
&selectedRoom.room->waterLevel, 0.1f, &u8_min, &u8_max);
ImGui::InputScalar("##ForcedPalette", ImGuiDataType_U8, &forcedPalette,
&u8_one);
if (forcedPalette > 31)
forcedPalette = 31;
ImGui::SameLine(0, 4);
ImGui::Checkbox("Forced lighting", &options["cheat_palette"].value);
if (options["cheat_palette"].value) {
Max::get().force_palette = forcedPalette;
} else {
Max::get().force_palette = std::nullopt;
}
if (ImGui::Button("Reset room params##ResetRoomParams") &&
defaultRoom.contains(selectedRoom.room)) {
selectedRoom.room->bgId = defaultRoom[selectedRoom.room].bgId;
selectedRoom.room->waterLevel =
defaultRoom[selectedRoom.room].waterLevel;
selectedRoom.room->params = defaultRoom[selectedRoom.room].params;
}

auto palette = options["cheat_palette"].value
? forcedPalette
: selectedRoom.room->params.palette;
ImGui::SeparatorText(fmt::format("Light params ({})", palette).c_str());

auto amb = Max::get().ambient(palette);

if (amb) {
if (!defaultLighting.contains(palette))
defaultLighting[palette] = *amb;

ColorEdit3("Color", amb->ambient_light);
ColorEdit3("FG tile multiplier", amb->fg_ambient_multi);
ColorEdit3("BG tile multiplier", amb->bg_ambient_multi);

ColorEdit4("Lamp intensity", amb->light_intensity);
ImGui::DragFloat3("Dividers", amb->dividers, 0.1f);
ImGui::DragFloat("Saturation", &amb->saturation, 0.1f);
ImGui::DragFloat("BG texture multiplier", &amb->bg_tex_light_multi,
0.1f);

if (ImGui::Button("Reset light params##ResetRoomLightParams") &&
defaultLighting.contains(palette))
*amb = defaultLighting[palette];
}
}
ImGui::InputScalar("##ForcedPalette", ImGuiDataType_U8, &forcedPalette,
&u8_one);
if (forcedPalette > 31)
forcedPalette = 31;
ImGui::SameLine(0, 4);
ImGui::Checkbox("Forced palette", &options["cheat_palette"].value);
if (options["cheat_palette"].value) {
Max::get().force_palette = forcedPalette;
} else {
Max::get().force_palette = std::nullopt;
}
ImGui::PopItemWidth();
}

ImGui::PushID("TileEditor");
Expand All @@ -870,6 +937,7 @@ void UI::DrawLevel() {

ImGui::PushID("TileSearch");
if (ImGui::CollapsingHeader("Tile search ")) {
ImGui::PushItemWidth(100.f * uiScale);
static uint16_t searchId{0};
ImGui::InputScalar("ID", ImGuiDataType_U16, &searchId, &u16_one);
const bool focused = ImGui::IsItemFocused();
Expand Down Expand Up @@ -937,6 +1005,7 @@ void UI::DrawLevel() {
ImGui::PopID();
}
ImGui::PopID();
ImGui::PopItemWidth();
}
ImGui::PopID();

Expand Down Expand Up @@ -973,7 +1042,6 @@ void UI::DrawLevel() {
ImGui::TextWrapped(
"Put files exported by map editor in MAXWELL/Maps to import!");
}
ImGui::PopItemWidth();
}

UI::UI(float scale) {
Expand Down Expand Up @@ -1230,15 +1298,17 @@ void UI::Windows() {
window->detached = true;
}
ImGui::EndMainMenuBar();
} else {
ImGui::PopStyleVar(2);
}
for (auto *window : windows) {
if (!window->detached)
continue;
if (ImGui::Begin(window->title.c_str(), &window->detached,
window->flags)) {
window->cb();
ImGui::End();
}
ImGui::End();
}
}
}
Expand Down Expand Up @@ -1454,7 +1524,9 @@ void UI::Draw() {
return;
}

if (options["ui_scaling"].value) {
auto ui_scaling =
options["ui_scaling"].value; // cache value in case it gets changed
if (ui_scaling) {
uiScale = dpiScale;
ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);

Expand Down Expand Up @@ -1491,7 +1563,7 @@ void UI::Draw() {
Cheats();

ImGui::PopFont();
if (options["ui_scaling"].value)
if (ui_scaling)
ImGui::PopStyleVar(10);

if (ImGui::GetFrameCount() == 20)
Expand Down
9 changes: 7 additions & 2 deletions ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,9 @@ class UI {
{false, "Remove lights",
"Removes the lighting effect of hanging lights.", "toggle_lights"}},
{"cheat_palette",
{false, "Force color palette",
"Forces a specific room color palette.\n(a very bright one by default)",
{false, "Force lighting",
"Forces a specific room color palette/lighting.\n(a very bright one by "
"default)",
"toggle_palette"}},
{"cheat_gameboy",
{false, "Gameboy mode",
Expand Down Expand Up @@ -202,6 +203,8 @@ class UI {
std::vector<std::filesystem::path> maps;
uint8_t forcedPalette{26};
std::vector<SelectedTile> searchTiles;
std::unordered_map<Room *, RoomData> defaultRoom;
std::unordered_map<uint8_t, LightingData> defaultLighting;

public:
UI(float scale = 1.0f);
Expand Down Expand Up @@ -239,6 +242,8 @@ class UI {
void LoadMuralPage(int page);
void RefreshMaps();

bool GetOption(const std::string &name) { return options[name].value; }

HWND hWnd;
ID3D12Device *pD3DDevice = NULL;
IDXGISwapChain3 *pSwapChain = NULL;
Expand Down

0 comments on commit e7b4a82

Please sign in to comment.