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..fc347af1 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); @@ -484,25 +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 = 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; - } - 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, @@ -514,29 +506,26 @@ namespace 0); } - void drawDebugCursor(WorldSegment* segment) + 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, uiColor(4)); + drawCursorAt(segment, selection, uiColor(3)); // We draw the main one second so it appears on top + } + void drawDebugCursor(WorldSegment* segment) + { Crd3D cursor = segment->segState.dfCursor; - 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); + DFHack::Gui::setCursorCoords( + cursor.x, + cursor.y, + cursor.z); + drawCursorAt(segment, cursor, uiColor(2)); } void drawAdvmodeMenuTalk(const ALLEGRO_FONT* font, int x, int y) @@ -765,6 +754,224 @@ 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); + + //get tile info + Tile* b = segment->getTile( + segment->segState.dfCursor.x, + segment->segState.dfCursor.y, + segment->segState.dfCursor.z); + + 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; + } + const char* tform = NULL; + using df::tiletype_shape_basic; + + if (b->tileShapeBasic() == tiletype_shape_basic::Floor) { + tform = "floor"; + } + else if (b->tileShapeBasic() == tiletype_shape_basic::Wall) { + tform = "wall"; + } + else if (b->tileShapeBasic() == tiletype_shape_basic::Ramp || + b->tileType == df::tiletype::RampTop) { + tform = "ramp"; + } + else if (b->tileShapeBasic() == tiletype_shape_basic::Stair) { + tform = "stair"; + } + + auto modeStr = ""; + std::vector options = {""}; + auto keymods = getKeyMods(&stonesenseState.keyboard); + if (keymods & ALLEGRO_KEYMOD_SHIFT) { + options = { + "Toggle Names", + "Cycle Professions", + "Toggle Moods", + "Toggle Zones", + "Toggle Stockpiles", + "Toggle Designations", + "Toggle Announcements", + }; + } 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 + 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, "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) { + 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* subTypeName = lookupBuildingSubtype(b->building.type, b->building.info->subtype); + draw_textf_border(font, uiColor(1), 2, (i++ * fontHeight), 0, + "Building: %s %s", + 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); + 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()) + { + 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 +1122,13 @@ 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); + 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); + } if(ssConfig.show_keybinds){ std::string *keyname, *actionname; keyname = actionname = NULL; @@ -923,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) { @@ -935,7 +1149,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); @@ -955,7 +1169,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/GameState.h b/GameState.h index 4bcd3a3e..1ecfb097 100644 --- a/GameState.h +++ b/GameState.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "common.h" #include "commonTypes.h" @@ -16,10 +17,31 @@ 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; int ScreenH; + + bool blueprinting = false; + bool rectangleSelect = true; + bool veinMining = false; + bool clickedOnceYet = false; + + 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 6b1862b7..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; jstart_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/Overlay.cpp b/Overlay.cpp index 126dcf64..a17447c1 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,30 @@ 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, + /* 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); - DFSDL_Rect src; + /*FIXME SDL_Rect is an incomplete type + 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_FreeSurface(sssurf); + //do the blit + DFHack::DFSDL::DFSDL_UpperBlit(sssurf->surface, &src, dfsurf->surface, &pos); + */ + DFHack::DFSDL::DFSDL_FreeSurface(sssurf->surface); } front_updated = false; } else { 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 bd437b2c..161d8a36 100644 --- a/SpriteObjects.cpp +++ b/SpriteObjects.cpp @@ -1023,6 +1023,12 @@ 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 (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) { b->AssembleSprite( diff --git a/UserInput.cpp b/UserInput.cpp index ebb2ad6d..b085a918 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,22 @@ void abortAutoReload() //remove_int( automaticReloadProc ); } +auto lastMoveTime = clock(); +bool okToMoveView() { + if ((clockToMs(clock() - lastMoveTime) >= MOVEMENTWAITTIME)) { + 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(); + screen->feed_key(key); +} + void changeRelativeToRotation( int &inputx, int &inputy, int stepx, int stepy ) { auto& ssState = stonesenseState.ssState; @@ -99,7 +116,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 @@ -121,7 +138,7 @@ void moveViewRelativeToRotation( int stepx, int stepy ) } } - +bool mouseDown = false; void doMouse() { auto& ssConfig = stonesenseState.ssConfig; @@ -154,23 +171,28 @@ 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); + stonesenseState.ssState.clickedOnceYet = false; + }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; @@ -178,7 +200,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 { @@ -204,8 +227,23 @@ 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 { + mouseDown = false; + } } } @@ -323,7 +361,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; @@ -458,15 +496,25 @@ void action_toggledebug(uint32_t keymod) void action_incrzoom(uint32_t keymod) { auto& ssConfig = stonesenseState.ssConfig; - ssConfig.zoom++; - ssConfig.recalculateScale(); + if (stonesenseState.ssConfig.overlay_mode) { + sendDFKey(df::interface_key::ZOOM_IN); + } + else { + 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 +561,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 +570,29 @@ 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) { + if (!okToMoveView()) { return; } + 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 +602,29 @@ 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) { + if (!okToMoveView()) { return; } + 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 +634,30 @@ 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) { + if (!okToMoveView()) { return; } + 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 +668,29 @@ 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) { + if (!okToMoveView()) { return; } + 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 +703,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 +732,243 @@ 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; } +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); + 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 + case 3: //Gather + break; + case 4: //Smooth + sendDFKey(df::interface_key::DESIGNATE_SMOOTH); + stonesenseState.ssState.submode = "Smooth"; + break; + case 5: //Erase + case 6: //Building + case 7: //Traffic + break; + }; +} +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); + 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 + case 3: //Gather + break; + case 4: //Smooth + sendDFKey(df::interface_key::DESIGNATE_ENGRAVE); + stonesenseState.ssState.submode = "Engrave"; + break; + case 5: //Erase + case 6: //Building + case 7: //Traffic + break; + }; +} +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); + stonesenseState.ssState.mode = GameState::modeTypes::GATHER; + break; + case 1: //Dig + sendDFKey(df::interface_key::DESIGNATE_RAMP); + stonesenseState.ssState.submode = "Ramp"; + break; + case 2: //Chop + case 3: //Gather + break; + case 4: //Smooth + sendDFKey(df::interface_key::DESIGNATE_TRACK); + stonesenseState.ssState.submode = "Carve Track"; + break; + case 5: //Erase + case 6: //Building + case 7: //Traffic + break; + }; +} +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); + stonesenseState.ssState.mode = GameState::modeTypes::SMOOTH; + break; + case 1: //Dig + sendDFKey(df::interface_key::DESIGNATE_CHANNEL); + stonesenseState.ssState.submode = "Channel"; + break; + case 2: //Chop + case 3: //Gather + break; + case 4: //Smooth + sendDFKey(df::interface_key::DESIGNATE_FORTIFY); + stonesenseState.ssState.submode = "Fortification"; + break; + case 5: //Erase + case 6: //Building + case 7: //Traffic + break; + }; +} +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); + 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 + case 3: //Gather + case 4: //Smooth + case 5: //Erase + case 6: //Building + 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; + 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 + 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; + 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 + case 7: //Traffic + break; + }; +} +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; + case 5: //Erase + 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; + }; +} + +void action_togglePause(uint32_t keymod) +{ + sendDFKey(df::interface_key::D_PAUSE); +} + void doRepeatActions() { al_get_keyboard_state(&stonesenseState.keyboard); diff --git a/UserInput.h b/UserInput.h index 5a5e3cfe..ae2d382a 100644 --- a/UserInput.h +++ b/UserInput.h @@ -1,5 +1,18 @@ //declarations of actions taken for user keystrokes +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_option9(uint32_t keymod); + +void action_togglePause(uint32_t keymod); + + void action_incrrotation(uint32_t keymod); void action_reloadsegment(uint32_t keymod); void action_paintboard(uint32_t keymod); diff --git a/common.h b/common.h index 2acdccfe..bead8f73 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(); @@ -228,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/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 diff --git a/main.cpp b/main.cpp index ddf6da38..98b8d33d 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. -std::unique_ptr overlay; -*/ +/*FIXME: Find a new replacement for the overlay mode.*/ +//std::unique_ptr overlay; + ALLEGRO_DISPLAY * display; ALLEGRO_EVENT event; @@ -221,40 +221,45 @@ 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; + stonesenseState.ssState.submode = "None"; + stonesenseState.ssState.clickedOnceYet = false; + } if (redraw && al_event_queue_is_empty(queue)) { al_rest(0); - /*FIXME: Find a new replacement for the overlay mode. - if (ssConfig.overlay_mode) - { - bool goodoverlay = ovrlay->GoodViewscreen(); - if (!goodoverlay) { - //do nothing; this isn't a view we can overlay - }if (ssConfig.spriteIndexOverlay) { - DrawSpriteIndexOverlay(ssConfig.currentSpriteOverlay); - ovrlay->Flip(); - } - else if (!Maps::IsValid()) { - drawcredits(); - ovrlay->Flip(); - } - else if (timeToReloadSegment) { - reloadPosition(); - al_clear_to_color(ssConfig.config.backcol); - paintboard(); - ovrlay->Flip(); - timeToReloadSegment = false; - animationFrameShown = true; - } - else if (animationFrameShown == false) { - al_clear_to_color(ssConfig.config.backcol); - paintboard(); - ovrlay->Flip(); - animationFrameShown = true; - } - } - else */ + /*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 (ssConfig.spriteIndexOverlay) { DrawSpriteIndexOverlay(ssConfig.currentSpriteOverlay); @@ -280,7 +285,7 @@ static void main_loop(ALLEGRO_DISPLAY * display, ALLEGRO_EVENT_QUEUE *queue, ALL } } - if (!ssConfig.overlay_mode) { + if (!stonesenseState.ssConfig.overlay_mode||true) { doMouse(); doRepeatActions(); } @@ -302,9 +307,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 (ssConfig.overlay_mode) { - break; - } + //if (stonesenseState.ssConfig.overlay_mode) { + // break; + //} stonesenseState.timeToReloadSegment = true; redraw = true; stonesenseState.ssState.ScreenH = event.display.height; @@ -317,9 +322,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 (ssConfig.overlay_mode) { - break; - } + //if (stonesenseState.ssConfig.overlay_mode) { + // break; + //} if(event.keyboard.display != display) { break; } @@ -393,12 +398,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( - (ssConfig.config.Fullscreen && !ssConfig.overlay_mode ? ALLEGRO_FULLSCREEN : ALLEGRO_WINDOWED) - |(ssConfig.overlay_mode ? 0 : ALLEGRO_RESIZABLE) - |(ssConfig.overlay_mode ? ALLEGRO_MINIMIZED : 0) + /*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); @@ -437,12 +449,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); - 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"; IMGIcon = load_bitmap_withWarning(p); @@ -502,9 +514,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. - overlay.reset(); - */ + /*FIXME: Find a new replacement for the overlay mode.*/ + //overlay.reset(); + if(ssConfig.threadmade) { al_broadcast_cond(ssConfig.readCond); @@ -556,31 +568,24 @@ 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; } - stonesenseState.ssConfig.overlay_mode = false; + + auto& ssConfig = stonesenseState.ssConfig; + ssConfig.overlay_mode = false; if(params.size() > 0 ) { if(params[0] == "overlay"){ - //ssConfig.overlay_mode = true; + 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); return CR_OK;