From 17c867b346a97cf81c048d7166889776f19d6019 Mon Sep 17 00:00:00 2001 From: Squid Coder <92821989+realSquidCoder@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:19:04 -0600 Subject: [PATCH 01/21] Begin fixing Overlay Mode --- CMakeLists.txt | 4 ++-- Overlay.cpp | 32 +++++++++++++++++--------------- main.cpp | 26 +++++++++++++------------- 3 files changed, 32 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 86523689..8e27118e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ install(DIRECTORY ${CMAKE_SOURCE_DIR}/plugins/stonesense/configs/ SET(PROJECT_SRCS TrackingModes.cpp - #Overlay.cpp + Overlay.cpp Tile.cpp TileCondition.cpp TileTree.cpp @@ -64,7 +64,7 @@ SET(PROJECT_HDRS MapLoading.h MaterialMatcher.h OcclusionTest.h - #Overlay.h + Overlay.h SegmentProcessing.h SpriteColors.h SpriteMaps.h diff --git a/Overlay.cpp b/Overlay.cpp index 126dcf64..eb418228 100644 --- a/Overlay.cpp +++ b/Overlay.cpp @@ -1,3 +1,5 @@ +#include "GameState.h" +#include "StonesenseState.h" #include "Overlay.h" #include "TrackingModes.h" #include "Hooks.h" @@ -180,14 +182,14 @@ void Overlay::Flip() { al_unlock_bitmap(front); - if(al_get_bitmap_width(front) != ssState.ScreenW - || al_get_bitmap_height(front) != ssState.ScreenH){ + if(al_get_bitmap_width(front) != stonesenseState.ssState.ScreenW + || al_get_bitmap_height(front) != stonesenseState.ssState.ScreenH){ al_destroy_bitmap(front); int32_t flags = al_get_new_bitmap_flags(); if(al_get_current_display() != NULL){ al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP | ALLEGRO_ALPHA_TEST); } - front = al_create_bitmap(ssState.ScreenW, ssState.ScreenH); + front = al_create_bitmap(stonesenseState.ssState.ScreenW, stonesenseState.ssState.ScreenH); al_set_new_bitmap_flags(flags); } @@ -201,14 +203,14 @@ void Overlay::Flip() front_updated = true; al_unlock_mutex(front_mutex); - if(al_get_bitmap_width(back) != ssState.ScreenW - || al_get_bitmap_height(back) != ssState.ScreenH){ + if(al_get_bitmap_width(back) != stonesenseState.ssState.ScreenW + || al_get_bitmap_height(back) != stonesenseState.ssState.ScreenH){ al_destroy_bitmap(back); int32_t flags = al_get_new_bitmap_flags(); if(al_get_current_display() != NULL){ al_set_new_bitmap_flags(al_get_bitmap_flags(al_get_backbuffer(al_get_current_display()))); } - back = al_create_bitmap(ssState.ScreenW, ssState.ScreenH); + back = al_create_bitmap(stonesenseState.ssState.ScreenW, stonesenseState.ssState.ScreenH); al_set_new_bitmap_flags(flags); } @@ -216,7 +218,7 @@ void Overlay::Flip() //do the ending timer stuff clock_t donetime = clock(); - ssTimers.overlay_time = (donetime - starttime)*0.1 + ssTimers.overlay_time*0.9; + stonesenseState.stoneSenseTimers.overlay_time.update(donetime - starttime); } bool Overlay::GoodViewscreen() @@ -258,26 +260,26 @@ void Overlay::render() } //get the SDL surface information so we can do a blit - DFHack::DFSDL_Surface * dfsurf = (DFHack::DFSDL_Surface *) DFHack::DFSDL::DFSDL_GetVideoSurface(); - DFHack::DFSDL_Surface * sssurf = (DFHack::DFSDL_Surface *) DFHack::DFSDL::DFSDL_CreateRGBSurfaceFrom( ((char*) front_data->data) + dataoffset, + DFHack::DFTileSurface * dfsurf = (DFHack::DFTileSurface*) DFHack::DFSDL::DFSDL_GetVideoSurface(); + DFHack::DFTileSurface * sssurf = (DFHack::DFTileSurface*) DFHack::DFSDL::DFSDL_CreateRGBSurfaceFrom( ((char*) front_data->data) + dataoffset, al_get_bitmap_width(front), al_get_bitmap_height(front), 8*front_data->pixel_size, neg*front_data->pitch, 0, 0, 0, 0); - DFSDL_Rect src; + SDL_Rect src; src.x = 0; src.y = 0; - src.w = ssState.ScreenW; - src.h = ssState.ScreenH; + src.w = stonesenseState.ssState.ScreenW; + src.h = stonesenseState.ssState.ScreenH; - DFSDL_Rect pos; + SDL_Rect pos; pos.x = offsetx; pos.y = offsety; pos.w = 0; pos.h = 0; //do the blit - DFHack::DFSDL::DFSDL_UpperBlit(sssurf, &src, dfsurf, &pos); + DFHack::DFSDL::DFSDL_UpperBlit(sssurf->surface, &src, dfsurf->surface, &pos); - DFHack::DFSDL::DFSDL_FreeSurface(sssurf); + DFHack::DFSDL::DFSDL_FreeSurface(sssurf->surface); } front_updated = false; } else { diff --git a/main.cpp b/main.cpp index 3cd402c2..6da61d00 100644 --- a/main.cpp +++ b/main.cpp @@ -6,7 +6,7 @@ #include "commonTypes.h" #include "Config.h" -//#include "Overlay.h" +#include "Overlay.h" #include "Tile.h" #include "GUI.h" //#include "SpriteMaps.h" @@ -226,7 +226,7 @@ static void main_loop(ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE *queue, ALL al_rest(0); /*FIXME: Find a new replacement for the overlay mode. - if (ssConfig.overlay_mode) + if (stonesenseState.ssConfig.overlay_mode) { bool goodoverlay = ovrlay->GoodViewscreen(); if (!goodoverlay) { @@ -280,7 +280,7 @@ static void main_loop(ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE *queue, ALL } } - if (!ssConfig.overlay_mode) { + if (!stonesenseState.ssConfig.overlay_mode) { doMouse(); doRepeatActions(); } @@ -302,7 +302,7 @@ static void main_loop(ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE *queue, ALL if(in_time) { switch (event.type) { case ALLEGRO_EVENT_DISPLAY_RESIZE: - if (ssConfig.overlay_mode) { + if (stonesenseState.ssConfig.overlay_mode) { break; } stonesenseState.timeToReloadSegment = true; @@ -317,7 +317,7 @@ static void main_loop(ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE *queue, ALL /* ALLEGRO_EVENT_KEY_DOWN - a keyboard key was pressed. */ case ALLEGRO_EVENT_KEY_CHAR: - if (ssConfig.overlay_mode) { + if (stonesenseState.ssConfig.overlay_mode) { break; } if(event.keyboard.display != display) { @@ -390,9 +390,9 @@ static void* stonesense_thread(ALLEGRO_THREAD* main_thread, void* parms) auto& ssConfig = stonesenseState.ssConfig; al_set_new_display_flags( - (ssConfig.config.Fullscreen && !ssConfig.overlay_mode ? ALLEGRO_FULLSCREEN : ALLEGRO_WINDOWED) - |(ssConfig.overlay_mode ? 0 : ALLEGRO_RESIZABLE) - |(ssConfig.overlay_mode ? ALLEGRO_MINIMIZED : 0) + (ssConfig.config.Fullscreen && !stonesenseState.ssConfig.overlay_mode ? ALLEGRO_FULLSCREEN : ALLEGRO_WINDOWED) + |(stonesenseState.ssConfig.overlay_mode ? 0 : ALLEGRO_RESIZABLE) + |(stonesenseState.ssConfig.overlay_mode ? ALLEGRO_MINIMIZED : 0) |(ssConfig.config.opengl ? ALLEGRO_OPENGL : 0) |(ssConfig.config.directX ? ALLEGRO_DIRECT3D_INTERNAL : 0)); @@ -421,12 +421,12 @@ static void* stonesense_thread(ALLEGRO_THREAD* main_thread, void* parms) SetTitle("Stonesense"); drawcredits(); - /*FIXME: Find a new replacement for the overlay mode. - if(ssConfig.overlay_mode){ - overlay = std::make_unique(df::global::enabler->renderer); + //FIXME: Find a new replacement for the overlay mode. + if(stonesenseState.ssConfig.overlay_mode){ + auto overlay = std::make_unique(df::global::enabler->renderer); df::global::enabler->renderer = overlay.get(); } - */ + std::filesystem::path p = std::filesystem::path{} / "stonesense" / "stonesense.png"; IMGIcon = load_bitmap_withWarning(p); @@ -564,7 +564,7 @@ DFhackCExport command_result stonesense_command(color_ostream &out, std::vector< stonesenseState.ssConfig.overlay_mode = false; if(params.size() > 0 ) { if(params[0] == "overlay"){ - //ssConfig.overlay_mode = true; + stonesenseState.ssConfig.overlay_mode = true; } else { DumpInfo(out, params); return CR_OK; From ca5e27bcc54c94ff23f194412a0c5a025c2dd0a9 Mon Sep 17 00:00:00 2001 From: Squid Coder <92821989+realSquidCoder@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:24:17 -0600 Subject: [PATCH 02/21] Fix whitespace --- main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 6da61d00..a80e7c5a 100644 --- a/main.cpp +++ b/main.cpp @@ -426,7 +426,7 @@ static void* stonesense_thread(ALLEGRO_THREAD* main_thread, void* parms) auto overlay = std::make_unique(df::global::enabler->renderer); df::global::enabler->renderer = overlay.get(); } - + std::filesystem::path p = std::filesystem::path{} / "stonesense" / "stonesense.png"; IMGIcon = load_bitmap_withWarning(p); From 220d65e9ea084449229d3f73de9679fdda518ca0 Mon Sep 17 00:00:00 2001 From: Squid Coder <92821989+realSquidCoder@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:32:48 -0600 Subject: [PATCH 03/21] Comment out the broken parts so that it still builds. --- Overlay.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Overlay.cpp b/Overlay.cpp index eb418228..c103b5c5 100644 --- a/Overlay.cpp +++ b/Overlay.cpp @@ -260,10 +260,13 @@ void Overlay::render() } //get the SDL surface information so we can do a blit + /* FIXME: need to get the DF video surface DFHack::DFTileSurface * dfsurf = (DFHack::DFTileSurface*) DFHack::DFSDL::DFSDL_GetVideoSurface(); + */ DFHack::DFTileSurface * sssurf = (DFHack::DFTileSurface*) DFHack::DFSDL::DFSDL_CreateRGBSurfaceFrom( ((char*) front_data->data) + dataoffset, al_get_bitmap_width(front), al_get_bitmap_height(front), 8*front_data->pixel_size, neg*front_data->pitch, 0, 0, 0, 0); - + + /*FIXME SDL_Rect is an incomplete type SDL_Rect src; src.x = 0; src.y = 0; @@ -276,9 +279,10 @@ void Overlay::render() pos.w = 0; pos.h = 0; + //do the blit DFHack::DFSDL::DFSDL_UpperBlit(sssurf->surface, &src, dfsurf->surface, &pos); - + */ DFHack::DFSDL::DFSDL_FreeSurface(sssurf->surface); } front_updated = false; From a75ad05ef8b2de7e419d80b90ccb4964d3e1b3e5 Mon Sep 17 00:00:00 2001 From: Squid Coder <92821989+realSquidCoder@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:33:33 -0600 Subject: [PATCH 04/21] again with the whitespace --- Overlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Overlay.cpp b/Overlay.cpp index c103b5c5..a17447c1 100644 --- a/Overlay.cpp +++ b/Overlay.cpp @@ -265,7 +265,7 @@ void Overlay::render() */ DFHack::DFTileSurface * sssurf = (DFHack::DFTileSurface*) DFHack::DFSDL::DFSDL_CreateRGBSurfaceFrom( ((char*) front_data->data) + dataoffset, al_get_bitmap_width(front), al_get_bitmap_height(front), 8*front_data->pixel_size, neg*front_data->pitch, 0, 0, 0, 0); - + /*FIXME SDL_Rect is an incomplete type SDL_Rect src; src.x = 0; From 8ceb39fd0055f7bce52453c786b6cdaf643732f0 Mon Sep 17 00:00:00 2001 From: Squid Coder <92821989+realSquidCoder@users.noreply.github.com> Date: Sun, 26 Jan 2025 10:25:30 -0600 Subject: [PATCH 05/21] More overlay clean up --- main.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/main.cpp b/main.cpp index 95bc5dec..6f9d16c8 100644 --- a/main.cpp +++ b/main.cpp @@ -46,9 +46,9 @@ int keyoffset=0; std::vector v_stonetypes; -/*FIXME: Find a new replacement for the overlay mode. +/*FIXME: Find a new replacement for the overlay mode.*/ std::unique_ptr overlay; -*/ + ALLEGRO_DISPLAY * display; ALLEGRO_EVENT event; @@ -225,36 +225,36 @@ static void main_loop(ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE *queue, ALL al_rest(0); - /*FIXME: Find a new replacement for the overlay mode. + /*FIXME: Find a new replacement for the overlay mode.*/ if (stonesenseState.ssConfig.overlay_mode) { - bool goodoverlay = ovrlay->GoodViewscreen(); + bool goodoverlay = overlay->GoodViewscreen(); if (!goodoverlay) { //do nothing; this isn't a view we can overlay }if (ssConfig.spriteIndexOverlay) { DrawSpriteIndexOverlay(ssConfig.currentSpriteOverlay); - ovrlay->Flip(); + overlay->Flip(); } - else if (!Maps::IsValid()) { + else if (!DFHack::Maps::IsValid()) { drawcredits(); - ovrlay->Flip(); + overlay->Flip(); } - else if (timeToReloadSegment) { + else if (stonesenseState.timeToReloadSegment) { reloadPosition(); al_clear_to_color(ssConfig.config.backcol); paintboard(); - ovrlay->Flip(); - timeToReloadSegment = false; - animationFrameShown = true; + overlay->Flip(); + stonesenseState.timeToReloadSegment = false; + stonesenseState.animationFrameShown = true; } - else if (animationFrameShown == false) { + else if (stonesenseState.animationFrameShown == false) { al_clear_to_color(ssConfig.config.backcol); paintboard(); - ovrlay->Flip(); - animationFrameShown = true; + overlay->Flip(); + stonesenseState.animationFrameShown = true; } } - else */ + else { if (ssConfig.spriteIndexOverlay) { DrawSpriteIndexOverlay(ssConfig.currentSpriteOverlay); @@ -430,7 +430,7 @@ static void* stonesense_thread(ALLEGRO_THREAD* main_thread, void* parms) //FIXME: Find a new replacement for the overlay mode. if(stonesenseState.ssConfig.overlay_mode){ - auto overlay = std::make_unique(df::global::enabler->renderer); + overlay = std::make_unique(df::global::enabler->renderer); df::global::enabler->renderer = overlay.get(); } @@ -493,9 +493,9 @@ static void* stonesense_thread(ALLEGRO_THREAD* main_thread, void* parms) // window is destroyed. al_destroy_display(display); display = 0; - /*FIXME: Find a new replacement for the overlay mode. + /*FIXME: Find a new replacement for the overlay mode.*/ overlay.reset(); - */ + if(ssConfig.threadmade) { al_broadcast_cond(ssConfig.readCond); From 2d16edc5d68762e4b2c04139b9c0e0228b8b5680 Mon Sep 17 00:00:00 2001 From: Squid Coder <92821989+realSquidCoder@users.noreply.github.com> Date: Sun, 26 Jan 2025 12:44:22 -0600 Subject: [PATCH 06/21] whitespace --- main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 6f9d16c8..bb5f7d56 100644 --- a/main.cpp +++ b/main.cpp @@ -495,7 +495,7 @@ static void* stonesense_thread(ALLEGRO_THREAD* main_thread, void* parms) display = 0; /*FIXME: Find a new replacement for the overlay mode.*/ overlay.reset(); - + if(ssConfig.threadmade) { al_broadcast_cond(ssConfig.readCond); From 2ab16b9e5ee210e6a3c1b1a6fb4993c0d44fea1c Mon Sep 17 00:00:00 2001 From: Squid Coder <92821989+realSquidCoder@users.noreply.github.com> Date: Tue, 28 Jan 2025 13:24:27 -0600 Subject: [PATCH 07/21] more refactor disable calls to the overlay code and substitute my own version. you can use the stonesense keybinds to move in DF rn if overlay mode is active (impossible rn for unknown reasons) --- Config.cpp | 4 ++ Config.h | 1 + GUI.cpp | 2 +- Keybinds.cpp | 2 + MapLoading.cpp | 2 +- UserInput.cpp | 186 +++++++++++++++++++++++++++++++++++++++---------- UserInput.h | 2 + main.cpp | 104 ++++++++++++++------------- 8 files changed, 217 insertions(+), 86 deletions(-) diff --git a/Config.cpp b/Config.cpp index 5a671aa2..4f7ffd2c 100644 --- a/Config.cpp +++ b/Config.cpp @@ -819,6 +819,10 @@ namespace { } } +bool isViewTracking() { + auto& ssConfig = stonesenseState.ssConfig; + return ssConfig.config.track_mode != Config::TRACKING_NONE; +} bool loadConfigFile() { diff --git a/Config.h b/Config.h index 93b9f0fe..76e597f2 100644 --- a/Config.h +++ b/Config.h @@ -77,5 +77,6 @@ struct action_name_mapper { void (*func)(uint32_t); }; +bool isViewTracking(); bool loadConfigFile(); std::optional trim_line(std::string line); diff --git a/GUI.cpp b/GUI.cpp index bfde84ec..68bf89d4 100644 --- a/GUI.cpp +++ b/GUI.cpp @@ -955,7 +955,7 @@ void paintboard() } ssConfig.platecount = 0; int top = 0; - if(ssConfig.config.track_mode != Config::TRACKING_NONE) { + if(isViewTracking()) { top += fontHeight; draw_textf_border(font, uiColor(1), ssState.ScreenW/2,top, ALLEGRO_ALIGN_CENTRE, "Locked on DF screen + (%d,%d,%d)",ssConfig.config.viewOffset.x,ssConfig.config.viewOffset.y,ssConfig.config.viewOffset.z); } diff --git a/Keybinds.cpp b/Keybinds.cpp index 6b1862b7..1cac5a72 100644 --- a/Keybinds.cpp +++ b/Keybinds.cpp @@ -220,6 +220,8 @@ action_name_mapper actionnamemap[] = { {"INCR_X", action_incrX}, //add extra action here! + {"OPENBUILD", action_openBuild}, + {"INVALID", action_invalid}//this is the stop condition }; diff --git a/MapLoading.cpp b/MapLoading.cpp index 0c82c469..dda841cf 100644 --- a/MapLoading.cpp +++ b/MapLoading.cpp @@ -953,7 +953,7 @@ void read_segment( void *arg) ssState.dfSelection.z = df::global::selection_rect->start_z; } - if (firstLoad || stonesenseState.ssConfig.config.track_mode != Config::TRACKING_NONE) { + if (firstLoad || isViewTracking()) { firstLoad = 0; if (stonesenseState.ssConfig.config.track_mode == Config::TRACKING_CENTER) { followCurrentDFCenter(); diff --git a/UserInput.cpp b/UserInput.cpp index ebb2ad6d..a3e99f0a 100644 --- a/UserInput.cpp +++ b/UserInput.cpp @@ -1,6 +1,7 @@ #include #include "common.h" +#include "df/viewscreen.h" #include "GUI.h" #include "BuildingConfiguration.h" #include "ContentLoader.h" @@ -70,6 +71,12 @@ void abortAutoReload() //remove_int( automaticReloadProc ); } +void sendDFKey(df::interface_key key) { + DFHack::CoreSuspender suspend; + df::viewscreen* screen = DFHack::Gui::getDFViewscreen(); + screen->feed_key(key); +} + void changeRelativeToRotation( int &inputx, int &inputy, int stepx, int stepy ) { auto& ssState = stonesenseState.ssState; @@ -99,7 +106,7 @@ void moveViewRelativeToRotation( int stepx, int stepy ) auto& ssConfig = stonesenseState.ssConfig; auto& ssState = stonesenseState.ssState; - if (ssConfig.config.track_mode != Config::TRACKING_NONE) { + if (isViewTracking()) { changeRelativeToRotation(ssConfig.config.viewOffset.x, ssConfig.config.viewOffset.y, stepx, stepy ); } //if we're following the DF screen, we DO NOT bound the view, since we have a simple way to get back @@ -323,7 +330,7 @@ void action_resetscreen(uint32_t keymod) auto& ssConfig = stonesenseState.ssConfig; auto& ssState = stonesenseState.ssState; - if (ssConfig.config.track_mode != Config::TRACKING_NONE) { + if (isViewTracking()) { ssConfig.config.viewOffset.x = 0; ssConfig.config.viewOffset.y = 0; ssConfig.config.viewOffset.z = 0; @@ -457,16 +464,27 @@ void action_toggledebug(uint32_t keymod) void action_incrzoom(uint32_t keymod) { + auto& ssConfig = stonesenseState.ssConfig; + if (stonesenseState.ssConfig.overlay_mode) { + sendDFKey(df::interface_key::ZOOM_IN); + } + else { auto& ssConfig = stonesenseState.ssConfig; ssConfig.zoom++; ssConfig.recalculateScale(); + } } void action_decrzoom(uint32_t keymod) { auto& ssConfig = stonesenseState.ssConfig; - ssConfig.zoom--; - ssConfig.recalculateScale(); + if (stonesenseState.ssConfig.overlay_mode) { + sendDFKey(df::interface_key::ZOOM_OUT); + } + else { + ssConfig.zoom--; + ssConfig.recalculateScale(); + } } void action_screenshot(uint32_t keymod) @@ -513,6 +531,7 @@ void action_credits(uint32_t keymod) { auto& ssConfig = stonesenseState.ssConfig; ssConfig.creditScreen = false; + sendDFKey(df::interface_key::CURSOR_DOWN); } void action_decrY(uint32_t keymod) @@ -521,11 +540,30 @@ void action_decrY(uint32_t keymod) action_decrsegmentY(keymod); return; } - char stepsize = ((keymod&ALLEGRO_KEYMOD_SHIFT) ? MAPNAVIGATIONSTEPBIG : MAPNAVIGATIONSTEP); - if (!(keymod&ALLEGRO_KEYMOD_ALT)) { - stonesenseState.ssConfig.config.track_mode = Config::TRACKING_NONE; + if (stonesenseState.ssConfig.overlay_mode) { + switch (stonesenseState.ssState.Rotation) { + case 0: + sendDFKey(df::interface_key::CURSOR_UP); + return; + case 1: + sendDFKey(df::interface_key::CURSOR_LEFT); + return; + case 2: + sendDFKey(df::interface_key::CURSOR_DOWN); + return; + case 3: + sendDFKey(df::interface_key::CURSOR_RIGHT); + return; + }; + + } + else { + char stepsize = ((keymod & ALLEGRO_KEYMOD_SHIFT) ? MAPNAVIGATIONSTEPBIG : MAPNAVIGATIONSTEP); + if (!(keymod & ALLEGRO_KEYMOD_ALT)) { + stonesenseState.ssConfig.config.track_mode = Config::TRACKING_NONE; + } + moveViewRelativeToRotation(0, -stepsize); } - moveViewRelativeToRotation( 0, -stepsize ); stonesenseState.timeToReloadSegment = true; } @@ -535,11 +573,28 @@ void action_incrY(uint32_t keymod) action_incrsegmentY(keymod); return; } - char stepsize = ((keymod&ALLEGRO_KEYMOD_SHIFT) ? MAPNAVIGATIONSTEPBIG : MAPNAVIGATIONSTEP); - if (!(keymod&ALLEGRO_KEYMOD_ALT)) { - stonesenseState.ssConfig.config.track_mode = Config::TRACKING_NONE; + if (stonesenseState.ssConfig.overlay_mode) { + switch (stonesenseState.ssState.Rotation) { + case 0: + sendDFKey(df::interface_key::CURSOR_DOWN); + return; + case 1: + sendDFKey(df::interface_key::CURSOR_RIGHT); + return; + case 2: + sendDFKey(df::interface_key::CURSOR_UP); + return; + case 3: + sendDFKey(df::interface_key::CURSOR_LEFT); + return; + }; + }else{ + char stepsize = ((keymod&ALLEGRO_KEYMOD_SHIFT) ? MAPNAVIGATIONSTEPBIG : MAPNAVIGATIONSTEP); + if (!(keymod&ALLEGRO_KEYMOD_ALT)) { + stonesenseState.ssConfig.config.track_mode = Config::TRACKING_NONE; + } + moveViewRelativeToRotation( 0, stepsize ); } - moveViewRelativeToRotation( 0, stepsize ); stonesenseState.timeToReloadSegment = true; } @@ -549,11 +604,29 @@ void action_decrX(uint32_t keymod) action_decrsegmentX(keymod); return; } - char stepsize = ((keymod&ALLEGRO_KEYMOD_SHIFT) ? MAPNAVIGATIONSTEPBIG : MAPNAVIGATIONSTEP); - if (!(keymod&ALLEGRO_KEYMOD_ALT)) { - stonesenseState.ssConfig.config.track_mode = Config::TRACKING_NONE; + if (stonesenseState.ssConfig.overlay_mode) { + switch (stonesenseState.ssState.Rotation) { + case 0: + sendDFKey(df::interface_key::CURSOR_LEFT); + return; + case 1: + sendDFKey(df::interface_key::CURSOR_DOWN); + return; + case 2: + sendDFKey(df::interface_key::CURSOR_RIGHT); + return; + case 3: + sendDFKey(df::interface_key::CURSOR_UP); + return; + }; + } + else { + char stepsize = ((keymod&ALLEGRO_KEYMOD_SHIFT) ? MAPNAVIGATIONSTEPBIG : MAPNAVIGATIONSTEP); + if (!(keymod&ALLEGRO_KEYMOD_ALT)) { + stonesenseState.ssConfig.config.track_mode = Config::TRACKING_NONE; + } + moveViewRelativeToRotation( -stepsize, 0 ); } - moveViewRelativeToRotation( -stepsize, 0 ); stonesenseState.timeToReloadSegment = true; } @@ -564,10 +637,28 @@ void action_incrX(uint32_t keymod) return; } char stepsize = ((keymod&ALLEGRO_KEYMOD_SHIFT) ? MAPNAVIGATIONSTEPBIG : MAPNAVIGATIONSTEP); - if (!(keymod&ALLEGRO_KEYMOD_ALT)) { - stonesenseState.ssConfig.config.track_mode = Config::TRACKING_NONE; + if (stonesenseState.ssConfig.overlay_mode) { + switch (stonesenseState.ssState.Rotation) { + case 0: + sendDFKey(df::interface_key::CURSOR_RIGHT); + return; + case 1: + sendDFKey(df::interface_key::CURSOR_UP); + return; + case 2: + sendDFKey(df::interface_key::CURSOR_LEFT); + return; + case 3: + sendDFKey(df::interface_key::CURSOR_DOWN); + return; + }; + } + else { + if (!(keymod&ALLEGRO_KEYMOD_ALT)) { + stonesenseState.ssConfig.config.track_mode = Config::TRACKING_NONE; + } + moveViewRelativeToRotation( stepsize, 0 ); } - moveViewRelativeToRotation( stepsize, 0 ); stonesenseState.timeToReloadSegment = true; } @@ -580,17 +671,22 @@ void action_decrZ(uint32_t keymod) action_decrsegmentZ(keymod); return; } - char stepsize = ((keymod&ALLEGRO_KEYMOD_SHIFT) ? MAPNAVIGATIONSTEPBIG : MAPNAVIGATIONSTEP); - if (!(keymod&ALLEGRO_KEYMOD_ALT)) { - ssConfig.config.track_mode = Config::TRACKING_NONE; - } - if (ssConfig.config.track_mode != Config::TRACKING_NONE) { - ssConfig.config.viewOffset.z -= stepsize; + if (stonesenseState.ssConfig.overlay_mode) { + sendDFKey(df::interface_key::CURSOR_DOWN_Z); } else { - ssState.Position.z -= stepsize; - } - if(ssState.Position.z<1) { - ssState.Position.z = 1; + char stepsize = ((keymod & ALLEGRO_KEYMOD_SHIFT) ? MAPNAVIGATIONSTEPBIG : MAPNAVIGATIONSTEP); + if (!(keymod & ALLEGRO_KEYMOD_ALT)) { + ssConfig.config.track_mode = Config::TRACKING_NONE; + } + if (isViewTracking()) { + ssConfig.config.viewOffset.z -= stepsize; + } + else { + ssState.Position.z -= stepsize; + } + if (ssState.Position.z < 1) { + ssState.Position.z = 1; + } } stonesenseState.timeToReloadSegment = true; } @@ -604,18 +700,36 @@ void action_incrZ(uint32_t keymod) action_incrsegmentZ(keymod); return; } - char stepsize = ((keymod&ALLEGRO_KEYMOD_SHIFT) ? MAPNAVIGATIONSTEPBIG : MAPNAVIGATIONSTEP); - if (!(keymod&ALLEGRO_KEYMOD_ALT)) { - ssConfig.config.track_mode = Config::TRACKING_NONE; + if (stonesenseState.ssConfig.overlay_mode) { + sendDFKey(df::interface_key::CURSOR_UP_Z); } - if (ssConfig.config.track_mode != Config::TRACKING_NONE) { - ssConfig.config.viewOffset.z += stepsize; - } else { - ssState.Position.z += stepsize; + else { + char stepsize = ((keymod & ALLEGRO_KEYMOD_SHIFT) ? MAPNAVIGATIONSTEPBIG : MAPNAVIGATIONSTEP); + if (!(keymod & ALLEGRO_KEYMOD_ALT)) { + ssConfig.config.track_mode = Config::TRACKING_NONE; + } + if (isViewTracking()) { + ssConfig.config.viewOffset.z += stepsize; + } + else { + ssState.Position.z += stepsize; + } } stonesenseState.timeToReloadSegment = true; } +bool buildMenu = false; +void action_openBuild(uint32_t keymod) +{ + if (buildMenu) { + sendDFKey(df::interface_key::LEAVESCREEN); + buildMenu = false; + }else{ + sendDFKey(df::interface_key::D_BUILDING); + buildMenu = true; + } +} + void doRepeatActions() { al_get_keyboard_state(&stonesenseState.keyboard); diff --git a/UserInput.h b/UserInput.h index 5a5e3cfe..5ce4b8df 100644 --- a/UserInput.h +++ b/UserInput.h @@ -1,5 +1,7 @@ //declarations of actions taken for user keystrokes +void action_openBuild(uint32_t keymod); + void action_incrrotation(uint32_t keymod); void action_reloadsegment(uint32_t keymod); void action_paintboard(uint32_t keymod); diff --git a/main.cpp b/main.cpp index bb5f7d56..69f0a121 100644 --- a/main.cpp +++ b/main.cpp @@ -6,7 +6,7 @@ #include "commonTypes.h" #include "Config.h" -#include "Overlay.h" +//#include "Overlay.h" #include "Tile.h" #include "GUI.h" //#include "SpriteMaps.h" @@ -47,7 +47,7 @@ int keyoffset=0; std::vector v_stonetypes; /*FIXME: Find a new replacement for the overlay mode.*/ -std::unique_ptr overlay; +//std::unique_ptr overlay; ALLEGRO_DISPLAY * display; @@ -226,35 +226,35 @@ static void main_loop(ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE *queue, ALL al_rest(0); /*FIXME: Find a new replacement for the overlay mode.*/ - if (stonesenseState.ssConfig.overlay_mode) - { - bool goodoverlay = overlay->GoodViewscreen(); - if (!goodoverlay) { - //do nothing; this isn't a view we can overlay - }if (ssConfig.spriteIndexOverlay) { - DrawSpriteIndexOverlay(ssConfig.currentSpriteOverlay); - overlay->Flip(); - } - else if (!DFHack::Maps::IsValid()) { - drawcredits(); - overlay->Flip(); - } - else if (stonesenseState.timeToReloadSegment) { - reloadPosition(); - al_clear_to_color(ssConfig.config.backcol); - paintboard(); - overlay->Flip(); - stonesenseState.timeToReloadSegment = false; - stonesenseState.animationFrameShown = true; - } - else if (stonesenseState.animationFrameShown == false) { - al_clear_to_color(ssConfig.config.backcol); - paintboard(); - overlay->Flip(); - stonesenseState.animationFrameShown = true; - } - } - else + //if (stonesenseState.ssConfig.overlay_mode) + //{ + // bool goodoverlay = overlay->GoodViewscreen(); + // if (!goodoverlay) { + // //do nothing; this isn't a view we can overlay + // }if (ssConfig.spriteIndexOverlay) { + // DrawSpriteIndexOverlay(ssConfig.currentSpriteOverlay); + // overlay->Flip(); + // } + // else if (!DFHack::Maps::IsValid()) { + // drawcredits(); + // overlay->Flip(); + // } + // else if (stonesenseState.timeToReloadSegment) { + // reloadPosition(); + // al_clear_to_color(ssConfig.config.backcol); + // paintboard(); + // overlay->Flip(); + // stonesenseState.timeToReloadSegment = false; + // stonesenseState.animationFrameShown = true; + // } + // else if (stonesenseState.animationFrameShown == false) { + // al_clear_to_color(ssConfig.config.backcol); + // paintboard(); + // overlay->Flip(); + // stonesenseState.animationFrameShown = true; + // } + //} + //else { if (ssConfig.spriteIndexOverlay) { DrawSpriteIndexOverlay(ssConfig.currentSpriteOverlay); @@ -280,7 +280,7 @@ static void main_loop(ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE *queue, ALL } } - if (!stonesenseState.ssConfig.overlay_mode) { + if (!stonesenseState.ssConfig.overlay_mode||true) { doMouse(); doRepeatActions(); } @@ -302,9 +302,9 @@ static void main_loop(ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE *queue, ALL if(in_time) { switch (event.type) { case ALLEGRO_EVENT_DISPLAY_RESIZE: - if (stonesenseState.ssConfig.overlay_mode) { - break; - } + //if (stonesenseState.ssConfig.overlay_mode) { + // break; + //} stonesenseState.timeToReloadSegment = true; redraw = true; stonesenseState.ssState.ScreenH = event.display.height; @@ -317,9 +317,9 @@ static void main_loop(ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE *queue, ALL /* ALLEGRO_EVENT_KEY_DOWN - a keyboard key was pressed. */ case ALLEGRO_EVENT_KEY_CHAR: - if (stonesenseState.ssConfig.overlay_mode) { - break; - } + //if (stonesenseState.ssConfig.overlay_mode) { + // break; + //} if(event.keyboard.display != display) { break; } @@ -389,12 +389,19 @@ static void* stonesense_thread(ALLEGRO_THREAD* main_thread, void* parms) out.print("Using allegro version %d.%d.%d r%d\n", major, minor, revision, release); auto& ssConfig = stonesenseState.ssConfig; - al_set_new_display_flags( + /*al_set_new_display_flags( (ssConfig.config.Fullscreen && !stonesenseState.ssConfig.overlay_mode ? ALLEGRO_FULLSCREEN : ALLEGRO_WINDOWED) |(stonesenseState.ssConfig.overlay_mode ? 0 : ALLEGRO_RESIZABLE) |(stonesenseState.ssConfig.overlay_mode ? ALLEGRO_MINIMIZED : 0) |(ssConfig.config.opengl ? ALLEGRO_OPENGL : 0) - |(ssConfig.config.directX ? ALLEGRO_DIRECT3D_INTERNAL : 0)); + |(ssConfig.config.directX ? ALLEGRO_DIRECT3D_INTERNAL : 0));*/ + + al_set_new_display_flags( + (ssConfig.config.Fullscreen ? ALLEGRO_FULLSCREEN : ALLEGRO_WINDOWED) + | (ALLEGRO_RESIZABLE) + | (ALLEGRO_MINIMIZED) + | (ssConfig.config.opengl ? ALLEGRO_OPENGL : 0) + | (ssConfig.config.directX ? ALLEGRO_DIRECT3D_INTERNAL : 0)); if(ssConfig.config.software) { al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP|_ALLEGRO_ALPHA_TEST|ALLEGRO_MIN_LINEAR|ALLEGRO_MIPMAP); @@ -428,11 +435,11 @@ static void* stonesense_thread(ALLEGRO_THREAD* main_thread, void* parms) SetTitle("Stonesense"); drawcredits(); - //FIXME: Find a new replacement for the overlay mode. - if(stonesenseState.ssConfig.overlay_mode){ - overlay = std::make_unique(df::global::enabler->renderer); - df::global::enabler->renderer = overlay.get(); - } + ////FIXME: Find a new replacement for the overlay mode. + // if(stonesenseState.ssConfig.overlay_mode){ + // overlay = std::make_unique(df::global::enabler->renderer); + // df::global::enabler->renderer = overlay.get(); + //} std::filesystem::path p = std::filesystem::path{} / "stonesense" / "stonesense.png"; @@ -494,7 +501,7 @@ static void* stonesense_thread(ALLEGRO_THREAD* main_thread, void* parms) al_destroy_display(display); display = 0; /*FIXME: Find a new replacement for the overlay mode.*/ - overlay.reset(); + //overlay.reset(); if(ssConfig.threadmade) { @@ -568,10 +575,11 @@ DFhackCExport command_result stonesense_command(color_ostream &out, std::vector< out.print("Stonesense already running.\n"); return CR_OK; } - stonesenseState.ssConfig.overlay_mode = false; + auto& ssConfig = stonesenseState.ssConfig; + ssConfig.overlay_mode = false; if(params.size() > 0 ) { if(params[0] == "overlay"){ - stonesenseState.ssConfig.overlay_mode = true; + ssConfig.overlay_mode = true; } else { DumpInfo(out, params); return CR_OK; From 5bf444f01575f1da51b32b4a32b9a23a586c4838 Mon Sep 17 00:00:00 2001 From: Squid Coder Date: Tue, 28 Jan 2025 23:21:20 -0600 Subject: [PATCH 08/21] Perma-enable "overlay" mode and smooth out the movement code --- GameConfiguration.h | 2 +- UserInput.cpp | 22 ++++++++++++++++------ main.cpp | 17 ----------------- 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/GameConfiguration.h b/GameConfiguration.h index 1cf7d6e1..177fb794 100644 --- a/GameConfiguration.h +++ b/GameConfiguration.h @@ -13,7 +13,7 @@ struct GameConfiguration { Config config; // items not configurable via the config file - bool overlay_mode; + bool overlay_mode = true; bool show_designations = true; bool show_announcements = false; bool show_keybinds = false; diff --git a/UserInput.cpp b/UserInput.cpp index a3e99f0a..f48fe22a 100644 --- a/UserInput.cpp +++ b/UserInput.cpp @@ -71,6 +71,15 @@ void abortAutoReload() //remove_int( automaticReloadProc ); } +auto lastMoveTime = clock(); +bool okToMoveView() { + if ((clock() - lastMoveTime >= 50)) { + lastMoveTime = clock(); + return true; + } + return false; +} + void sendDFKey(df::interface_key key) { DFHack::CoreSuspender suspend; df::viewscreen* screen = DFHack::Gui::getDFViewscreen(); @@ -469,9 +478,8 @@ void action_incrzoom(uint32_t keymod) sendDFKey(df::interface_key::ZOOM_IN); } else { - auto& ssConfig = stonesenseState.ssConfig; - ssConfig.zoom++; - ssConfig.recalculateScale(); + ssConfig.zoom++; + ssConfig.recalculateScale(); } } @@ -541,6 +549,7 @@ void action_decrY(uint32_t keymod) return; } if (stonesenseState.ssConfig.overlay_mode) { + if (!okToMoveView()) { return; } switch (stonesenseState.ssState.Rotation) { case 0: sendDFKey(df::interface_key::CURSOR_UP); @@ -555,9 +564,7 @@ void action_decrY(uint32_t keymod) sendDFKey(df::interface_key::CURSOR_RIGHT); return; }; - - } - else { + } else { char stepsize = ((keymod & ALLEGRO_KEYMOD_SHIFT) ? MAPNAVIGATIONSTEPBIG : MAPNAVIGATIONSTEP); if (!(keymod & ALLEGRO_KEYMOD_ALT)) { stonesenseState.ssConfig.config.track_mode = Config::TRACKING_NONE; @@ -574,6 +581,7 @@ void action_incrY(uint32_t keymod) return; } if (stonesenseState.ssConfig.overlay_mode) { + if (!okToMoveView()) { return; } switch (stonesenseState.ssState.Rotation) { case 0: sendDFKey(df::interface_key::CURSOR_DOWN); @@ -605,6 +613,7 @@ void action_decrX(uint32_t keymod) return; } if (stonesenseState.ssConfig.overlay_mode) { + if (!okToMoveView()) { return; } switch (stonesenseState.ssState.Rotation) { case 0: sendDFKey(df::interface_key::CURSOR_LEFT); @@ -638,6 +647,7 @@ void action_incrX(uint32_t keymod) } char stepsize = ((keymod&ALLEGRO_KEYMOD_SHIFT) ? MAPNAVIGATIONSTEPBIG : MAPNAVIGATIONSTEP); if (stonesenseState.ssConfig.overlay_mode) { + if (!okToMoveView()) { return; } switch (stonesenseState.ssState.Rotation) { case 0: sendDFKey(df::interface_key::CURSOR_RIGHT); diff --git a/main.cpp b/main.cpp index 69f0a121..bc498516 100644 --- a/main.cpp +++ b/main.cpp @@ -554,23 +554,6 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out ) //and the actual stonesense command. Maybe. DFhackCExport command_result stonesense_command(color_ostream &out, std::vector & params) { -/* - if (!init->display.flag.is_set(init_display_flags::RENDER_2D) && - !params.empty() && params[0] == "overlay") - { - out.printerr("'stonesense overlay' is not supported in this print mode.\n" - "Try changing PRINT_MODE to 2D or a similar choice in init.txt.\n"); - return CR_FAILURE; - } -#ifdef _DARWIN - if (!init->display.flag.is_set(init_display_flags::RENDER_2D)) - { - out.printerr("The current print mode is not suported\n" - "Change PRINT_MODE in init.txt to 2D or a similar choice\n"); - return CR_FAILURE; - } -#endif -*/ if(stonesense_started) { out.print("Stonesense already running.\n"); return CR_OK; From 38082e44ada88f50de0432c212538375376d8ea0 Mon Sep 17 00:00:00 2001 From: Squid Coder Date: Wed, 29 Jan 2025 16:05:16 -0600 Subject: [PATCH 09/21] First Pass for Immersive info --- GUI.cpp | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++ UserInput.cpp | 48 ++++++++-------- main.cpp | 7 ++- 3 files changed, 180 insertions(+), 26 deletions(-) diff --git a/GUI.cpp b/GUI.cpp index 68bf89d4..5f40c63d 100644 --- a/GUI.cpp +++ b/GUI.cpp @@ -765,6 +765,149 @@ namespace b->tileeffect.density, matName ? matName : "Unknown", subMatName ? "/" : "", subMatName ? subMatName : ""); } } + + void drawGeneralInfo(WorldSegment* segment) + { + using df::global::plotinfo; + auto font = stonesenseState.font; + auto fontHeight = al_get_font_line_height(font); + auto& contentLoader = stonesenseState.contentLoader; + + //get tile info + Tile* b = segment->getTile( + segment->segState.dfCursor.x, + segment->segState.dfCursor.y, + segment->segState.dfCursor.z); + int i = 10; + draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, + "Coord:(%i,%i,%i)", segment->segState.dfCursor.x, segment->segState.dfCursor.y, segment->segState.dfCursor.z); + + if (!b) { + return; + } + int ttype; + const char* tform = NULL; + using df::tiletype_shape_basic; + + if (b->tileShapeBasic() == tiletype_shape_basic::Floor) { + ttype = b->tileType; + tform = "floor"; + } + else if (b->tileShapeBasic() == tiletype_shape_basic::Wall) { + ttype = b->tileType; + tform = "wall"; + } + else if (b->tileShapeBasic() == tiletype_shape_basic::Ramp || + b->tileType == df::tiletype::RampTop) { + ttype = b->tileType; + tform = "ramp"; + } + else if (b->tileShapeBasic() == tiletype_shape_basic::Stair) { + ttype = b->tileType; + tform = "stair"; + } + else { + ttype = -1; + } + if (tform != NULL && b->material.type != INVALID_INDEX) { + const char* formName = lookupFormName(b->consForm); + const char* matName = lookupMaterialTypeName(b->material.type); + const char* subMatName = lookupMaterialName(b->material.type, b->material.index); + draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, + "%s%s%s %s %s", + matName ? matName : "Unknown", + subMatName ? "/" : "", + subMatName ? subMatName : "", + formName, + tform + ); + } + + if (b->building.info && b->building.type != BUILDINGTYPE_NA && b->building.type != BUILDINGTYPE_BLACKBOX && b->building.type != BUILDINGTYPE_TREE) { + const char* matName = lookupMaterialTypeName(b->building.info->material.type); + const char* subMatName = lookupMaterialName(b->building.info->material.type, b->building.info->material.index); + const char* subTypeName = lookupBuildingSubtype(b->building.type, b->building.info->subtype); + draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, + "Building: %s %s", + subTypeName != "NA" ? subTypeName : "", + ENUM_KEY_STR(building_type, (df::building_type)b->building.type).c_str()); + for (size_t index = 0; index < b->building.constructed_mats.size(); index++) { + const char* partMatName = lookupMaterialTypeName(b->building.constructed_mats[index].matt.type); + const char* partSubMatName = lookupMaterialName(b->building.constructed_mats[index].matt.type, b->building.constructed_mats[index].matt.index); + draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, + "Material[%i]: %s%s%s", + index, + partMatName ? partMatName : "Unknown", partSubMatName ? "/" : "", partSubMatName ? partSubMatName : ""); + } + } + else { + + if (tform != NULL && b->material.type != INVALID_INDEX && b->material.index != INVALID_INDEX) { + DFHack::MaterialInfo mat; + mat.decode(b->material.type, b->material.index); + if (mat.isValid()) + { + ALLEGRO_COLOR color = al_map_rgb_f(contentLoader->Mats->color[mat.material->state_color[0]].red, contentLoader->Mats->color[mat.material->state_color[0]].green, contentLoader->Mats->color[mat.material->state_color[0]].blue); + draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, + "Tile: %s %s", mat.material->state_name[0].c_str(), DFHack::enum_item_key_str(b->tileType)); + } + } + + } + + if (b->designation.bits.traffic) { + draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, + "Traffic: %d", b->designation.bits.traffic); + } + if (b->designation.bits.pile) { + draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, + "Stockpile?"); + } + if (b->designation.bits.water_table) { + draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, "Water table"); + } + if (b->designation.bits.rained) { + draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, "Rained"); + } + if (b->Item.item.type >= 0) { + DFHack::MaterialInfo mat; + mat.decode(b->Item.matt.type, b->Item.matt.index); + DFHack::ItemTypeInfo itemdef; + bool subtype = itemdef.decode((df::item_type)b->Item.item.type, b->Item.item.index); + draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, + "Item: %s - %s", + mat.getToken().c_str(), + subtype ? itemdef.getToken().c_str() : ""); + } + + const char* matName = lookupMaterialTypeName(b->tileeffect.matt.type); + const char* subMatName = lookupMaterialName(b->tileeffect.matt.type, b->tileeffect.matt.index); + std::string text{}; + switch (b->tileeffect.type) { + case df::flow_type::Miasma: text = "Miasma"; break; + case df::flow_type::Steam: text = "Steam"; break; + case df::flow_type::Mist: text = "Mist"; break; + case df::flow_type::MaterialDust: text = "MaterialDust"; break; + case df::flow_type::MagmaMist: text = "MagmaMist"; break; + case df::flow_type::Smoke: text = "Smoke"; break; + case df::flow_type::Dragonfire: text = "Dragonfire"; break; + case df::flow_type::Fire: text = "Fire"; break; + case df::flow_type::Web: text = "Web"; break; + case df::flow_type::MaterialGas: text = "MaterialGas"; break; + case df::flow_type::MaterialVapor: text = "MaterialVapor"; break; + case df::flow_type::OceanWave: text = "OceanWave"; break; + case df::flow_type::SeaFoam: text = "SeaFoam"; break; + case df::flow_type::ItemCloud: + // TODO + break; + } + + if (!text.empty()) { + draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, + "%s: %d, Material:%s%s%s", text.c_str(), + b->tileeffect.density, matName ? matName : "Unknown", subMatName ? "/" : "", subMatName ? subMatName : ""); + } + } } void DrawMinimap(WorldSegment * segment) @@ -915,6 +1058,14 @@ void paintboard() draw_announcements(font, ssState.ScreenW, ssState.ScreenH - 10 - al_get_font_line_height(font), ALLEGRO_ALIGN_RIGHT, df::global::world->status.announcements); al_hold_bitmap_drawing(false); } + if (ssConfig.overlay_mode) { + al_hold_bitmap_drawing(true); + ALLEGRO_COLOR red = ssConfig.config.colors.getDfColor(dfColors::lred, ssConfig.config.useDfColors); + draw_textf_border(font, *df::global::pause_state ? red : uiColor(3), 0, 0, ALLEGRO_ALIGN_LEFT, (*df::global::pause_state ? "Paused" : "Running")); + drawDebugCursor(segment); + drawGeneralInfo(segment); + al_hold_bitmap_drawing(false); + } if(ssConfig.show_keybinds){ std::string *keyname, *actionname; keyname = actionname = NULL; diff --git a/UserInput.cpp b/UserInput.cpp index f48fe22a..9814d48c 100644 --- a/UserInput.cpp +++ b/UserInput.cpp @@ -170,23 +170,27 @@ void doMouse() last_mouse_z = mouse.z; } if( mouse.buttons & 2 ) { - ssConfig.config.track_mode = Config::TRACKING_NONE; - int x, y; - x = mouse.x; - y = mouse.y; - int tilex,tiley,tilez; - ScreenToPoint(x,y,tilex,tiley,tilez); - int diffx = tilex - ssState.Size.x/2; - int diffy = tiley - ssState.Size.y/2; - /*we use changeRelativeToRotation directly, and not through moveViewRelativeToRotation - because we don't want to move the offset with the mouse. It just feels weird. */ - // changing to +1,+1 which moves the clicked point to one of the 4 surrounding the center of rotation - changeRelativeToRotation(ssState.Position.x, ssState.Position.y, diffx+1, diffy+1 ); - //moveViewRelativeToRotation(diffx+1, diffy+1); - stonesenseState.timeToReloadSegment = true; - //rest(50); + if (ssConfig.overlay_mode) { + sendDFKey(df::interface_key::LEAVESCREEN); + }else{ + ssConfig.config.track_mode = Config::TRACKING_NONE; + int x, y; + x = mouse.x; + y = mouse.y; + int tilex,tiley,tilez; + ScreenToPoint(x,y,tilex,tiley,tilez); + int diffx = tilex - ssState.Size.x/2; + int diffy = tiley - ssState.Size.y/2; + /*we use changeRelativeToRotation directly, and not through moveViewRelativeToRotation + because we don't want to move the offset with the mouse. It just feels weird. */ + // changing to +1,+1 which moves the clicked point to one of the 4 surrounding the center of rotation + changeRelativeToRotation(ssState.Position.x, ssState.Position.y, diffx+1, diffy+1 ); + //moveViewRelativeToRotation(diffx+1, diffy+1); + stonesenseState.timeToReloadSegment = true; + //rest(50); + } } - if( mouse.buttons & 1 ) { + if( mouse.buttons & 1 || ssConfig.overlay_mode) { ssConfig.config.follow_DFcursor = false; int x, y; x = mouse.x;//pos >> 16; @@ -194,7 +198,8 @@ void doMouse() if(x >= stonesenseState.MiniMapTopLeftX && x <= stonesenseState.MiniMapBottomRightX && y >= stonesenseState.MiniMapTopLeftY && - y <= stonesenseState.MiniMapBottomRightY) { // in minimap + y <= stonesenseState.MiniMapBottomRightY && + mouse.buttons & 1) { // clicking in minimap (we recheck the button for immersive mode ssState.Position.x = (x- stonesenseState.MiniMapTopLeftX- stonesenseState.MiniMapSegmentWidth/2)/ stonesenseState.oneTileInPixels; ssState.Position.y = (y- stonesenseState.MiniMapTopLeftY- stonesenseState.MiniMapSegmentHeight/2)/ stonesenseState.oneTileInPixels; } else { @@ -728,16 +733,9 @@ void action_incrZ(uint32_t keymod) stonesenseState.timeToReloadSegment = true; } -bool buildMenu = false; void action_openBuild(uint32_t keymod) { - if (buildMenu) { - sendDFKey(df::interface_key::LEAVESCREEN); - buildMenu = false; - }else{ - sendDFKey(df::interface_key::D_BUILDING); - buildMenu = true; - } + sendDFKey(df::interface_key::D_BUILDING); } void doRepeatActions() diff --git a/main.cpp b/main.cpp index bc498516..bfd7a951 100644 --- a/main.cpp +++ b/main.cpp @@ -406,7 +406,12 @@ static void* stonesense_thread(ALLEGRO_THREAD* main_thread, void* parms) if(ssConfig.config.software) { al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP|_ALLEGRO_ALPHA_TEST|ALLEGRO_MIN_LINEAR|ALLEGRO_MIPMAP); } else { - al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR|ALLEGRO_MIPMAP); + // FIXME: When we have ability to set a maximum mipmap lod, + // do so when cache_images is enabled to prevent sprites going transparent. + // Until then, disable mipmapping when using an image cache. + al_set_new_bitmap_flags( + ALLEGRO_MIN_LINEAR + |(ssConfig.config.cache_images ? 0 : ALLEGRO_MIPMAP)); } display = al_create_display(stonesenseState.ssState.ScreenW, stonesenseState.ssState.ScreenH); From c2035385d49367de83fe75ace43f2536ec368c59 Mon Sep 17 00:00:00 2001 From: Squid Coder Date: Wed, 29 Jan 2025 23:49:06 -0600 Subject: [PATCH 10/21] clicking in immersive mode is now a lot like using the cursor --- CMakeLists.txt | 4 ++-- GUI.cpp | 4 ++++ UserInput.cpp | 11 ++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e27118e..86523689 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ install(DIRECTORY ${CMAKE_SOURCE_DIR}/plugins/stonesense/configs/ SET(PROJECT_SRCS TrackingModes.cpp - Overlay.cpp + #Overlay.cpp Tile.cpp TileCondition.cpp TileTree.cpp @@ -64,7 +64,7 @@ SET(PROJECT_HDRS MapLoading.h MaterialMatcher.h OcclusionTest.h - Overlay.h + #Overlay.h SegmentProcessing.h SpriteColors.h SpriteMaps.h diff --git a/GUI.cpp b/GUI.cpp index 5f40c63d..540dd617 100644 --- a/GUI.cpp +++ b/GUI.cpp @@ -519,6 +519,10 @@ namespace auto& ssConfig = stonesenseState.ssConfig; Crd3D cursor = segment->segState.dfCursor; + DFHack::Gui::setCursorCoords( + cursor.x, + cursor.y, + cursor.z); segment->CorrectTileForSegmentOffset(cursor.x, cursor.y, cursor.z); segment->CorrectTileForSegmentRotation(cursor.x, cursor.y, cursor.z); diff --git a/UserInput.cpp b/UserInput.cpp index 9814d48c..6f96661e 100644 --- a/UserInput.cpp +++ b/UserInput.cpp @@ -137,7 +137,7 @@ void moveViewRelativeToRotation( int stepx, int stepy ) } } - +bool mouseDown = false; void doMouse() { auto& ssConfig = stonesenseState.ssConfig; @@ -227,6 +227,15 @@ void doMouse() ssState.dfCursor.z = tilez; } stonesenseState.timeToReloadSegment = true; + if (ssConfig.overlay_mode && mouse.buttons & 1) { + if (!mouseDown) { + sendDFKey(df::interface_key::SELECT); + mouseDown = true; + } + } + else { + mouseDown = false; + } } } From c113c45ce64fde3439af81ee1ab17a52d4d64e9d Mon Sep 17 00:00:00 2001 From: Squid Coder Date: Thu, 30 Jan 2025 01:22:54 -0600 Subject: [PATCH 11/21] bunch of controls to test and dbug with --- Keybinds.cpp | 14 +++++++++++++- UserInput.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++-- UserInput.h | 16 +++++++++++++++- 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/Keybinds.cpp b/Keybinds.cpp index 1cac5a72..da47d661 100644 --- a/Keybinds.cpp +++ b/Keybinds.cpp @@ -220,7 +220,19 @@ action_name_mapper actionnamemap[] = { {"INCR_X", action_incrX}, //add extra action here! - {"OPENBUILD", action_openBuild}, + {"TOGGLEPAUSE", action_togglePause}, + {"OPENDIG", action_openDig}, + {"DESIGNSTAIRS", action_designStairs}, + {"DESIGNRAMP", action_designRamp}, + {"DESIGNCHANNEL", action_designChannel}, + {"REMOVEDESIGN", action_removeDesign}, + + {"OPENSMOOTH", action_openSmooth}, + {"DESIGNENGRAVE", action_designEngrave}, + {"DESIGNTRACK", action_designTrack}, + {"DESIGNFORTIFY", action_designFortify}, + + {"DESIGNERASE", action_designErase}, {"INVALID", action_invalid}//this is the stop condition }; diff --git a/UserInput.cpp b/UserInput.cpp index 6f96661e..c6130ae7 100644 --- a/UserInput.cpp +++ b/UserInput.cpp @@ -742,9 +742,50 @@ void action_incrZ(uint32_t keymod) stonesenseState.timeToReloadSegment = true; } -void action_openBuild(uint32_t keymod) +void action_openDig(uint32_t keymod){ + sendDFKey(df::interface_key::D_DESIGNATE_DIG); + sendDFKey(df::interface_key::DESIGNATE_DIG); +} +void action_designStairs(uint32_t keymod){ + sendDFKey(df::interface_key::DESIGNATE_STAIR_UPDOWN); +} +void action_designRamp(uint32_t keymod){ + sendDFKey(df::interface_key::DESIGNATE_RAMP); +} +void action_designChannel(uint32_t keymod){ + sendDFKey(df::interface_key::DESIGNATE_CHANNEL); +} +void action_removeDesign(uint32_t keymod){ + sendDFKey(df::interface_key::DESIGNATE_DIG_REMOVE_STAIRS_RAMPS); +} + +void action_openSmooth(uint32_t keymod) +{ + sendDFKey(df::interface_key::D_DESIGNATE_SMOOTH); + sendDFKey(df::interface_key::DESIGNATE_SMOOTH); +} +void action_designEngrave(uint32_t keymod) +{ + sendDFKey(df::interface_key::DESIGNATE_ENGRAVE); +} +void action_designTrack(uint32_t keymod) +{ + sendDFKey(df::interface_key::DESIGNATE_TRACK); +} +void action_designFortify(uint32_t keymod) +{ + sendDFKey(df::interface_key::DESIGNATE_FORTIFY); +} + +void action_designErase(uint32_t keymod) +{ + sendDFKey(df::interface_key::D_DESIGNATE_ERASE); +} + + +void action_togglePause(uint32_t keymod) { - sendDFKey(df::interface_key::D_BUILDING); + sendDFKey(df::interface_key::D_PAUSE); } void doRepeatActions() diff --git a/UserInput.h b/UserInput.h index 5ce4b8df..21551e1d 100644 --- a/UserInput.h +++ b/UserInput.h @@ -1,6 +1,20 @@ //declarations of actions taken for user keystrokes -void action_openBuild(uint32_t keymod); +void action_openDig(uint32_t keymod); +void action_designStairs(uint32_t keymod); +void action_designRamp(uint32_t keymod); +void action_designChannel(uint32_t keymod); +void action_removeDesign(uint32_t keymod); + +void action_openSmooth(uint32_t keymod); +void action_designEngrave(uint32_t keymod); +void action_designTrack(uint32_t keymod); +void action_designFortify(uint32_t keymod); + +void action_designErase(uint32_t keymod); + +void action_togglePause(uint32_t keymod); + void action_incrrotation(uint32_t keymod); void action_reloadsegment(uint32_t keymod); From fc331dcc385571579b6ea09d8db169a8141973ff Mon Sep 17 00:00:00 2001 From: Squid Coder Date: Thu, 30 Jan 2025 16:40:27 -0600 Subject: [PATCH 12/21] Stonesense Immersive Mode now can do most designations --- GUI.cpp | 75 ++++++++++++++++-- GameState.h | 19 +++++ Keybinds.cpp | 21 +++-- UserInput.cpp | 210 ++++++++++++++++++++++++++++++++++++++++++-------- UserInput.h | 20 ++--- main.cpp | 3 + 6 files changed, 284 insertions(+), 64 deletions(-) diff --git a/GUI.cpp b/GUI.cpp index 540dd617..11d02c4f 100644 --- a/GUI.cpp +++ b/GUI.cpp @@ -782,37 +782,96 @@ namespace segment->segState.dfCursor.x, segment->segState.dfCursor.y, segment->segState.dfCursor.z); - int i = 10; + + int i = 1; + draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, "Coord:(%i,%i,%i)", segment->segState.dfCursor.x, segment->segState.dfCursor.y, segment->segState.dfCursor.z); if (!b) { return; } - int ttype; const char* tform = NULL; using df::tiletype_shape_basic; if (b->tileShapeBasic() == tiletype_shape_basic::Floor) { - ttype = b->tileType; tform = "floor"; } else if (b->tileShapeBasic() == tiletype_shape_basic::Wall) { - ttype = b->tileType; tform = "wall"; } else if (b->tileShapeBasic() == tiletype_shape_basic::Ramp || b->tileType == df::tiletype::RampTop) { - ttype = b->tileType; tform = "ramp"; } else if (b->tileShapeBasic() == tiletype_shape_basic::Stair) { - ttype = b->tileType; tform = "stair"; } - else { - ttype = -1; + + auto modeStr = ""; + std::vector options = {""}; + switch (stonesenseState.ssState.mode) { + case 0: //Default + modeStr = "DEFAULT"; + options = { "Dig", "Chop", "Gather", "Smooth", "Erase"}; + break; + case 1: //Dig + modeStr = "DIGGING"; + options = {"Dig", "Stairs", "Ramp", "Channel", "Remove"}; + break; + case 2: //Chop + modeStr = "CHOP"; + options = { "Chop", "-", "-", "-", "-" }; + break; + case 3: //Gather + modeStr = "GATHER"; + options = { "Gather", "-", "-", "-", "-"}; + break; + case 4: //Smooth + modeStr = "SMOOTH"; + options = { "Smooth", "Engrave", "Carve Track", "Fortification", "-"}; + break; + case 5: //Erase + modeStr = "ERASER"; + options = { "Erase", "-", "-", "-", "-"}; + break; + break; + case 6: //Building + modeStr = "BUILDING"; + options = { "Build", "-", "-", "-", "-" }; + break; + break; + case 7: //Traffic + modeStr = "TRAFFIC"; + options = { "High", "Medium", "Low", "Restricted", "-"}; + break; + }; + + // Draw mode string + draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, modeStr); + i++; + + // Draw each option in the list + int idx = 1; + for (const auto& option : options) { + if (!option.empty()) { + std::string displayText = "Option" + std::to_string(idx) + ": " + option; + draw_textf_border(font, stonesenseState.ssState.submode == option ? uiColor(2) : uiColor(1), + 2, (i++ * fontHeight), 0, displayText.c_str()); + } + idx++; + } + if (stonesenseState.ssState.mode == 1 || //Dig + stonesenseState.ssState.mode == 2 || //Chop + stonesenseState.ssState.mode == 3 || //Gather + stonesenseState.ssState.mode == 4 || //Smooth + stonesenseState.ssState.mode == 5 || //Erase + stonesenseState.ssState.mode == 7) { //Traffic + draw_textf_border(font, stonesenseState.ssState.rectangleSelect ? uiColor(2) : uiColor(1), 2, (i++ * fontHeight), 0, "Rectangle"); + draw_textf_border(font, !stonesenseState.ssState.rectangleSelect ? uiColor(2) : uiColor(1), 2, (i++ * fontHeight), 0, "FreeDraw"); + draw_textf_border(font, stonesenseState.ssState.blueprinting ? uiColor(2) : uiColor(1), 2, (i++ * fontHeight), 0, "Blueprint Mode"); } + if (tform != NULL && b->material.type != INVALID_INDEX) { const char* formName = lookupFormName(b->consForm); const char* matName = lookupMaterialTypeName(b->material.type); diff --git a/GameState.h b/GameState.h index 4bcd3a3e..43fdcfe0 100644 --- a/GameState.h +++ b/GameState.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "common.h" #include "commonTypes.h" @@ -22,4 +23,22 @@ struct GameState{ //the width and height of the stonesense window int ScreenW; int ScreenH; + + bool blueprinting = false; + bool rectangleSelect = true; + + enum modeTypes { + DEFAULT, + DIG, + CHOP, + GATHER, + SMOOTH, + ERASE, + BUILDING, + TRAFFIC, + }; + + //the current mode we're in + enum modeTypes mode = DEFAULT; + std::string submode = "None"; }; diff --git a/Keybinds.cpp b/Keybinds.cpp index da47d661..4773dc0c 100644 --- a/Keybinds.cpp +++ b/Keybinds.cpp @@ -221,18 +221,15 @@ action_name_mapper actionnamemap[] = { //add extra action here! {"TOGGLEPAUSE", action_togglePause}, - {"OPENDIG", action_openDig}, - {"DESIGNSTAIRS", action_designStairs}, - {"DESIGNRAMP", action_designRamp}, - {"DESIGNCHANNEL", action_designChannel}, - {"REMOVEDESIGN", action_removeDesign}, - - {"OPENSMOOTH", action_openSmooth}, - {"DESIGNENGRAVE", action_designEngrave}, - {"DESIGNTRACK", action_designTrack}, - {"DESIGNFORTIFY", action_designFortify}, - - {"DESIGNERASE", action_designErase}, + + {"OPTION1",action_option1}, + {"OPTION2",action_option2}, + {"OPTION3",action_option3}, + {"OPTION4",action_option4}, + {"OPTION5",action_option5}, + {"OPTION6",action_option6}, + {"OPTION7",action_option7}, + {"OPTION8",action_option8}, {"INVALID", action_invalid}//this is the stop condition }; diff --git a/UserInput.cpp b/UserInput.cpp index c6130ae7..e93f1ebf 100644 --- a/UserInput.cpp +++ b/UserInput.cpp @@ -742,47 +742,193 @@ void action_incrZ(uint32_t keymod) stonesenseState.timeToReloadSegment = true; } -void action_openDig(uint32_t keymod){ - sendDFKey(df::interface_key::D_DESIGNATE_DIG); - sendDFKey(df::interface_key::DESIGNATE_DIG); -} -void action_designStairs(uint32_t keymod){ - sendDFKey(df::interface_key::DESIGNATE_STAIR_UPDOWN); -} -void action_designRamp(uint32_t keymod){ - sendDFKey(df::interface_key::DESIGNATE_RAMP); +void action_option1(uint32_t keymod) { + switch (stonesenseState.ssState.mode) { + case 0: //Default + sendDFKey(df::interface_key::D_DESIGNATE_DIG); + stonesenseState.ssState.mode = GameState::modeTypes::DIG; + stonesenseState.ssState.submode = "Dig"; + break; + case 1: //Dig + sendDFKey(df::interface_key::DESIGNATE_DIG); + stonesenseState.ssState.submode = "Dig"; + break; + case 2: //Chop + break; + case 3: //Gather + break; + case 4: //Smooth + sendDFKey(df::interface_key::DESIGNATE_SMOOTH); + stonesenseState.ssState.submode = "Smooth"; + break; + case 5: //Erase + break; + case 6: //Building + break; + case 7: //Traffic + break; + }; } -void action_designChannel(uint32_t keymod){ - sendDFKey(df::interface_key::DESIGNATE_CHANNEL); +void action_option2(uint32_t keymod) { + switch (stonesenseState.ssState.mode) { + case 0: //Default + sendDFKey(df::interface_key::D_DESIGNATE_CHOP); + stonesenseState.ssState.mode = GameState::modeTypes::CHOP; + break; + case 1: //Dig + sendDFKey(df::interface_key::DESIGNATE_STAIR_UPDOWN); + stonesenseState.ssState.submode = "Stairs"; + break; + case 2: //Chop + break; + case 3: //Gather + break; + case 4: //Smooth + sendDFKey(df::interface_key::DESIGNATE_ENGRAVE); + stonesenseState.ssState.submode = "Engrave"; + break; + case 5: //Erase + break; + case 6: //Building + break; + case 7: //Traffic + break; + }; } -void action_removeDesign(uint32_t keymod){ - sendDFKey(df::interface_key::DESIGNATE_DIG_REMOVE_STAIRS_RAMPS); +void action_option3(uint32_t keymod) { + switch (stonesenseState.ssState.mode) { + case 0: //Default + sendDFKey(df::interface_key::D_DESIGNATE_GATHER); + stonesenseState.ssState.mode = GameState::modeTypes::GATHER; + break; + case 1: //Dig + sendDFKey(df::interface_key::DESIGNATE_RAMP); + stonesenseState.ssState.submode = "Ramp"; + break; + case 2: //Chop + break; + case 3: //Gather + break; + case 4: //Smooth + sendDFKey(df::interface_key::DESIGNATE_TRACK); + stonesenseState.ssState.submode = "Carve Track"; + break; + case 5: //Erase + break; + case 6: //Building + break; + case 7: //Traffic + break; + }; } - -void action_openSmooth(uint32_t keymod) -{ - sendDFKey(df::interface_key::D_DESIGNATE_SMOOTH); - sendDFKey(df::interface_key::DESIGNATE_SMOOTH); +void action_option4(uint32_t keymod) { + switch (stonesenseState.ssState.mode) { + case 0: //Default + sendDFKey(df::interface_key::D_DESIGNATE_SMOOTH); + stonesenseState.ssState.mode = GameState::modeTypes::SMOOTH; + break; + case 1: //Dig + sendDFKey(df::interface_key::DESIGNATE_CHANNEL); + stonesenseState.ssState.submode = "Channel"; + break; + case 2: //Chop + break; + case 3: //Gather + break; + case 4: //Smooth + sendDFKey(df::interface_key::DESIGNATE_FORTIFY); + stonesenseState.ssState.submode = "Fortification"; + break; + case 5: //Erase + break; + case 6: //Building + break; + case 7: //Traffic + break; + }; } -void action_designEngrave(uint32_t keymod) -{ - sendDFKey(df::interface_key::DESIGNATE_ENGRAVE); +void action_option5(uint32_t keymod) { + switch (stonesenseState.ssState.mode) { + case 0: //Default + sendDFKey(df::interface_key::D_DESIGNATE_ERASE); + stonesenseState.ssState.mode = GameState::modeTypes::ERASE; + break; + case 1: //Dig + sendDFKey(df::interface_key::DESIGNATE_DIG_REMOVE_STAIRS_RAMPS); + stonesenseState.ssState.submode = "Remove"; + break; + case 2: //Chop + break; + case 3: //Gather + break; + case 4: //Smooth + break; + case 5: //Erase + break; + case 6: //Building + break; + case 7: //Traffic + break; + }; } -void action_designTrack(uint32_t keymod) -{ - sendDFKey(df::interface_key::DESIGNATE_TRACK); +void action_option6(uint32_t keymod) { + switch (stonesenseState.ssState.mode) { + case 0: //Default + break; + case 1: //Dig + case 2: //Chop + case 3: //Gather + case 4: //Smooth + case 5: //Erase + sendDFKey(df::interface_key::DESIGNATE_RECTANGLE); + stonesenseState.ssState.rectangleSelect = true; + break; + case 6: //Building + break; + case 7: //Traffic + break; + }; } -void action_designFortify(uint32_t keymod) -{ - sendDFKey(df::interface_key::DESIGNATE_FORTIFY); +void action_option7(uint32_t keymod) { + switch (stonesenseState.ssState.mode) { + case 0: //Default + break; + case 1: //Dig + case 2: //Chop + case 3: //Gather + case 4: //Smooth + case 5: //Erase + sendDFKey(df::interface_key::DESIGNATE_FREE_DRAW); + stonesenseState.ssState.rectangleSelect = false; + break; + case 6: //Building + break; + case 7: //Traffic + break; + }; } - -void action_designErase(uint32_t keymod) -{ - sendDFKey(df::interface_key::D_DESIGNATE_ERASE); +void action_option8(uint32_t keymod) { + switch (stonesenseState.ssState.mode) { + case 0: //Default + break; + case 1: //Dig + case 2: //Chop + case 3: //Gather + case 4: //Smooth + sendDFKey(df::interface_key::DESIGNATE_TOGGLE_ADVANCED_OPTIONS); + sendDFKey(df::interface_key::DESIGNATE_TOGGLE_MARKER); + sendDFKey(df::interface_key::DESIGNATE_TOGGLE_ADVANCED_OPTIONS); + stonesenseState.ssState.blueprinting = !stonesenseState.ssState.blueprinting; + break; + case 5: //Erase + break; + case 6: //Building + break; + case 7: //Traffic + break; + }; } - void action_togglePause(uint32_t keymod) { sendDFKey(df::interface_key::D_PAUSE); diff --git a/UserInput.h b/UserInput.h index 21551e1d..e7ca4341 100644 --- a/UserInput.h +++ b/UserInput.h @@ -1,17 +1,13 @@ //declarations of actions taken for user keystrokes -void action_openDig(uint32_t keymod); -void action_designStairs(uint32_t keymod); -void action_designRamp(uint32_t keymod); -void action_designChannel(uint32_t keymod); -void action_removeDesign(uint32_t keymod); - -void action_openSmooth(uint32_t keymod); -void action_designEngrave(uint32_t keymod); -void action_designTrack(uint32_t keymod); -void action_designFortify(uint32_t keymod); - -void action_designErase(uint32_t keymod); +void action_option1(uint32_t keymod); +void action_option2(uint32_t keymod); +void action_option3(uint32_t keymod); +void action_option4(uint32_t keymod); +void action_option5(uint32_t keymod); +void action_option6(uint32_t keymod); +void action_option7(uint32_t keymod); +void action_option8(uint32_t keymod); void action_togglePause(uint32_t keymod); diff --git a/main.cpp b/main.cpp index bfd7a951..a5f3a940 100644 --- a/main.cpp +++ b/main.cpp @@ -221,6 +221,9 @@ static void main_loop(ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE *queue, ALL ALLEGRO_EVENT event; while (!al_get_thread_should_stop(main_thread)) { + if (DFHack::Gui::getCurFocus().front().starts_with("dwarfmode/Default")) { + stonesenseState.ssState.mode = GameState::modeTypes::DEFAULT; + } if (redraw && al_event_queue_is_empty(queue)) { al_rest(0); From cc0ed487fef43c1e68e11efc021f873f5dbbbc59 Mon Sep 17 00:00:00 2001 From: Squid Coder Date: Thu, 30 Jan 2025 17:07:14 -0600 Subject: [PATCH 13/21] Fix warnings as errors --- GUI.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/GUI.cpp b/GUI.cpp index 11d02c4f..39d56494 100644 --- a/GUI.cpp +++ b/GUI.cpp @@ -775,7 +775,6 @@ namespace using df::global::plotinfo; auto font = stonesenseState.font; auto fontHeight = al_get_font_line_height(font); - auto& contentLoader = stonesenseState.contentLoader; //get tile info Tile* b = segment->getTile( @@ -887,12 +886,10 @@ namespace } if (b->building.info && b->building.type != BUILDINGTYPE_NA && b->building.type != BUILDINGTYPE_BLACKBOX && b->building.type != BUILDINGTYPE_TREE) { - const char* matName = lookupMaterialTypeName(b->building.info->material.type); - const char* subMatName = lookupMaterialName(b->building.info->material.type, b->building.info->material.index); const char* subTypeName = lookupBuildingSubtype(b->building.type, b->building.info->subtype); draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, "Building: %s %s", - subTypeName != "NA" ? subTypeName : "", + std::string(subTypeName) != "NA" ? subTypeName : "", ENUM_KEY_STR(building_type, (df::building_type)b->building.type).c_str()); for (size_t index = 0; index < b->building.constructed_mats.size(); index++) { const char* partMatName = lookupMaterialTypeName(b->building.constructed_mats[index].matt.type); @@ -910,7 +907,6 @@ namespace mat.decode(b->material.type, b->material.index); if (mat.isValid()) { - ALLEGRO_COLOR color = al_map_rgb_f(contentLoader->Mats->color[mat.material->state_color[0]].red, contentLoader->Mats->color[mat.material->state_color[0]].green, contentLoader->Mats->color[mat.material->state_color[0]].blue); draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, "Tile: %s %s", mat.material->state_name[0].c_str(), DFHack::enum_item_key_str(b->tileType)); } From 422986a277088bf17eef8b5264d9aa6ecaf3d913 Mon Sep 17 00:00:00 2001 From: Squid Coder Date: Sat, 1 Feb 2025 02:37:38 -0600 Subject: [PATCH 14/21] various changes see description Blueprints look different from normal designations improved my new option key interface. --- GUI.cpp | 114 ++++++++++++++++++++++++------------------ SegmentProcessing.cpp | 7 +++ SpriteObjects.cpp | 1 + Tile.cpp | 11 ++++ Tile.h | 2 + UserInput.cpp | 25 ++++++++- common.h | 4 ++ main.cpp | 1 + 8 files changed, 113 insertions(+), 52 deletions(-) diff --git a/GUI.cpp b/GUI.cpp index 39d56494..b661e706 100644 --- a/GUI.cpp +++ b/GUI.cpp @@ -463,7 +463,6 @@ void DrawCurrentLevelOutline(bool backPart) p3.y += FLOORHEIGHT*ssConfig.scale; p4.y += FLOORHEIGHT*ssConfig.scale; if(backPart) { - al_draw_line(p1.x, p1.y, p1.x, p1.y-TILEHEIGHT*ssConfig.scale, uiColor(0), 0); al_draw_line(p1.x, p1.y, p1.x, p1.y-TILEHEIGHT*ssConfig.scale, uiColor(0), 0); al_draw_line(p1.x, p1.y, p2.x, p2.y, uiColor(0), 0); al_draw_line(p1.x, p1.y-TILEHEIGHT*ssConfig.scale, p2.x, p2.y-TILEHEIGHT*ssConfig.scale, uiColor(0), 0); @@ -488,15 +487,14 @@ namespace { auto& ssConfig = stonesenseState.ssConfig; - Crd3D selection = segment->segState.dfSelection; - if ((selection.x != -30000 && ssConfig.config.follow_DFcursor) - || (ssConfig.config.track_mode == Config::TRACKING_FOCUS)) { - segment->CorrectTileForSegmentOffset(selection.x, selection.y, selection.z); - segment->CorrectTileForSegmentRotation(selection.x, selection.y, selection.z); - } - else { - return; - } + Crd3D selection; + (stonesenseState.ssConfig.overlay_mode) ? selection = segment->segState.dfCursor : selection = segment->segState.dfSelection; + DFHack::Gui::setCursorCoords( + selection.x, + selection.y, + selection.z); + segment->CorrectTileForSegmentOffset(selection.x, selection.y, selection.z); + segment->CorrectTileForSegmentRotation(selection.x, selection.y, selection.z); Crd2D point = LocalTileToScreen(selection.x, selection.y, selection.z); int sheetx = SPRITEOBJECT_CURSOR % SHEET_OBJECTSWIDE; int sheety = SPRITEOBJECT_CURSOR / SHEET_OBJECTSWIDE; @@ -809,45 +807,61 @@ namespace auto modeStr = ""; std::vector options = {""}; - switch (stonesenseState.ssState.mode) { - case 0: //Default - modeStr = "DEFAULT"; - options = { "Dig", "Chop", "Gather", "Smooth", "Erase"}; - break; - case 1: //Dig - modeStr = "DIGGING"; - options = {"Dig", "Stairs", "Ramp", "Channel", "Remove"}; - break; - case 2: //Chop - modeStr = "CHOP"; - options = { "Chop", "-", "-", "-", "-" }; - break; - case 3: //Gather - modeStr = "GATHER"; - options = { "Gather", "-", "-", "-", "-"}; - break; - case 4: //Smooth - modeStr = "SMOOTH"; - options = { "Smooth", "Engrave", "Carve Track", "Fortification", "-"}; - break; - case 5: //Erase - modeStr = "ERASER"; - options = { "Erase", "-", "-", "-", "-"}; - break; - break; - case 6: //Building - modeStr = "BUILDING"; - options = { "Build", "-", "-", "-", "-" }; - break; - break; - case 7: //Traffic - modeStr = "TRAFFIC"; - options = { "High", "Medium", "Low", "Restricted", "-"}; - break; - }; + auto keymods = getKeyMods(&stonesenseState.keyboard); + if (keymods & ALLEGRO_KEYMOD_SHIFT) { + options = { + "Toggle Names", + "Cycle Professions", + "Toggle Moods", + "Toggle Zones", + "Toggle Stockpiles", + "Toggle Designations", + }; + } else { + switch (stonesenseState.ssState.mode) { + case 0: //Default + modeStr = "DEFAULT"; + options = { "Dig", "Chop", "Gather", "Smooth", "Erase" }; + break; + case 1: //Dig + modeStr = "DIGGING"; + options = { "Dig", "Stairs", "Ramp", "Channel", "Remove" }; + break; + case 2: //Chop + modeStr = "CHOP"; + options = { "Chop", "-", "-", "-", "-" }; + break; + case 3: //Gather + modeStr = "GATHER"; + options = { "Gather", "-", "-", "-", "-" }; + break; + case 4: //Smooth + modeStr = "SMOOTH"; + options = { "Smooth", "Engrave", "Carve Track", "Fortification", "-" }; + break; + case 5: //Erase + modeStr = "ERASER"; + options = { "Erase", "-", "-", "-", "-" }; + break; + break; + case 6: //Building + modeStr = "BUILDING"; + options = { "Build", "-", "-", "-", "-" }; + break; + break; + case 7: //Traffic + modeStr = "TRAFFIC"; + options = { "High", "Medium", "Low", "Restricted", "-" }; + break; + }; + } // Draw mode string draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, modeStr); + draw_textf_border(font, (keymods & ALLEGRO_KEYMOD_SHIFT) ? uiColor(2) : uiColor(1), 2, (i * fontHeight), 0, "Shift "); + draw_textf_border(font, (keymods & ALLEGRO_KEYMOD_CTRL) ? uiColor(2) : uiColor(1), 2 + al_get_text_width(font, "Shift "), (i * fontHeight), 0, "Ctrl "); + draw_textf_border(font, (keymods & ALLEGRO_KEYMOD_ALT) ? uiColor(2) : uiColor(1), 2 + al_get_text_width(font, "Shift Ctrl "), (i * fontHeight), 0, "Alt"); + i++; // Draw each option in the list @@ -866,9 +880,9 @@ namespace stonesenseState.ssState.mode == 4 || //Smooth stonesenseState.ssState.mode == 5 || //Erase stonesenseState.ssState.mode == 7) { //Traffic - draw_textf_border(font, stonesenseState.ssState.rectangleSelect ? uiColor(2) : uiColor(1), 2, (i++ * fontHeight), 0, "Rectangle"); - draw_textf_border(font, !stonesenseState.ssState.rectangleSelect ? uiColor(2) : uiColor(1), 2, (i++ * fontHeight), 0, "FreeDraw"); - draw_textf_border(font, stonesenseState.ssState.blueprinting ? uiColor(2) : uiColor(1), 2, (i++ * fontHeight), 0, "Blueprint Mode"); + draw_textf_border(font, stonesenseState.ssState.rectangleSelect ? uiColor(2) : uiColor(1), 2, (i++ * fontHeight), 0, "Option6: Rectangle"); + draw_textf_border(font, !stonesenseState.ssState.rectangleSelect ? uiColor(2) : uiColor(1), 2, (i++ * fontHeight), 0, "Option7: FreeDraw"); + draw_textf_border(font, stonesenseState.ssState.blueprinting ? uiColor(2) : uiColor(1), 2, (i++ * fontHeight), 0, "Option8: Blueprint Mode"); } if (tform != NULL && b->material.type != INVALID_INDEX) { @@ -1121,7 +1135,7 @@ void paintboard() al_hold_bitmap_drawing(true); ALLEGRO_COLOR red = ssConfig.config.colors.getDfColor(dfColors::lred, ssConfig.config.useDfColors); draw_textf_border(font, *df::global::pause_state ? red : uiColor(3), 0, 0, ALLEGRO_ALIGN_LEFT, (*df::global::pause_state ? "Paused" : "Running")); - drawDebugCursor(segment); + drawSelectionCursor(segment); drawGeneralInfo(segment); al_hold_bitmap_drawing(false); } diff --git a/SegmentProcessing.cpp b/SegmentProcessing.cpp index 3c9b2bc5..fce4ead7 100644 --- a/SegmentProcessing.cpp +++ b/SegmentProcessing.cpp @@ -439,11 +439,18 @@ void optimizeSegment(WorldSegment * segment) unhideWaterFromAbove(segment, b); if( ssConfig.show_designations && containsDesignations(b->designation, b->occ) ) { + if (containsBlueprints(b->designation, b->occ)) { + b->blueprint = true; + } + else { + b->blueprint = false; + } b->visible = true; } else if( ssConfig.shade_hidden_tiles ) { maskTile(segment, b); } else if( b->designation.bits.hidden ) { b->visible = false; + b->blueprint = false; } } diff --git a/SpriteObjects.cpp b/SpriteObjects.cpp index 200aad9f..d6e95fff 100644 --- a/SpriteObjects.cpp +++ b/SpriteObjects.cpp @@ -1022,6 +1022,7 @@ void c_sprite::assemble_world_offset(int x, int y, int z, int plateoffset, Tile sheety = ((sheetindex+plateoffset+spriteoffset) / SHEET_OBJECTSWIDE) * spriteheight; } ALLEGRO_COLOR shade_color = shadeAdventureMode(get_color(b), b->fog_of_war, b->designation.bits.outside); + if (b->blueprint && containsDesignations(b->designation, b->occ)) { shade_color = al_map_rgba(0, 127, 255, 127); } if(chop && ( halftile == HALFPLATECHOP)) { if(shade_color.a > 0.001f) b->AssembleSprite( diff --git a/Tile.cpp b/Tile.cpp index 627a6c47..6ee34093 100644 --- a/Tile.cpp +++ b/Tile.cpp @@ -753,6 +753,17 @@ bool containsDesignations( df::tile_designation des, df::tile_occupancy occ ) return false; } + +bool containsBlueprints(df::tile_designation des, df::tile_occupancy occ) +{ + if (!df::global::gamemode || *df::global::gamemode == df::game_mode::ADVENTURE) + return false; + if (des.bits.dig != df::tile_dig_designation::No && + occ.bits.dig_marked) { + return true; + } + return false; +} void createEffectSprites() { sprite_miasma = CreateSpriteFromSheet( 180, stonesenseState.IMGObjectSheet); diff --git a/Tile.h b/Tile.h index ceb0d4d9..9594f2ad 100644 --- a/Tile.h +++ b/Tile.h @@ -26,6 +26,7 @@ class Tile void Attach(WorldSegment*, df::tiletype, int32_t, int32_t, int32_t); bool visible; + bool blueprint; WorldSegment* ownerSegment; @@ -136,6 +137,7 @@ bool hasBuildingIdentity(Tile* b, Stonesense_Building* index, df::tile_building_ bool hasBuildingOfIndex(Tile* b, Stonesense_Building* index); bool wallShouldNotHaveBorders( df::tiletype in ); bool containsDesignations( df::tile_designation, df::tile_occupancy ); +bool containsBlueprints( df::tile_designation, df::tile_occupancy ); inline bool IDisWall(int in) { diff --git a/UserInput.cpp b/UserInput.cpp index e93f1ebf..2e093c02 100644 --- a/UserInput.cpp +++ b/UserInput.cpp @@ -73,13 +73,14 @@ void abortAutoReload() auto lastMoveTime = clock(); bool okToMoveView() { - if ((clock() - lastMoveTime >= 50)) { + if ((clockToMs(clock() - lastMoveTime) >= 50)) { lastMoveTime = clock(); return true; } return false; } +//Safely sends a key to DF void sendDFKey(df::interface_key key) { DFHack::CoreSuspender suspend; df::viewscreen* screen = DFHack::Gui::getDFViewscreen(); @@ -230,7 +231,7 @@ void doMouse() if (ssConfig.overlay_mode && mouse.buttons & 1) { if (!mouseDown) { sendDFKey(df::interface_key::SELECT); - mouseDown = true; + mouseDown = stonesenseState.ssState.rectangleSelect; } } else { @@ -743,6 +744,10 @@ void action_incrZ(uint32_t keymod) } void action_option1(uint32_t keymod) { + if (keymod & ALLEGRO_KEYMOD_SHIFT) { + action_togglecreaturenames(keymod); + return; + } switch (stonesenseState.ssState.mode) { case 0: //Default sendDFKey(df::interface_key::D_DESIGNATE_DIG); @@ -770,6 +775,10 @@ void action_option1(uint32_t keymod) { }; } void action_option2(uint32_t keymod) { + if (keymod & ALLEGRO_KEYMOD_SHIFT) { + action_togglecreatureprof(keymod); + return; + } switch (stonesenseState.ssState.mode) { case 0: //Default sendDFKey(df::interface_key::D_DESIGNATE_CHOP); @@ -796,6 +805,10 @@ void action_option2(uint32_t keymod) { }; } void action_option3(uint32_t keymod) { + if (keymod & ALLEGRO_KEYMOD_SHIFT) { + action_togglecreaturemood(keymod); + return; + } switch (stonesenseState.ssState.mode) { case 0: //Default sendDFKey(df::interface_key::D_DESIGNATE_GATHER); @@ -822,6 +835,10 @@ void action_option3(uint32_t keymod) { }; } void action_option4(uint32_t keymod) { + if (keymod & ALLEGRO_KEYMOD_SHIFT) { + action_togglezones(keymod); + return; + } switch (stonesenseState.ssState.mode) { case 0: //Default sendDFKey(df::interface_key::D_DESIGNATE_SMOOTH); @@ -848,6 +865,10 @@ void action_option4(uint32_t keymod) { }; } void action_option5(uint32_t keymod) { + if (keymod & ALLEGRO_KEYMOD_SHIFT) { + action_togglestockpiles(keymod); + return; + } switch (stonesenseState.ssState.mode) { case 0: //Default sendDFKey(df::interface_key::D_DESIGNATE_ERASE); diff --git a/common.h b/common.h index 2acdccfe..5f367964 100644 --- a/common.h +++ b/common.h @@ -163,7 +163,11 @@ constexpr auto MAX_ANIMFRAME = 6; // binary 00111111 constexpr auto ALL_FRAMES = 0b111111; +//from Gui.cpp +float clockToMs(float clockTicks); + //from UserInput.cpp +int32_t getKeyMods(ALLEGRO_KEYBOARD_STATE * keyboardState); void doMouse(); void doKeys(int32_t key, uint32_t keymod); void doRepeatActions(); diff --git a/main.cpp b/main.cpp index a5f3a940..d58ff0e2 100644 --- a/main.cpp +++ b/main.cpp @@ -223,6 +223,7 @@ static void main_loop(ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE *queue, ALL while (!al_get_thread_should_stop(main_thread)) { if (DFHack::Gui::getCurFocus().front().starts_with("dwarfmode/Default")) { stonesenseState.ssState.mode = GameState::modeTypes::DEFAULT; + stonesenseState.ssState.submode = "None"; } if (redraw && al_event_queue_is_empty(queue)) { From e86105ddea9d17ec3f293d5e1ced934877b68c3a Mon Sep 17 00:00:00 2001 From: Squid Coder Date: Sat, 1 Feb 2025 02:54:59 -0600 Subject: [PATCH 15/21] made blueprints WAY cleaner and added `dig_auto` indicator too (its green!) --- SegmentProcessing.cpp | 7 ------- SpriteObjects.cpp | 3 ++- Tile.cpp | 11 ----------- Tile.h | 2 -- 4 files changed, 2 insertions(+), 21 deletions(-) diff --git a/SegmentProcessing.cpp b/SegmentProcessing.cpp index fce4ead7..3c9b2bc5 100644 --- a/SegmentProcessing.cpp +++ b/SegmentProcessing.cpp @@ -439,18 +439,11 @@ void optimizeSegment(WorldSegment * segment) unhideWaterFromAbove(segment, b); if( ssConfig.show_designations && containsDesignations(b->designation, b->occ) ) { - if (containsBlueprints(b->designation, b->occ)) { - b->blueprint = true; - } - else { - b->blueprint = false; - } b->visible = true; } else if( ssConfig.shade_hidden_tiles ) { maskTile(segment, b); } else if( b->designation.bits.hidden ) { b->visible = false; - b->blueprint = false; } } diff --git a/SpriteObjects.cpp b/SpriteObjects.cpp index d6e95fff..e418d63f 100644 --- a/SpriteObjects.cpp +++ b/SpriteObjects.cpp @@ -1022,7 +1022,8 @@ void c_sprite::assemble_world_offset(int x, int y, int z, int plateoffset, Tile sheety = ((sheetindex+plateoffset+spriteoffset) / SHEET_OBJECTSWIDE) * spriteheight; } ALLEGRO_COLOR shade_color = shadeAdventureMode(get_color(b), b->fog_of_war, b->designation.bits.outside); - if (b->blueprint && containsDesignations(b->designation, b->occ)) { shade_color = al_map_rgba(0, 127, 255, 127); } + if (b->occ.bits.dig_marked && containsDesignations(b->designation, b->occ)) { shade_color = al_map_rgba(0, 127, 255, 127); } + if (b->occ.bits.dig_auto && containsDesignations(b->designation, b->occ)) { shade_color = al_map_rgba(0, 255, 127, 127); } if(chop && ( halftile == HALFPLATECHOP)) { if(shade_color.a > 0.001f) b->AssembleSprite( diff --git a/Tile.cpp b/Tile.cpp index 6ee34093..627a6c47 100644 --- a/Tile.cpp +++ b/Tile.cpp @@ -753,17 +753,6 @@ bool containsDesignations( df::tile_designation des, df::tile_occupancy occ ) return false; } - -bool containsBlueprints(df::tile_designation des, df::tile_occupancy occ) -{ - if (!df::global::gamemode || *df::global::gamemode == df::game_mode::ADVENTURE) - return false; - if (des.bits.dig != df::tile_dig_designation::No && - occ.bits.dig_marked) { - return true; - } - return false; -} void createEffectSprites() { sprite_miasma = CreateSpriteFromSheet( 180, stonesenseState.IMGObjectSheet); diff --git a/Tile.h b/Tile.h index 9594f2ad..ceb0d4d9 100644 --- a/Tile.h +++ b/Tile.h @@ -26,7 +26,6 @@ class Tile void Attach(WorldSegment*, df::tiletype, int32_t, int32_t, int32_t); bool visible; - bool blueprint; WorldSegment* ownerSegment; @@ -137,7 +136,6 @@ bool hasBuildingIdentity(Tile* b, Stonesense_Building* index, df::tile_building_ bool hasBuildingOfIndex(Tile* b, Stonesense_Building* index); bool wallShouldNotHaveBorders( df::tiletype in ); bool containsDesignations( df::tile_designation, df::tile_occupancy ); -bool containsBlueprints( df::tile_designation, df::tile_occupancy ); inline bool IDisWall(int in) { From ae492703a180aa47059e3b5acf948ad9f5ebdc16 Mon Sep 17 00:00:00 2001 From: Squid Coder Date: Sat, 1 Feb 2025 07:25:37 -0600 Subject: [PATCH 16/21] no need to perma enable overlay mode now --- GameConfiguration.h | 2 +- docs/changelog.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/GameConfiguration.h b/GameConfiguration.h index 62e6200d..64f1c633 100644 --- a/GameConfiguration.h +++ b/GameConfiguration.h @@ -13,7 +13,7 @@ struct GameConfiguration { Config config; // items not configurable via the config file - bool overlay_mode = true; + bool overlay_mode; bool show_designations = true; bool show_announcements = false; bool show_keybinds = false; diff --git a/docs/changelog.txt b/docs/changelog.txt index c1deb4d6..ee4f23c5 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -56,6 +56,7 @@ Template for new versions: ## Misc Improvements - `stonesense`: improved the way altars look - `stonesense`: fog no longer unnecessarily renders to a separate bitmap +- `stonesense`: blueprint and vein mining designations now look different from regular designations (blue a nd green, respectively, instead of yellow, matching DF) ## Removed From 9eb28e6dcf256db03c1d046c75c3b2ac4f8a9aad Mon Sep 17 00:00:00 2001 From: Squid Coder Date: Sat, 1 Feb 2025 08:17:12 -0600 Subject: [PATCH 17/21] various changes Initial selection point now indicated with a blue cursor De-magic numbered movement wait time DRY-ed out the cursor drawing into a generic function (now you can draw a cursor at a 3d point with a color) --- GUI.cpp | 53 +++++++++++++++++++++------------------------------ GameState.h | 4 +++- UserInput.cpp | 9 ++++++++- common.h | 1 + main.cpp | 1 + 5 files changed, 35 insertions(+), 33 deletions(-) diff --git a/GUI.cpp b/GUI.cpp index b661e706..cbad6c9d 100644 --- a/GUI.cpp +++ b/GUI.cpp @@ -483,24 +483,18 @@ void DrawCurrentLevelOutline(bool backPart) namespace { - void drawSelectionCursor(WorldSegment* segment) + void drawCursorAt(WorldSegment* segment, Crd3D location, ALLEGRO_COLOR color) { auto& ssConfig = stonesenseState.ssConfig; - Crd3D selection; - (stonesenseState.ssConfig.overlay_mode) ? selection = segment->segState.dfCursor : selection = segment->segState.dfSelection; - DFHack::Gui::setCursorCoords( - selection.x, - selection.y, - selection.z); - segment->CorrectTileForSegmentOffset(selection.x, selection.y, selection.z); - segment->CorrectTileForSegmentRotation(selection.x, selection.y, selection.z); - Crd2D point = LocalTileToScreen(selection.x, selection.y, selection.z); + segment->CorrectTileForSegmentOffset(location.x, location.y, location.z); + segment->CorrectTileForSegmentRotation(location.x, location.y, location.z); + Crd2D point = LocalTileToScreen(location.x, location.y, location.z); int sheetx = SPRITEOBJECT_CURSOR % SHEET_OBJECTSWIDE; int sheety = SPRITEOBJECT_CURSOR / SHEET_OBJECTSWIDE; al_draw_tinted_scaled_bitmap( stonesenseState.IMGObjectSheet, - uiColor(3), + color, sheetx * SPRITEWIDTH, sheety * SPRITEHEIGHT, SPRITEWIDTH, @@ -512,6 +506,20 @@ namespace 0); } + void drawSelectionCursors(WorldSegment* segment) + { + auto& ssConfig = stonesenseState.ssConfig; + + Crd3D selection; + (stonesenseState.ssConfig.overlay_mode) ? selection = segment->segState.dfCursor : selection = segment->segState.dfSelection; + DFHack::Gui::setCursorCoords( + selection.x, + selection.y, + selection.z); + drawCursorAt(segment, segment->segState.dfSelection2, ssConfig.config.colors.getDfColor(dfColors::lblue, ssConfig.config.useDfColors)); + drawCursorAt(segment, selection, uiColor(3)); // We draw the main one second so it appears on top + } + void drawDebugCursor(WorldSegment* segment) { auto& ssConfig = stonesenseState.ssConfig; @@ -521,24 +529,7 @@ namespace cursor.x, cursor.y, cursor.z); - segment->CorrectTileForSegmentOffset(cursor.x, cursor.y, cursor.z); - segment->CorrectTileForSegmentRotation(cursor.x, cursor.y, cursor.z); - - Crd2D point = LocalTileToScreen(cursor.x, cursor.y, cursor.z); - int sheetx = SPRITEOBJECT_CURSOR % SHEET_OBJECTSWIDE; - int sheety = SPRITEOBJECT_CURSOR / SHEET_OBJECTSWIDE; - al_draw_tinted_scaled_bitmap( - stonesenseState.IMGObjectSheet, - uiColor(2), - sheetx * SPRITEWIDTH, - sheety * SPRITEHEIGHT, - SPRITEWIDTH, - SPRITEHEIGHT, - point.x - ((SPRITEWIDTH / 2) * ssConfig.scale), - point.y - (WALLHEIGHT)*ssConfig.scale, - SPRITEWIDTH * ssConfig.scale, - SPRITEHEIGHT * ssConfig.scale, - 0); + drawCursorAt(segment, cursor, uiColor(2)); } void drawAdvmodeMenuTalk(const ALLEGRO_FONT* font, int x, int y) @@ -1135,7 +1126,7 @@ void paintboard() al_hold_bitmap_drawing(true); ALLEGRO_COLOR red = ssConfig.config.colors.getDfColor(dfColors::lred, ssConfig.config.useDfColors); draw_textf_border(font, *df::global::pause_state ? red : uiColor(3), 0, 0, ALLEGRO_ALIGN_LEFT, (*df::global::pause_state ? "Paused" : "Running")); - drawSelectionCursor(segment); + drawSelectionCursors(segment); drawGeneralInfo(segment); al_hold_bitmap_drawing(false); } @@ -1159,7 +1150,7 @@ void paintboard() al_hold_bitmap_drawing(true); draw_textf_border(font, uiColor(1), 10,fontHeight, 0, "%i,%i,%i, r%i, z%i", ssState.Position.x,ssState.Position.y,ssState.Position.z, ssState.Rotation, ssConfig.zoom); - drawSelectionCursor(segment); + drawSelectionCursors(segment); drawDebugCursor(segment); diff --git a/GameState.h b/GameState.h index 43fdcfe0..cb523ac2 100644 --- a/GameState.h +++ b/GameState.h @@ -17,8 +17,9 @@ struct GameState{ //position of the cursor Crd3D dfCursor; - //position of the selection cursor + //position of the selection cursors Crd3D dfSelection; + Crd3D dfSelection2; //the width and height of the stonesense window int ScreenW; @@ -26,6 +27,7 @@ struct GameState{ bool blueprinting = false; bool rectangleSelect = true; + bool clickedOnceYet = false; enum modeTypes { DEFAULT, diff --git a/UserInput.cpp b/UserInput.cpp index 2e093c02..69370cdf 100644 --- a/UserInput.cpp +++ b/UserInput.cpp @@ -73,7 +73,7 @@ void abortAutoReload() auto lastMoveTime = clock(); bool okToMoveView() { - if ((clockToMs(clock() - lastMoveTime) >= 50)) { + if ((clockToMs(clock() - lastMoveTime) >= MOVEMENTWAITTIME)) { lastMoveTime = clock(); return true; } @@ -173,6 +173,7 @@ void doMouse() if( mouse.buttons & 2 ) { if (ssConfig.overlay_mode) { sendDFKey(df::interface_key::LEAVESCREEN); + stonesenseState.ssState.clickedOnceYet = false; }else{ ssConfig.config.track_mode = Config::TRACKING_NONE; int x, y; @@ -226,12 +227,18 @@ void doMouse() ssState.dfCursor.x = tilex; ssState.dfCursor.y = tiley; ssState.dfCursor.z = tilez; + if (!ssState.clickedOnceYet) { + ssState.dfSelection2.x = tilex; + ssState.dfSelection2.y = tiley; + ssState.dfSelection2.z = tilez; + } } stonesenseState.timeToReloadSegment = true; if (ssConfig.overlay_mode && mouse.buttons & 1) { if (!mouseDown) { sendDFKey(df::interface_key::SELECT); mouseDown = stonesenseState.ssState.rectangleSelect; + stonesenseState.ssState.clickedOnceYet = !stonesenseState.ssState.clickedOnceYet; } } else { diff --git a/common.h b/common.h index 5f367964..bead8f73 100644 --- a/common.h +++ b/common.h @@ -232,3 +232,4 @@ constexpr auto FORM_BOULDER = 3; constexpr auto FORM_LOG = 4; constexpr auto SCALEZOOMFACTOR = 1.1f; +constexpr auto MOVEMENTWAITTIME = 100; //100ms seems to feel good diff --git a/main.cpp b/main.cpp index b249bdfb..7f27a857 100644 --- a/main.cpp +++ b/main.cpp @@ -224,6 +224,7 @@ static void main_loop(ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE *queue, ALL if (DFHack::Gui::getCurFocus().front().starts_with("dwarfmode/Default")) { stonesenseState.ssState.mode = GameState::modeTypes::DEFAULT; stonesenseState.ssState.submode = "None"; + stonesenseState.ssState.clickedOnceYet = false; } if (redraw && al_event_queue_is_empty(queue)) { From 582654e8d46b7266efadd9a68a5978f5595c76c0 Mon Sep 17 00:00:00 2001 From: Squid Coder Date: Sat, 1 Feb 2025 09:56:35 -0600 Subject: [PATCH 18/21] various changes Added Option9 added vein mining cleaned up my switches added 2 new uiColor() options --- GUI.cpp | 9 ++++++--- GameState.h | 1 + Keybinds.cpp | 2 ++ SpriteColors.cpp | 6 ++++++ SpriteObjects.cpp | 4 +++- UserInput.cpp | 49 +++++++++++++++++++++++++++-------------------- UserInput.h | 1 + main.cpp | 9 +++++++++ 8 files changed, 56 insertions(+), 25 deletions(-) diff --git a/GUI.cpp b/GUI.cpp index cbad6c9d..3e717d00 100644 --- a/GUI.cpp +++ b/GUI.cpp @@ -516,7 +516,7 @@ namespace selection.x, selection.y, selection.z); - drawCursorAt(segment, segment->segState.dfSelection2, ssConfig.config.colors.getDfColor(dfColors::lblue, ssConfig.config.useDfColors)); + drawCursorAt(segment, segment->segState.dfSelection2, uiColor(4)); drawCursorAt(segment, selection, uiColor(3)); // We draw the main one second so it appears on top } @@ -807,6 +807,7 @@ namespace "Toggle Zones", "Toggle Stockpiles", "Toggle Designations", + "Toggle Announcements", }; } else { switch (stonesenseState.ssState.mode) { @@ -874,6 +875,9 @@ namespace draw_textf_border(font, stonesenseState.ssState.rectangleSelect ? uiColor(2) : uiColor(1), 2, (i++ * fontHeight), 0, "Option6: Rectangle"); draw_textf_border(font, !stonesenseState.ssState.rectangleSelect ? uiColor(2) : uiColor(1), 2, (i++ * fontHeight), 0, "Option7: FreeDraw"); draw_textf_border(font, stonesenseState.ssState.blueprinting ? uiColor(2) : uiColor(1), 2, (i++ * fontHeight), 0, "Option8: Blueprint Mode"); + if (stonesenseState.ssState.mode == 1) { //Dig + draw_textf_border(font, stonesenseState.ssState.veinMining ? uiColor(2) : uiColor(1), 2, (i++ * fontHeight), 0, "Option9: Vein Mode"); + } } if (tform != NULL && b->material.type != INVALID_INDEX) { @@ -1124,8 +1128,7 @@ void paintboard() } if (ssConfig.overlay_mode) { al_hold_bitmap_drawing(true); - ALLEGRO_COLOR red = ssConfig.config.colors.getDfColor(dfColors::lred, ssConfig.config.useDfColors); - draw_textf_border(font, *df::global::pause_state ? red : uiColor(3), 0, 0, ALLEGRO_ALIGN_LEFT, (*df::global::pause_state ? "Paused" : "Running")); + draw_textf_border(font, *df::global::pause_state ? uiColor(5) : uiColor(3), 0, 0, ALLEGRO_ALIGN_LEFT, (*df::global::pause_state ? "Paused" : "Running")); drawSelectionCursors(segment); drawGeneralInfo(segment); al_hold_bitmap_drawing(false); diff --git a/GameState.h b/GameState.h index cb523ac2..1ecfb097 100644 --- a/GameState.h +++ b/GameState.h @@ -27,6 +27,7 @@ struct GameState{ bool blueprinting = false; bool rectangleSelect = true; + bool veinMining = false; bool clickedOnceYet = false; enum modeTypes { diff --git a/Keybinds.cpp b/Keybinds.cpp index 4773dc0c..b1a1c766 100644 --- a/Keybinds.cpp +++ b/Keybinds.cpp @@ -230,6 +230,8 @@ action_name_mapper actionnamemap[] = { {"OPTION6",action_option6}, {"OPTION7",action_option7}, {"OPTION8",action_option8}, + {"OPTION9",action_option9}, + {"INVALID", action_invalid}//this is the stop condition }; diff --git a/SpriteColors.cpp b/SpriteColors.cpp index 3bd1f528..0f68676f 100644 --- a/SpriteColors.cpp +++ b/SpriteColors.cpp @@ -322,6 +322,12 @@ ALLEGRO_COLOR uiColor(int32_t index) case 3: //lime return ssConfig.config.colors.getDfColor(dfColors::lgreen, ssConfig.config.useDfColors); + case 4: + //light blue + return ssConfig.config.colors.getDfColor(dfColors::lblue, ssConfig.config.useDfColors); + case 5: + //light red + return ssConfig.config.colors.getDfColor(dfColors::lred, ssConfig.config.useDfColors); default: //white return ssConfig.config.colors.getDfColor(dfColors::white, ssConfig.config.useDfColors); diff --git a/SpriteObjects.cpp b/SpriteObjects.cpp index a1411482..803dcf91 100644 --- a/SpriteObjects.cpp +++ b/SpriteObjects.cpp @@ -1023,8 +1023,10 @@ void c_sprite::assemble_world_offset(int x, int y, int z, int plateoffset, Tile } ALLEGRO_COLOR shade_color = shadeAdventureMode(get_color(b), b->fog_of_war, b->designation.bits.outside); - if (b->occ.bits.dig_marked && containsDesignations(b->designation, b->occ)) { shade_color = al_map_rgba(0, 127, 255, 127); } if (b->occ.bits.dig_auto && containsDesignations(b->designation, b->occ)) { shade_color = al_map_rgba(0, 255, 127, 127); } + if (b->occ.bits.dig_marked && containsDesignations(b->designation, b->occ)) { shade_color = al_map_rgba(0, 127, 255, 127); } + if (b->occ.bits.dig_marked && b->occ.bits.dig_auto && containsDesignations(b->designation, b->occ)) { shade_color = partialBlend(shade_color, al_map_rgba(0, 255, 127, 127), 25); } + if(chop && ( halftile == HALFPLATECHOP)) { if(shade_color.a > 0.001f) { b->AssembleSprite( diff --git a/UserInput.cpp b/UserInput.cpp index 69370cdf..e994d415 100644 --- a/UserInput.cpp +++ b/UserInput.cpp @@ -766,7 +766,6 @@ void action_option1(uint32_t keymod) { stonesenseState.ssState.submode = "Dig"; break; case 2: //Chop - break; case 3: //Gather break; case 4: //Smooth @@ -774,9 +773,7 @@ void action_option1(uint32_t keymod) { stonesenseState.ssState.submode = "Smooth"; break; case 5: //Erase - break; case 6: //Building - break; case 7: //Traffic break; }; @@ -796,7 +793,6 @@ void action_option2(uint32_t keymod) { stonesenseState.ssState.submode = "Stairs"; break; case 2: //Chop - break; case 3: //Gather break; case 4: //Smooth @@ -804,9 +800,7 @@ void action_option2(uint32_t keymod) { stonesenseState.ssState.submode = "Engrave"; break; case 5: //Erase - break; case 6: //Building - break; case 7: //Traffic break; }; @@ -826,7 +820,6 @@ void action_option3(uint32_t keymod) { stonesenseState.ssState.submode = "Ramp"; break; case 2: //Chop - break; case 3: //Gather break; case 4: //Smooth @@ -834,9 +827,7 @@ void action_option3(uint32_t keymod) { stonesenseState.ssState.submode = "Carve Track"; break; case 5: //Erase - break; case 6: //Building - break; case 7: //Traffic break; }; @@ -856,7 +847,6 @@ void action_option4(uint32_t keymod) { stonesenseState.ssState.submode = "Channel"; break; case 2: //Chop - break; case 3: //Gather break; case 4: //Smooth @@ -864,9 +854,7 @@ void action_option4(uint32_t keymod) { stonesenseState.ssState.submode = "Fortification"; break; case 5: //Erase - break; case 6: //Building - break; case 7: //Traffic break; }; @@ -886,20 +874,19 @@ void action_option5(uint32_t keymod) { stonesenseState.ssState.submode = "Remove"; break; case 2: //Chop - break; case 3: //Gather - break; case 4: //Smooth - break; case 5: //Erase - break; case 6: //Building - break; case 7: //Traffic break; }; } void action_option6(uint32_t keymod) { + if (keymod & ALLEGRO_KEYMOD_SHIFT) { + action_toggledesignations(keymod); + return; + } switch (stonesenseState.ssState.mode) { case 0: //Default break; @@ -912,12 +899,15 @@ void action_option6(uint32_t keymod) { stonesenseState.ssState.rectangleSelect = true; break; case 6: //Building - break; case 7: //Traffic break; }; } void action_option7(uint32_t keymod) { + if (keymod & ALLEGRO_KEYMOD_SHIFT) { + action_toggleannouncements(keymod); + return; + } switch (stonesenseState.ssState.mode) { case 0: //Default break; @@ -930,7 +920,6 @@ void action_option7(uint32_t keymod) { stonesenseState.ssState.rectangleSelect = false; break; case 6: //Building - break; case 7: //Traffic break; }; @@ -947,11 +936,29 @@ void action_option8(uint32_t keymod) { sendDFKey(df::interface_key::DESIGNATE_TOGGLE_MARKER); sendDFKey(df::interface_key::DESIGNATE_TOGGLE_ADVANCED_OPTIONS); stonesenseState.ssState.blueprinting = !stonesenseState.ssState.blueprinting; - break; case 5: //Erase - break; case 6: //Building + case 7: //Traffic break; + }; +} +void action_option9(uint32_t keymod) { + switch (stonesenseState.ssState.mode) { + case 0: //Default + break; + case 1: //Dig + sendDFKey(df::interface_key::DESIGNATE_TOGGLE_ADVANCED_OPTIONS); + (stonesenseState.ssState.veinMining) ? + sendDFKey(df::interface_key::DESIGNATE_MINE_MODE_ALL): + sendDFKey(df::interface_key::DESIGNATE_MINE_MODE_AUTO); + sendDFKey(df::interface_key::DESIGNATE_TOGGLE_ADVANCED_OPTIONS); + stonesenseState.ssState.veinMining = !stonesenseState.ssState.veinMining; + break; + case 2: //Chop + case 3: //Gather + case 4: //Smooth + case 5: //Erase + case 6: //Building case 7: //Traffic break; }; diff --git a/UserInput.h b/UserInput.h index e7ca4341..ae2d382a 100644 --- a/UserInput.h +++ b/UserInput.h @@ -8,6 +8,7 @@ void action_option5(uint32_t keymod); void action_option6(uint32_t keymod); void action_option7(uint32_t keymod); void action_option8(uint32_t keymod); +void action_option9(uint32_t keymod); void action_togglePause(uint32_t keymod); diff --git a/main.cpp b/main.cpp index 7f27a857..98b8d33d 100644 --- a/main.cpp +++ b/main.cpp @@ -572,10 +572,19 @@ DFhackCExport command_result stonesense_command(color_ostream &out, std::vector< out.print("Stonesense already running.\n"); return CR_OK; } + auto& ssConfig = stonesenseState.ssConfig; ssConfig.overlay_mode = false; if(params.size() > 0 ) { if(params[0] == "overlay"){ + auto focusStr = DFHack::Gui::getCurFocus().front(); + if (!(focusStr.starts_with("title") || + focusStr.starts_with("loadgame"))) { + out.print( + "You need to start this mode from the titlescreen and enable keyboard cursor (in settings) to ensure a proper state." + ); + return CR_OK; + } ssConfig.overlay_mode = true; } else { DumpInfo(out, params); From 2f27b5bfa0477e3814c5cb2aeb536938a0154e66 Mon Sep 17 00:00:00 2001 From: Squid Coder Date: Sat, 1 Feb 2025 10:14:11 -0600 Subject: [PATCH 19/21] Fix whitespace and designation bug --- SpriteObjects.cpp | 8 +++++--- UserInput.cpp | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/SpriteObjects.cpp b/SpriteObjects.cpp index 803dcf91..161d8a36 100644 --- a/SpriteObjects.cpp +++ b/SpriteObjects.cpp @@ -1023,9 +1023,11 @@ void c_sprite::assemble_world_offset(int x, int y, int z, int plateoffset, Tile } ALLEGRO_COLOR shade_color = shadeAdventureMode(get_color(b), b->fog_of_war, b->designation.bits.outside); - if (b->occ.bits.dig_auto && containsDesignations(b->designation, b->occ)) { shade_color = al_map_rgba(0, 255, 127, 127); } - if (b->occ.bits.dig_marked && containsDesignations(b->designation, b->occ)) { shade_color = al_map_rgba(0, 127, 255, 127); } - if (b->occ.bits.dig_marked && b->occ.bits.dig_auto && containsDesignations(b->designation, b->occ)) { shade_color = partialBlend(shade_color, al_map_rgba(0, 255, 127, 127), 25); } + if (ssConfig.show_designations) { + if (b->occ.bits.dig_auto && containsDesignations(b->designation, b->occ)) { shade_color = al_map_rgba(0, 255, 127, 127); } + if (b->occ.bits.dig_marked && containsDesignations(b->designation, b->occ)) { shade_color = al_map_rgba(0, 127, 255, 127); } + if (b->occ.bits.dig_marked && b->occ.bits.dig_auto && containsDesignations(b->designation, b->occ)) { shade_color = partialBlend(shade_color, al_map_rgba(0, 255, 127, 127), 25); } + } if(chop && ( halftile == HALFPLATECHOP)) { if(shade_color.a > 0.001f) { diff --git a/UserInput.cpp b/UserInput.cpp index e994d415..b085a918 100644 --- a/UserInput.cpp +++ b/UserInput.cpp @@ -948,7 +948,7 @@ void action_option9(uint32_t keymod) { break; case 1: //Dig sendDFKey(df::interface_key::DESIGNATE_TOGGLE_ADVANCED_OPTIONS); - (stonesenseState.ssState.veinMining) ? + (stonesenseState.ssState.veinMining) ? sendDFKey(df::interface_key::DESIGNATE_MINE_MODE_ALL): sendDFKey(df::interface_key::DESIGNATE_MINE_MODE_AUTO); sendDFKey(df::interface_key::DESIGNATE_TOGGLE_ADVANCED_OPTIONS); From 6e32000e54243a505d0e0da69683f5166615a43b Mon Sep 17 00:00:00 2001 From: Squid Coder Date: Sat, 1 Feb 2025 10:16:09 -0600 Subject: [PATCH 20/21] Remove unused config references --- GUI.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/GUI.cpp b/GUI.cpp index 3e717d00..8ef63d48 100644 --- a/GUI.cpp +++ b/GUI.cpp @@ -508,8 +508,6 @@ namespace void drawSelectionCursors(WorldSegment* segment) { - auto& ssConfig = stonesenseState.ssConfig; - Crd3D selection; (stonesenseState.ssConfig.overlay_mode) ? selection = segment->segState.dfCursor : selection = segment->segState.dfSelection; DFHack::Gui::setCursorCoords( @@ -522,8 +520,6 @@ namespace void drawDebugCursor(WorldSegment* segment) { - auto& ssConfig = stonesenseState.ssConfig; - Crd3D cursor = segment->segState.dfCursor; DFHack::Gui::setCursorCoords( cursor.x, From 1157ec6eb3be77676ca8712c48eefbe483db4ab5 Mon Sep 17 00:00:00 2001 From: Squid Coder Date: Sat, 1 Feb 2025 12:21:37 -0600 Subject: [PATCH 21/21] See description - Made key action mappers use std::vectors not arrays - Added the ability to make default keys for new items we add - made a separate mapper for immersive mode - right aligned the keybinds in Stonesense so they dont cover the immersive menu --- GUI.cpp | 2 +- Keybinds.cpp | 162 ++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 117 insertions(+), 47 deletions(-) diff --git a/GUI.cpp b/GUI.cpp index 8ef63d48..fc347af1 100644 --- a/GUI.cpp +++ b/GUI.cpp @@ -1137,7 +1137,7 @@ void paintboard() for(int32_t i=1; true; i++){ if(getKeyStrings(i, keyname, actionname)){ - draw_textf_border(font, uiColor(1), 10, line*fontHeight, 0, "%s: %s%s", keyname->c_str(), actionname->c_str(), isRepeatable(i) ? " (repeats)" : ""); + draw_textf_border(font, uiColor(1), stonesenseState.ssState.ScreenW-10, line*fontHeight, ALLEGRO_ALIGN_RIGHT, "%s: %s%s", keyname->c_str(), actionname->c_str(), isRepeatable(i) ? " (repeats)" : ""); line++; } if(keyname == NULL) { diff --git a/Keybinds.cpp b/Keybinds.cpp index b1a1c766..afa2f041 100644 --- a/Keybinds.cpp +++ b/Keybinds.cpp @@ -1,5 +1,7 @@ +#include "vector" #include "common.h" #include "Config.h" +#include "StonesenseState.h" #include "UserInput.h" //should match allegrow/keycodes.h @@ -173,7 +175,112 @@ void action_invalid(uint32_t keymod){ PrintMessage("invalid action\n"); } -action_name_mapper actionnamemap[] = { +std::vector actionnamemap; + +void (*actionkeymap[ALLEGRO_KEY_UNKNOWN])(uint32_t); +void (*actionkeymap_default[ALLEGRO_KEY_UNKNOWN])(uint32_t); +bool actionrepeatmap[ALLEGRO_KEY_UNKNOWN]; + +void parseKeymapLine( std::string line ) +{ + auto ll = trim_line(line); + if (!ll) return; + line = *ll; + + //second-last character should tell us if this is a repeating action + auto c = line[ line.length() -2 ]; + + for(int i=0; actionnamemap[i].func != action_invalid; i++) { + if(line.find(actionnamemap[i].name)!=std::string::npos) { + for(int j=0; j