Merge branch 'develop' into myk_cpp20

develop
Myk Taylor 2023-07-03 11:49:54 -07:00
commit f111b69f2f
No known key found for this signature in database
GPG Key ID: 8A39CA0FA0C16E78
39 changed files with 344 additions and 982 deletions

3
.gitignore vendored

@ -81,5 +81,6 @@ tags
# external plugins # external plugins
/plugins/CMakeLists.custom.txt /plugins/CMakeLists.custom.txt
# steam api # 3rd party downloads
depends/steam depends/steam
depends/SDL2

@ -7,9 +7,9 @@ cmake_policy(SET CMP0074 NEW)
project(dfhack) project(dfhack)
# set up versioning. # set up versioning.
set(DF_VERSION "50.08") set(DF_VERSION "50.09")
set(DFHACK_RELEASE "r4rc1") set(DFHACK_RELEASE "r1")
set(DFHACK_PRERELEASE TRUE) set(DFHACK_PRERELEASE FALSE)
set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}") set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}")
set(DFHACK_ABI_VERSION 1) set(DFHACK_ABI_VERSION 1)
@ -61,9 +61,9 @@ endif()
if(WIN32) if(WIN32)
if(NOT MSVC) if(NOT MSVC)
message(SEND_ERROR "No MSVC found! MSVC 2022 version 1930 to 1935 is required.") message(SEND_ERROR "No MSVC found! MSVC 2022 version 1930 to 1936 is required.")
elseif((MSVC_VERSION LESS 1930) OR (MSVC_VERSION GREATER 1935)) elseif((MSVC_VERSION LESS 1930) OR (MSVC_VERSION GREATER 1936))
message(SEND_ERROR "MSVC 2022 version 1930 to 1935 is required, Version Found: ${MSVC_VERSION}") message(SEND_ERROR "MSVC 2022 version 1930 to 1936 is required, Version Found: ${MSVC_VERSION}")
endif() endif()
endif() endif()
@ -291,23 +291,20 @@ endif()
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
include_directories(${ZLIB_INCLUDE_DIRS}) include_directories(${ZLIB_INCLUDE_DIRS})
if(WIN32) # Download SDL release and extract into depends in the build dir
# Do the same for SDL.dll # all we need are the header files (including generated headers), so the same release package
# (DFHack doesn't require this at build time, so no need to move it to the build folder) # will work for all platforms
# TODO: remove SDL.dll from our distribution once DF moves to SDL2. we only # (the above statement is untested for OSX)
# continue to include it so we don't break Steam players on update by removing set(SDL_VERSION 2.26.2)
# the SDL.dll that DF needs. set(SDL_ZIP_MD5 574daf26d48de753d0b1e19823c9d8bb)
set(SDL_DOWNLOAD_DIR ${dfhack_SOURCE_DIR}/package/windows/win${DFHACK_BUILD_ARCH}) set(SDL_ZIP_FILE SDL2-devel-${SDL_VERSION}-VC.zip)
if(${DFHACK_BUILD_ARCH} STREQUAL "64") set(SDL_ZIP_PATH ${dfhack_SOURCE_DIR}/depends/SDL2/)
download_file("https://github.com/DFHack/dfhack-bin/releases/download/0.44.09/win64-SDL.dll" download_file("https://github.com/libsdl-org/SDL/releases/download/release-${SDL_VERSION}/${SDL_ZIP_FILE}"
${SDL_DOWNLOAD_DIR}/SDL.dll ${SDL_ZIP_PATH}${SDL_ZIP_FILE}
"1ae242c4b94cb03756a1288122a66faf") ${SDL_ZIP_MD5})
else() file(ARCHIVE_EXTRACT INPUT ${SDL_ZIP_PATH}${SDL_ZIP_FILE}
download_file("https://github.com/DFHack/dfhack-bin/releases/download/0.44.09/win32-SDL.dll" DESTINATION ${SDL_ZIP_PATH})
${SDL_DOWNLOAD_DIR}/SDL.dll include_directories(${SDL_ZIP_PATH}/SDL2-${SDL_VERSION}/include)
"5a09604daca6b2b5ce049d79af935d6a")
endif()
endif()
if(APPLE) if(APPLE)
# libstdc++ (GCC 4.8.5 for OS X 10.6) # libstdc++ (GCC 4.8.5 for OS X 10.6)

Binary file not shown.

After

Width:  |  Height:  |  Size: 615 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

@ -250,7 +250,7 @@ Features:
- A grid of small farm plots for lucrative surface farming - A grid of small farm plots for lucrative surface farming
"" ""
Manual steps you have to take: Manual steps you have to take:
- Assign grazing livestock to the large pasture and dogs to the pasture over the central stairs (DFHack's autonestbox can manage the nestbox zones) "- Assign grazing livestock to the large pasture, dogs to the pasture over the central stairs, and male birds to the zone between the rows of nestboxes (DFHack's autonestbox will auto-assign the female egg-laying birds to the nestbox zones)"
- Connect levers to the drawbridges that match the names of the levers - Connect levers to the drawbridges that match the names of the levers
- Assign minecarts to the trade goods and prisoner processing quantum stockpile hauling routes with assign-minecarts all - Assign minecarts to the trade goods and prisoner processing quantum stockpile hauling routes with assign-minecarts all
"" ""
@ -412,7 +412,7 @@ corridor_traps/surface_corridor_traps
#zone label(surface_zones) start(19; 19) hidden() message(Remember to assign your dogs to the pasture surrounding the central stairs and your grazing animals to the large pasture.) pastures and training areas "#zone label(surface_zones) start(19; 19) hidden() message(Remember to assign your dogs to the pasture surrounding the central stairs, your grazing animals to the large pasture, and your male birds to the zone between the rows of nestboxes.) pastures and training areas"
@ -430,7 +430,7 @@ corridor_traps/surface_corridor_traps
,,,`,,`,,,,,,,,,,,,,,,,,,,,,,,,,,`,,` ,,,`,,`,,,,,,,,,,,,,,,,,,,,,,,,,,`,,`
,,,`,,`,`,`,`,`,`,`,`,`,`,`,`,,`,,`,`,`,`,`,`,`,`,`,`,`,`,,` ,,,`,,`,`,`,`,`,`,`,`,`,`,`,`,,`,,`,`,`,`,`,`,`,`,`,`,`,`,,`
,,,`,,`,,`,"n{name=""Nestbox 1""}(1x1)","n{name=""Nestbox 2""}(1x1)","n{name=""Nestbox 3""}(1x1)","n{name=""Nestbox 4""}(1x1)","n{name=""Nestbox 5""}(1x1)","n{name=""Nestbox 6""}(1x1)","n{name=""Nestbox 7""}(1x1)",`,,,,,,`,,,,,,,,,,`,,` ,,,`,,`,,`,"n{name=""Nestbox 1""}(1x1)","n{name=""Nestbox 2""}(1x1)","n{name=""Nestbox 3""}(1x1)","n{name=""Nestbox 4""}(1x1)","n{name=""Nestbox 5""}(1x1)","n{name=""Nestbox 6""}(1x1)","n{name=""Nestbox 7""}(1x1)",`,,,,,,`,,,,,,,,,,`,,`
,,,`,,`,,`,,,,,,,,,"n/guarddogs{name=""Guard dogs""}(5x1)",~,~,~,~,,,,,,,,,,,`,,` ,,,`,,`,,`,"n{name=""Male birds""}(7x3)",,,,,,,,"n/guarddogs{name=""Guard dogs""}(5x1)",~,~,~,~,,,,,,,,,,,`,,`
,,,`,,`,,,,,,,,,,`,,`,~,`,,`,,,,,,,,,,`,,` ,,,`,,`,,,,,,,,,,`,,`,~,`,,`,,,,,,,,,,`,,`
,,,`,,`,,`,,,,,,,,,n/guarddogs(5x1),~,~,~,~,,,,,,,,,,,`,,` ,,,`,,`,,`,,,,,,,,,n/guarddogs(5x1),~,~,~,~,,,,,,,,,,,`,,`
,,,`,,`,,`,"n{name=""Nestbox 8""}(1x1)","n{name=""Nestbox 9""}(1x1)","n{name=""Nestbox 10""}(1x1)","n{name=""Nestbox 11""}(1x1)","n{name=""Nestbox 12""}(1x1)","n{name=""Nestbox 13""}(1x1)","n{name=""Nestbox 14""}(1x1)",`,,,,,,`,,,,,,,,,,`,,` ,,,`,,`,,`,"n{name=""Nestbox 8""}(1x1)","n{name=""Nestbox 9""}(1x1)","n{name=""Nestbox 10""}(1x1)","n{name=""Nestbox 11""}(1x1)","n{name=""Nestbox 12""}(1x1)","n{name=""Nestbox 13""}(1x1)","n{name=""Nestbox 14""}(1x1)",`,,,,,,`,,,,,,,,,,`,,`
@ -1686,7 +1686,7 @@ build2/industry_build2
,,w,`,`,`,`,`,`,`,`,`,`,`,,,`,,`,,,`,`,`,`,`,`,`,`,`,`,`,c ,,w,`,`,`,`,`,`,`,`,`,`,`,,,`,,`,,,`,`,`,`,`,`,`,`,`,`,`,c
,,w,`,`,`,`,`,`,"w{name=""Wood feeder""}(2x5)",,"g{name=""Goods feeder"" containers=0}:+cat_food/tallow+wax-crafts-goblets(3x3)",,`,,`,`,`,`,`,,"hlS{name=""Cloth/bones feeder"" containers=0}:+cat_refuse/skulls/,bones/,hair/,shells/,teeth/,horns/-adamantinethread(5x5)",,,~,~,`,`,`,`,`,`,c ,,w,`,`,`,`,`,`,"w{name=""Wood feeder""}(2x5)",,"g{name=""Goods feeder"" containers=0}:+cat_food/tallow+wax-crafts-goblets(3x3)",,`,,`,`,`,`,`,,"hlS{name=""Cloth/bones feeder"" containers=0}:+cat_refuse/skulls/,bones/,hair/,shells/,teeth/,horns/-adamantinethread(5x5)",,,~,~,`,`,`,`,`,`,c
,,w,`,`,`,`,`,`,~,~,~,~,~,`,`,,,,`,`,~,~,~,~,~,`,`,`,`,`,`,c ,,w,`,`,`,`,`,`,~,~,~,~,~,`,`,,,,`,`,~,~,~,~,~,`,`,`,`,`,`,c
,,`,`,`,`,`,"c{name=""Goods/wood quantum"" quantum=true give_to=Pots,Barrels,Jugs,Bags}:+all",`,~,~,~,~,~,,`,,`,,`,,~,~,~,~,~,`,"r{name=""Cloth/bones quantum"" quantum=true}:+all",`,`,`,`,c ,,`,`,`,`,`,"c{name=""Goods/wood quantum"" quantum=true give_to=""Pots,Barrels,Jugs,Bags,Seeds feeder""}:+all",`,~,~,~,~,~,,`,,`,,`,,~,~,~,~,~,`,"r{name=""Cloth/bones quantum"" quantum=true}:+all",`,`,`,`,c
,,"c{name=""Lye"" barrels=2}:+miscliquid",`,`,`,`,`,`,~,~,"u{name=""Furniture feeder""}:-sand(3x2)",~,~,`,`,,,,`,`,~,~,~,~,~,`,`,`,`,`,`,c ,,"c{name=""Lye"" barrels=2}:+miscliquid",`,`,`,`,`,`,~,~,"u{name=""Furniture feeder""}:-sand(3x2)",~,~,`,`,,,,`,`,~,~,~,~,~,`,`,`,`,`,`,c
,,c,`,`,`,`,`,`,~,~,~,~,~,,`,`,`,`,`,,~,~,~,~,~,`,`,`,`,`,`,c ,,c,`,`,`,`,`,`,~,~,~,~,~,,`,`,`,`,`,,~,~,~,~,~,`,`,`,`,`,`,c
,,c,`,`,`,`,`,`,`,`,`,`,`,,,`,,`,,,`,`,`,`,`,`,`,`,`,`,`,c ,,c,`,`,`,`,`,`,`,`,`,`,`,,,`,,`,,,`,`,`,`,`,`,`,`,`,`,`,c

Can't render this file because it has a wrong number of fields in line 53.

@ -418,7 +418,7 @@
"condition" : "AtLeast", "condition" : "AtLeast",
"item_type" : "BOULDER", "item_type" : "BOULDER",
"material" : "INORGANIC:CASSITERITE", "material" : "INORGANIC:CASSITERITE",
"value" : 5 "value" : 25
}, },
{ {
"condition" : "AtLeast", "condition" : "AtLeast",
@ -697,7 +697,7 @@
"bearing" : "TIN", "bearing" : "TIN",
"condition" : "AtLeast", "condition" : "AtLeast",
"item_type" : "BOULDER", "item_type" : "BOULDER",
"value" : 5 "value" : 25
}, },
{ {
"bearing" : "COPPER", "bearing" : "COPPER",
@ -758,7 +758,7 @@
"bearing" : "TIN", "bearing" : "TIN",
"condition" : "AtMost", "condition" : "AtMost",
"item_type" : "BOULDER", "item_type" : "BOULDER",
"value" : 5 "value" : 25
}, },
{ {
"bearing" : "COPPER", "bearing" : "COPPER",

@ -43,7 +43,7 @@
"condition" : "AtLeast", "condition" : "AtLeast",
"item_type" : "BOULDER", "item_type" : "BOULDER",
"material" : "INORGANIC:CASSITERITE", "material" : "INORGANIC:CASSITERITE",
"value" : 5 "value" : 25
}, },
{ {
"condition" : "AtLeast", "condition" : "AtLeast",
@ -668,7 +668,7 @@
"bearing" : "TIN", "bearing" : "TIN",
"condition" : "AtLeast", "condition" : "AtLeast",
"item_type" : "BOULDER", "item_type" : "BOULDER",
"value" : 5 "value" : 25
}, },
{ {
"bearing" : "COPPER", "bearing" : "COPPER",
@ -729,7 +729,7 @@
"bearing" : "TIN", "bearing" : "TIN",
"condition" : "AtMost", "condition" : "AtMost",
"item_type" : "BOULDER", "item_type" : "BOULDER",
"value" : 5 "value" : 25
}, },
{ {
"bearing" : "COPPER", "bearing" : "COPPER",

@ -33,6 +33,27 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
# Future # Future
## New Plugins
## Fixes
## Misc Improvements
## Documentation
## API
## Internals
## Lua
- ``dfhack.items.markForTrade``: new API for marking items for trade
## Removed
# 50.09-r1
# 50.08-r4
## New Plugins ## New Plugins
- `logistics`: automatically mark and route items or animals that come to monitored stockpiles. options are toggleable on an overlay that comes up when you have a stockpile selected. - `logistics`: automatically mark and route items or animals that come to monitored stockpiles. options are toggleable on an overlay that comes up when you have a stockpile selected.
@ -44,21 +65,15 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
## Misc Improvements ## Misc Improvements
- `autonick`: additional nicknames based on burrowing animals, colours, gems, and minerals - `autonick`: additional nicknames based on burrowing animals, colours, gems, and minerals
- `stockpiles`: added ``barrels``, ``organic``, ``artifacts``, and ``masterworks`` stockpile presets - `stockpiles`: added ``barrels``, ``organic``, ``artifacts``, and ``masterworks`` stockpile presets
- `orders`: only display import/export/sort/clear panel on main orders screen
- `orders`: refine order conditions for library orders to reduce cancellation spam
- Blueprint library: dreamfort: full rewrite and update for DF v50 - Blueprint library: dreamfort: full rewrite and update for DF v50
- Blueprint library: pump_stack: updated walkthrough and separated dig and channel steps so boulders can be cleared - Blueprint library: pump_stack: updated walkthrough and separated dig and channel steps so boulders can be cleared
- Blueprint library: aquifer_tap: updated walkthrough - Blueprint library: aquifer_tap: updated walkthrough
- `orders`: better order conditions for the ``smelting`` library orders to reduce cancellation spam - `dig-now`: can now handle digging obsidian that has been formed from magma and water
## Documentation ## Documentation
- `blueprint-library-guide`: update Dreamfort screenshots, add ``aquifer_tap`` screenshot - `blueprint-library-guide`: update Dreamfort screenshots and links, add ``aquifer_tap`` screenshot
## API
## Internals
## Lua
## Removed
# 50.08-r3 # 50.08-r3

@ -1775,6 +1775,10 @@ Items module
Checks whether the item and all items it contains, if any, can be traded. Checks whether the item and all items it contains, if any, can be traded.
* ``dfhack.items.markForTrade(item, depot)``
Marks the given item for trade at the given depot.
* ``dfhack.items.isRouteVehicle(item)`` * ``dfhack.items.isRouteVehicle(item)``
Checks whether the item is an assigned hauling vehicle. Checks whether the item is an assigned hauling vehicle.

@ -217,7 +217,7 @@ create a drainage system so your dwarves don't drown when digging the tap, by
running the ``library/aquifer_tap.csv`` ``/help`` blueprint. running the ``library/aquifer_tap.csv`` ``/help`` blueprint.
You can see how to nullify the water pressure (so you don't flood your fort) in You can see how to nullify the water pressure (so you don't flood your fort) in
the `Dreamfort screenshot above <Services levels (4 deep)>`_. the Dreamfort cistern screenshot above: `Services levels (4 deep)`_.
The blueprint spreadsheet is also available The blueprint spreadsheet is also available
`online <https://docs.google.com/spreadsheets/d/1kwuCipF9FYAHNP9C_XlMpqVseaPu4SmL9YLUSQkbW4s/edit#gid=611877584>`__. `online <https://docs.google.com/spreadsheets/d/1kwuCipF9FYAHNP9C_XlMpqVseaPu4SmL9YLUSQkbW4s/edit#gid=611877584>`__.

@ -431,10 +431,6 @@ if(UNIX)
install(TARGETS dfhooks install(TARGETS dfhooks
LIBRARY DESTINATION . LIBRARY DESTINATION .
RUNTIME DESTINATION .) RUNTIME DESTINATION .)
else()
# On windows, copy SDL.dll so DF can still run.
install(PROGRAMS ${dfhack_SOURCE_DIR}/package/windows/win${DFHACK_BUILD_ARCH}/SDL.dll
DESTINATION ${DFHACK_LIBRARY_DESTINATION})
endif() endif()
# install the main lib # install the main lib

@ -84,7 +84,7 @@ using namespace DFHack;
#include <condition_variable> #include <condition_variable>
#include "md5wrapper.h" #include "md5wrapper.h"
#include "SDL_events.h" #include <SDL_events.h>
#ifdef LINUX_BUILD #ifdef LINUX_BUILD
#include <dlfcn.h> #include <dlfcn.h>
@ -2347,99 +2347,37 @@ bool Core::DFH_ncurses_key(int key)
return ncurses_wgetch(key, dummy); return ncurses_wgetch(key, dummy);
} }
int UnicodeAwareSym(const SDL::KeyboardEvent& ke)
{
// Assume keyboard layouts don't change the order of numbers:
if( '0' <= ke.ksym.sym && ke.ksym.sym <= '9') return ke.ksym.sym;
if(SDL::K_F1 <= ke.ksym.sym && ke.ksym.sym <= SDL::K_F12) return ke.ksym.sym;
// These keys are mapped to the same control codes as Ctrl-?
switch (ke.ksym.sym)
{
case SDL::K_RETURN:
case SDL::K_KP_ENTER:
case SDL::K_TAB:
case SDL::K_ESCAPE:
case SDL::K_DELETE:
return ke.ksym.sym;
default:
break;
}
int unicode = ke.ksym.unicode;
// convert Ctrl characters to their 0x40-0x5F counterparts:
if (unicode < ' ')
{
unicode += 'A' - 1;
}
// convert A-Z to their a-z counterparts:
if('A' <= unicode && unicode <= 'Z')
{
unicode += 'a' - 'A';
}
// convert various other punctuation marks:
if('\"' == unicode) unicode = '\'';
if('+' == unicode) unicode = '=';
if(':' == unicode) unicode = ';';
if('<' == unicode) unicode = ',';
if('>' == unicode) unicode = '.';
if('?' == unicode) unicode = '/';
if('{' == unicode) unicode = '[';
if('|' == unicode) unicode = '\\';
if('}' == unicode) unicode = ']';
if('~' == unicode) unicode = '`';
return unicode;
}
// returns true if the event is handled // returns true if the event is handled
bool Core::DFH_SDL_Event(SDL::Event* ev) bool Core::DFH_SDL_Event(SDL_Event* ev)
{ {
// do NOT process events before we are ready. // do NOT process events before we are ready.
if(!started || !ev) if(!started || !ev)
return false; return false;
if(ev->type == SDL::ET_ACTIVEEVENT && ev->active.gain) if (ev->type == SDL_WINDOWEVENT && ev->window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
{
// clear modstate when gaining focus in case alt-tab was used when // clear modstate when gaining focus in case alt-tab was used when
// losing focus and modstate is now incorrectly set // losing focus and modstate is now incorrectly set
modstate = 0; modstate = 0;
return false; return false;
} }
if(ev->type == SDL::ET_KEYDOWN || ev->type == SDL::ET_KEYUP) if (ev->type == SDL_KEYDOWN || ev->type == SDL_KEYUP) {
{ auto &ke = ev->key;
auto ke = (SDL::KeyboardEvent *)ev;
if (ke->ksym.sym == SDL::K_LSHIFT || ke->ksym.sym == SDL::K_RSHIFT)
modstate = (ev->type == SDL::ET_KEYDOWN) ? modstate | DFH_MOD_SHIFT : modstate & ~DFH_MOD_SHIFT;
else if (ke->ksym.sym == SDL::K_LCTRL || ke->ksym.sym == SDL::K_RCTRL)
modstate = (ev->type == SDL::ET_KEYDOWN) ? modstate | DFH_MOD_CTRL : modstate & ~DFH_MOD_CTRL;
else if (ke->ksym.sym == SDL::K_LALT || ke->ksym.sym == SDL::K_RALT)
modstate = (ev->type == SDL::ET_KEYDOWN) ? modstate | DFH_MOD_ALT : modstate & ~DFH_MOD_ALT;
else if(ke->state == SDL::BTN_PRESSED && !hotkey_states[ke->ksym.sym])
{
hotkey_states[ke->ksym.sym] = true;
// Use unicode so Windows gives the correct value for the if (ke.keysym.sym == SDLK_LSHIFT || ke.keysym.sym == SDLK_RSHIFT)
// user's Input Language modstate = (ev->type == SDL_KEYDOWN) ? modstate | DFH_MOD_SHIFT : modstate & ~DFH_MOD_SHIFT;
if(ke->ksym.unicode && ((ke->ksym.unicode & 0xff80) == 0)) else if (ke.keysym.sym == SDLK_LCTRL || ke.keysym.sym == SDLK_RCTRL)
{ modstate = (ev->type == SDL_KEYDOWN) ? modstate | DFH_MOD_CTRL : modstate & ~DFH_MOD_CTRL;
int key = UnicodeAwareSym(*ke); else if (ke.keysym.sym == SDLK_LALT || ke.keysym.sym == SDLK_RALT)
SelectHotkey(key, modstate); modstate = (ev->type == SDL_KEYDOWN) ? modstate | DFH_MOD_ALT : modstate & ~DFH_MOD_ALT;
} else if (ke.state == SDL_PRESSED && !hotkey_states[ke.keysym.sym])
else
{ {
// Pretend non-ascii characters don't happen: hotkey_states[ke.keysym.sym] = true;
SelectHotkey(ke->ksym.sym, modstate); SelectHotkey(ke.keysym.sym, modstate);
}
} }
else if(ke->state == SDL::BTN_RELEASED) else if(ke.state == SDL_RELEASED)
{ {
hotkey_states[ke->ksym.sym] = false; hotkey_states[ke.keysym.sym] = false;
} }
} }
return false; return false;
@ -2455,12 +2393,12 @@ bool Core::SelectHotkey(int sym, int modifiers)
while (screen->child) while (screen->child)
screen = screen->child; screen = screen->child;
if (sym == SDL::K_KP_ENTER) if (sym == SDLK_KP_ENTER)
sym = SDL::K_RETURN; sym = SDLK_RETURN;
std::string cmd; std::string cmd;
DEBUG(keybinding).print("checking hotkeys for sym=%d, modifiers=%x\n", sym, modifiers); DEBUG(keybinding).print("checking hotkeys for sym=%d (%c), modifiers=%x\n", sym, sym, modifiers);
{ {
std::lock_guard<std::mutex> lock(HotkeyMutex); std::lock_guard<std::mutex> lock(HotkeyMutex);
@ -2497,7 +2435,7 @@ bool Core::SelectHotkey(int sym, int modifiers)
if (cmd.empty()) { if (cmd.empty()) {
// Check the hotkey keybindings // Check the hotkey keybindings
int idx = sym - SDL::K_F1; int idx = sym - SDLK_F1;
if(idx >= 0 && idx < 8) if(idx >= 0 && idx < 8)
{ {
/* TODO: understand how this changes for v50 /* TODO: understand how this changes for v50
@ -2555,22 +2493,22 @@ static bool parseKeySpec(std::string keyspec, int *psym, int *pmod, std::string
} }
if (keyspec.size() == 1 && keyspec[0] >= 'A' && keyspec[0] <= 'Z') { if (keyspec.size() == 1 && keyspec[0] >= 'A' && keyspec[0] <= 'Z') {
*psym = SDL::K_a + (keyspec[0]-'A'); *psym = SDLK_a + (keyspec[0]-'A');
return true; return true;
} else if (keyspec.size() == 1 && keyspec[0] == '`') { } else if (keyspec.size() == 1 && keyspec[0] == '`') {
*psym = SDL::K_BACKQUOTE; *psym = SDLK_BACKQUOTE;
return true; return true;
} else if (keyspec.size() == 1 && keyspec[0] >= '0' && keyspec[0] <= '9') { } else if (keyspec.size() == 1 && keyspec[0] >= '0' && keyspec[0] <= '9') {
*psym = SDL::K_0 + (keyspec[0]-'0'); *psym = SDLK_0 + (keyspec[0]-'0');
return true; return true;
} else if (keyspec.size() == 2 && keyspec[0] == 'F' && keyspec[1] >= '1' && keyspec[1] <= '9') { } else if (keyspec.size() == 2 && keyspec[0] == 'F' && keyspec[1] >= '1' && keyspec[1] <= '9') {
*psym = SDL::K_F1 + (keyspec[1]-'1'); *psym = SDLK_F1 + (keyspec[1]-'1');
return true; return true;
} else if (keyspec.size() == 3 && keyspec.substr(0, 2) == "F1" && keyspec[2] >= '0' && keyspec[2] <= '2') { } else if (keyspec.size() == 3 && keyspec.substr(0, 2) == "F1" && keyspec[2] >= '0' && keyspec[2] <= '2') {
*psym = SDL::K_F10 + (keyspec[2]-'0'); *psym = SDLK_F10 + (keyspec[2]-'0');
return true; return true;
} else if (keyspec == "Enter") { } else if (keyspec == "Enter") {
*psym = SDL::K_RETURN; *psym = SDLK_RETURN;
return true; return true;
} else } else
return false; return false;

@ -48,7 +48,7 @@ DFhackCExport void dfhooks_prerender() {
// called from the main thread for each SDL event. if true is returned, then // called from the main thread for each SDL event. if true is returned, then
// the event has been consumed and further processing shouldn't happen // the event has been consumed and further processing shouldn't happen
DFhackCExport bool dfhooks_sdl_event(SDL::Event* event) { DFhackCExport bool dfhooks_sdl_event(SDL_Event* event) {
if (disabled) if (disabled)
return false; return false;
return DFHack::Core::getInstance().DFH_SDL_Event(event); return DFHack::Core::getInstance().DFH_SDL_Event(event);

@ -1715,6 +1715,7 @@ static const LuaWrapper::FunctionReg dfhack_textures_module[] = {
WRAPM(Textures, getRedPinTexposStart), WRAPM(Textures, getRedPinTexposStart),
WRAPM(Textures, getIconsTexposStart), WRAPM(Textures, getIconsTexposStart),
WRAPM(Textures, getOnOffTexposStart), WRAPM(Textures, getOnOffTexposStart),
WRAPM(Textures, getMapUnsuspendTexposStart),
WRAPM(Textures, getControlPanelTexposStart), WRAPM(Textures, getControlPanelTexposStart),
WRAPM(Textures, getThinBordersTexposStart), WRAPM(Textures, getThinBordersTexposStart),
WRAPM(Textures, getMediumBordersTexposStart), WRAPM(Textures, getMediumBordersTexposStart),
@ -2013,6 +2014,7 @@ static const LuaWrapper::FunctionReg dfhack_items_module[] = {
WRAPM(Items, checkMandates), WRAPM(Items, checkMandates),
WRAPM(Items, canTrade), WRAPM(Items, canTrade),
WRAPM(Items, canTradeWithContents), WRAPM(Items, canTradeWithContents),
WRAPM(Items, markForTrade),
WRAPM(Items, isRouteVehicle), WRAPM(Items, isRouteVehicle),
WRAPM(Items, isSquadEquipment), WRAPM(Items, isSquadEquipment),
WRAPN(moveToGround, items_moveToGround), WRAPN(moveToGround, items_moveToGround),
@ -2635,6 +2637,7 @@ static int screen_charToKey(lua_State *L)
return 1; return 1;
} }
/*
static int screen_zoom(lua_State *L) static int screen_zoom(lua_State *L)
{ {
using df::global::enabler; using df::global::enabler;
@ -2651,6 +2654,7 @@ static int screen_zoom(lua_State *L)
enabler->zoom_display(cmd); enabler->zoom_display(cmd);
return 0; return 0;
} }
*/
} }
@ -2671,7 +2675,7 @@ static const luaL_Reg dfhack_screen_funcs[] = {
{ "_doSimulateInput", screen_doSimulateInput }, { "_doSimulateInput", screen_doSimulateInput },
{ "keyToChar", screen_keyToChar }, { "keyToChar", screen_keyToChar },
{ "charToKey", screen_charToKey }, { "charToKey", screen_charToKey },
{ "zoom", screen_zoom }, //{ "zoom", screen_zoom },
{ NULL, NULL } { NULL, NULL }
}; };

@ -110,7 +110,7 @@ namespace DFHack
friend void ::dfhooks_shutdown(); friend void ::dfhooks_shutdown();
friend void ::dfhooks_update(); friend void ::dfhooks_update();
friend void ::dfhooks_prerender(); friend void ::dfhooks_prerender();
friend bool ::dfhooks_sdl_event(SDL::Event* event); friend bool ::dfhooks_sdl_event(SDL_Event* event);
friend bool ::dfhooks_ncurses_key(int key); friend bool ::dfhooks_ncurses_key(int key);
public: public:
/// Get the single Core instance or make one. /// Get the single Core instance or make one.
@ -193,7 +193,7 @@ namespace DFHack
bool InitSimulationThread(); bool InitSimulationThread();
int Update (void); int Update (void);
int Shutdown (void); int Shutdown (void);
bool DFH_SDL_Event(SDL::Event* event); bool DFH_SDL_Event(SDL_Event* event);
bool ncurses_wgetch(int in, int & out); bool ncurses_wgetch(int in, int & out);
bool DFH_ncurses_key(int key); bool DFH_ncurses_key(int key);

@ -24,61 +24,11 @@ distribution.
#pragma once #pragma once
/* union SDL_Event;
* Some much needed SDL fakery.
*/
#include "Pragma.h"
#include "Export.h"
#include <string>
#include <stdint.h>
#include "modules/Graphic.h"
// function and variable pointer... we don't try to understand what SDL does here
typedef void * fPtr;
typedef void * vPtr;
struct WINDOW;
namespace SDL
{
union Event;
}
// these functions are here because they call into DFHack::Core and therefore need to
// be declared as friend functions/known
#ifdef _DARWIN
DFhackCExport int DFH_SDL_NumJoysticks(void);
DFhackCExport void DFH_SDL_Quit(void);
DFhackCExport int DFH_SDL_PollEvent(SDL::Event* event);
DFhackCExport int DFH_SDL_Init(uint32_t flags);
DFhackCExport int DFH_wgetch(WINDOW * win);
#endif
DFhackCExport int SDL_NumJoysticks(void);
DFhackCExport void SDL_Quit(void);
DFhackCExport int SDL_PollEvent(SDL::Event* event);
DFhackCExport int SDL_PushEvent(SDL::Event* event);
DFhackCExport int SDL_Init(uint32_t flags);
DFhackCExport int wgetch(WINDOW * win);
DFhackCExport int SDL_UpperBlit(DFHack::DFSDL_Surface* src, DFHack::DFSDL_Rect* srcrect, DFHack::DFSDL_Surface* dst, DFHack::DFSDL_Rect* dstrect);
DFhackCExport vPtr SDL_CreateRGBSurface(uint32_t flags, int width, int height, int depth,
uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask);
DFhackCExport vPtr SDL_CreateRGBSurfaceFrom(vPtr pixels, int width, int height, int depth, int pitch,
uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask);
DFhackCExport void SDL_FreeSurface(vPtr surface);
DFhackCExport vPtr SDL_ConvertSurface(vPtr surface, vPtr format, uint32_t flags);
DFhackCExport int SDL_LockSurface(vPtr surface);
DFhackCExport void SDL_UnlockSurface(vPtr surface);
DFhackCExport uint8_t SDL_GetMouseState(int *x, int *y);
DFhackCExport void * SDL_GetVideoSurface(void);
DFhackCExport int SDL_SemWait(vPtr sem);
DFhackCExport int SDL_SemPost(vPtr sem);
// new Hooks API
DFhackCExport void dfhooks_init(); DFhackCExport void dfhooks_init();
DFhackCExport void dfhooks_shutdown(); DFhackCExport void dfhooks_shutdown();
DFhackCExport void dfhooks_update(); DFhackCExport void dfhooks_update();
DFhackCExport void dfhooks_prerender(); DFhackCExport void dfhooks_prerender();
DFhackCExport bool dfhooks_sdl_event(SDL::Event* event); DFhackCExport bool dfhooks_sdl_event(SDL_Event* event);
DFhackCExport bool dfhooks_ncurses_key(int key); DFhackCExport bool dfhooks_ncurses_key(int key);

@ -1,210 +0,0 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2009 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
// Fake - only structs. Shamelessly pilfered from the SDL library.
// Needed for processing its event types without polluting our namespaces with C garbage
#pragma once
#include "SDL_keyboard.h"
namespace SDL
{
enum ButtonState
{
BTN_RELEASED = 0,
BTN_PRESSED = 1
};
/** Event enumerations */
enum EventType
{
ET_NOEVENT = 0, /**< Unused (do not remove) */
ET_ACTIVEEVENT, /**< Application loses/gains visibility */
ET_KEYDOWN, /**< Keys pressed */
ET_KEYUP, /**< Keys released */
ET_MOUSEMOTION, /**< Mouse moved */
ET_MOUSEBUTTONDOWN, /**< Mouse button pressed */
ET_MOUSEBUTTONUP, /**< Mouse button released */
ET_JOYAXISMOTION, /**< Joystick axis motion */
ET_JOYBALLMOTION, /**< Joystick trackball motion */
ET_JOYHATMOTION, /**< Joystick hat position change */
ET_JOYBUTTONDOWN, /**< Joystick button pressed */
ET_JOYBUTTONUP, /**< Joystick button released */
ET_QUIT, /**< User-requested quit */
ET_SYSWMEVENT, /**< System specific event */
ET_EVENT_RESERVEDA, /**< Reserved for future use.. */
ET_EVENT_RESERVEDB, /**< Reserved for future use.. */
ET_VIDEORESIZE, /**< User resized video mode */
ET_VIDEOEXPOSE, /**< Screen needs to be redrawn */
ET_EVENT_RESERVED2, /**< Reserved for future use.. */
ET_EVENT_RESERVED3, /**< Reserved for future use.. */
ET_EVENT_RESERVED4, /**< Reserved for future use.. */
ET_EVENT_RESERVED5, /**< Reserved for future use.. */
ET_EVENT_RESERVED6, /**< Reserved for future use.. */
ET_EVENT_RESERVED7, /**< Reserved for future use.. */
/** Events ET_USEREVENT through ET_MAXEVENTS-1 are for your use */
ET_USEREVENT = 24,
/** This last event is only for bounding internal arrays
* It is the number of bits in the event mask datatype -- Uint32
*/
ET_NUMEVENTS = 32
};
/** Application visibility event structure */
struct ActiveEvent
{
uint8_t type; /**< ET_ACTIVEEVENT */
uint8_t gain; /**< Whether given states were gained or lost (1/0) */
uint8_t state; /**< A mask of the focus states */
};
/** Keyboard event structure */
struct KeyboardEvent
{
uint8_t type; /**< ET_KEYDOWN or ET_KEYUP */
uint8_t which; /**< The keyboard device index */
uint8_t state; /**< BTN_PRESSED or BTN_RELEASED */
keysym ksym;
};
/** Mouse motion event structure */
struct MouseMotionEvent
{
uint8_t type; /**< ET_MOUSEMOTION */
uint8_t which; /**< The mouse device index */
uint8_t state; /**< The current button state */
uint16_t x, y; /**< The X/Y coordinates of the mouse */
int16_t xrel; /**< The relative motion in the X direction */
int16_t yrel; /**< The relative motion in the Y direction */
};
/** Mouse button event structure */
struct MouseButtonEvent
{
uint8_t type; /**< ET_MOUSEBUTTONDOWN or ET_MOUSEBUTTONUP */
uint8_t which; /**< The mouse device index */
uint8_t button; /**< The mouse button index */
uint8_t state; /**< BTN_PRESSED or BTN_RELEASED */
uint16_t x, y; /**< The X/Y coordinates of the mouse at press time */
};
/** Joystick axis motion event structure */
struct JoyAxisEvent
{
uint8_t type; /**< ET_JOYAXISMOTION */
uint8_t which; /**< The joystick device index */
uint8_t axis; /**< The joystick axis index */
int16_t value; /**< The axis value (range: -32768 to 32767) */
};
/** Joystick trackball motion event structure */
struct JoyBallEvent
{
uint8_t type; /**< ET_JOYBALLMOTION */
uint8_t which; /**< The joystick device index */
uint8_t ball; /**< The joystick trackball index */
int16_t xrel; /**< The relative motion in the X direction */
int16_t yrel; /**< The relative motion in the Y direction */
};
/** Joystick hat position change event structure */
struct JoyHatEvent
{
uint8_t type; /**< ET_JOYHATMOTION */
uint8_t which; /**< The joystick device index */
uint8_t hat; /**< The joystick hat index */
uint8_t value; /**< The hat position value:
* SDL_HAT_LEFTUP SDL_HAT_UP SDL_HAT_RIGHTUP
* SDL_HAT_LEFT SDL_HAT_CENTERED SDL_HAT_RIGHT
* SDL_HAT_LEFTDOWN SDL_HAT_DOWN SDL_HAT_RIGHTDOWN
* Note that zero means the POV is centered.
*/
};
/** Joystick button event structure */
struct JoyButtonEvent
{
uint8_t type; /**< ET_JOYBUTTONDOWN or ET_JOYBUTTONUP */
uint8_t which; /**< The joystick device index */
uint8_t button; /**< The joystick button index */
uint8_t state; /**< BTN_PRESSED or BTN_RELEASED */
};
/** The "window resized" event
* When you get this event, you are responsible for setting a new video
* mode with the new width and height.
*/
struct ResizeEvent
{
uint8_t type; /**< ET_VIDEORESIZE */
int w; /**< New width */
int h; /**< New height */
};
/** The "screen redraw" event */
struct ExposeEvent
{
uint8_t type; /**< ET_VIDEOEXPOSE */
};
/** The "quit requested" event */
struct QuitEvent
{
uint8_t type; /**< ET_QUIT */
};
/** A user-defined event type */
struct UserEvent
{
uint8_t type; /**< ETL_USEREVENT through ET_NUMEVENTS-1 */
int code; /**< User defined event code */
void *data1; /**< User defined data pointer */
void *data2; /**< User defined data pointer */
};
/** If you want to use this event, you should include SDL_syswm.h */
struct SysWMmsg;
struct SysWMEvent
{
uint8_t type;
SysWMmsg *msg;
};
/** General event structure */
union Event
{
uint8_t type;
ActiveEvent active;
KeyboardEvent key;
MouseMotionEvent motion;
MouseButtonEvent button;
JoyAxisEvent jaxis;
JoyBallEvent jball;
JoyHatEvent jhat;
JoyButtonEvent jbutton;
ResizeEvent resize;
ExposeEvent expose;
QuitEvent quit;
UserEvent user;
SysWMEvent syswm;
};
}

@ -1,61 +0,0 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2009 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
// Fake - only structs. Shamelessly pilfered from the SDL library.
// Needed for processing its event types without polluting our namespaces with C garbage
#pragma once
#include "SDL_keysym.h"
#include <stdint.h>
namespace SDL
{
/** Keysym structure
*
* - The scancode is hardware dependent, and should not be used by general
* applications. If no hardware scancode is available, it will be 0.
*
* - The 'unicode' translated character is only available when character
* translation is enabled by the SDL_EnableUNICODE() API. If non-zero,
* this is a UNICODE character corresponding to the keypress. If the
* high 9 bits of the character are 0, then this maps to the equivalent
* ASCII character:
* @code
* char ch;
* if ( (keysym.unicode & 0xFF80) == 0 ) {
* ch = keysym.unicode & 0x7F;
* } else {
* An international character..
* }
* @endcode
*/
typedef struct keysym
{
uint8_t scancode; /**< hardware specific scancode */
Key sym; /**< SDL virtual keysym */
Mod mod; /**< current key modifiers */
uint16_t unicode; /**< translated character */
} keysym;
/** This is the mask which refers to all hotkey bindings */
#define ALL_HOTKEYS 0xFFFFFFFF
}

@ -1,329 +0,0 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2009 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
// Fake - only structs. Shamelessly pilfered from the SDL library.
// Needed for processing its event types without polluting our namespaces with C garbage
#pragma once
namespace SDL
{
/** What we really want is a mapping of every raw key on the keyboard.
* To support international keyboards, we use the range 0xA1 - 0xFF
* as international virtual keycodes. We'll follow in the footsteps of X11...
* @brief The names of the keys
*/
enum Key
{
/** @name ASCII mapped keysyms
* The keyboard syms have been cleverly chosen to map to ASCII
*/
/*@{*/
K_UNKNOWN = 0,
K_FIRST = 0,
K_BACKSPACE = 8,
K_TAB = 9,
K_CLEAR = 12,
K_RETURN = 13,
K_PAUSE = 19,
K_ESCAPE = 27,
K_SPACE = 32,
K_EXCLAIM = 33,
K_QUOTEDBL = 34,
K_HASH = 35,
K_DOLLAR = 36,
K_AMPERSAND = 38,
K_QUOTE = 39,
K_LEFTPAREN = 40,
K_RIGHTPAREN = 41,
K_ASTERISK = 42,
K_PLUS = 43,
K_COMMA = 44,
K_MINUS = 45,
K_PERIOD = 46,
K_SLASH = 47,
K_0 = 48,
K_1 = 49,
K_2 = 50,
K_3 = 51,
K_4 = 52,
K_5 = 53,
K_6 = 54,
K_7 = 55,
K_8 = 56,
K_9 = 57,
K_COLON = 58,
K_SEMICOLON = 59,
K_LESS = 60,
K_EQUALS = 61,
K_GREATER = 62,
K_QUESTION = 63,
K_AT = 64,
/*
Skip uppercase letters
*/
K_LEFTBRACKET = 91,
K_BACKSLASH = 92,
K_RIGHTBRACKET = 93,
K_CARET = 94,
K_UNDERSCORE = 95,
K_BACKQUOTE = 96,
K_a = 97,
K_b = 98,
K_c = 99,
K_d = 100,
K_e = 101,
K_f = 102,
K_g = 103,
K_h = 104,
K_i = 105,
K_j = 106,
K_k = 107,
K_l = 108,
K_m = 109,
K_n = 110,
K_o = 111,
K_p = 112,
K_q = 113,
K_r = 114,
K_s = 115,
K_t = 116,
K_u = 117,
K_v = 118,
K_w = 119,
K_x = 120,
K_y = 121,
K_z = 122,
K_DELETE = 127,
/* End of ASCII mapped keysyms */
/*@}*/
/** @name International keyboard syms */
/*@{*/
K_WORLD_0 = 160, /* 0xA0 */
K_WORLD_1 = 161,
K_WORLD_2 = 162,
K_WORLD_3 = 163,
K_WORLD_4 = 164,
K_WORLD_5 = 165,
K_WORLD_6 = 166,
K_WORLD_7 = 167,
K_WORLD_8 = 168,
K_WORLD_9 = 169,
K_WORLD_10 = 170,
K_WORLD_11 = 171,
K_WORLD_12 = 172,
K_WORLD_13 = 173,
K_WORLD_14 = 174,
K_WORLD_15 = 175,
K_WORLD_16 = 176,
K_WORLD_17 = 177,
K_WORLD_18 = 178,
K_WORLD_19 = 179,
K_WORLD_20 = 180,
K_WORLD_21 = 181,
K_WORLD_22 = 182,
K_WORLD_23 = 183,
K_WORLD_24 = 184,
K_WORLD_25 = 185,
K_WORLD_26 = 186,
K_WORLD_27 = 187,
K_WORLD_28 = 188,
K_WORLD_29 = 189,
K_WORLD_30 = 190,
K_WORLD_31 = 191,
K_WORLD_32 = 192,
K_WORLD_33 = 193,
K_WORLD_34 = 194,
K_WORLD_35 = 195,
K_WORLD_36 = 196,
K_WORLD_37 = 197,
K_WORLD_38 = 198,
K_WORLD_39 = 199,
K_WORLD_40 = 200,
K_WORLD_41 = 201,
K_WORLD_42 = 202,
K_WORLD_43 = 203,
K_WORLD_44 = 204,
K_WORLD_45 = 205,
K_WORLD_46 = 206,
K_WORLD_47 = 207,
K_WORLD_48 = 208,
K_WORLD_49 = 209,
K_WORLD_50 = 210,
K_WORLD_51 = 211,
K_WORLD_52 = 212,
K_WORLD_53 = 213,
K_WORLD_54 = 214,
K_WORLD_55 = 215,
K_WORLD_56 = 216,
K_WORLD_57 = 217,
K_WORLD_58 = 218,
K_WORLD_59 = 219,
K_WORLD_60 = 220,
K_WORLD_61 = 221,
K_WORLD_62 = 222,
K_WORLD_63 = 223,
K_WORLD_64 = 224,
K_WORLD_65 = 225,
K_WORLD_66 = 226,
K_WORLD_67 = 227,
K_WORLD_68 = 228,
K_WORLD_69 = 229,
K_WORLD_70 = 230,
K_WORLD_71 = 231,
K_WORLD_72 = 232,
K_WORLD_73 = 233,
K_WORLD_74 = 234,
K_WORLD_75 = 235,
K_WORLD_76 = 236,
K_WORLD_77 = 237,
K_WORLD_78 = 238,
K_WORLD_79 = 239,
K_WORLD_80 = 240,
K_WORLD_81 = 241,
K_WORLD_82 = 242,
K_WORLD_83 = 243,
K_WORLD_84 = 244,
K_WORLD_85 = 245,
K_WORLD_86 = 246,
K_WORLD_87 = 247,
K_WORLD_88 = 248,
K_WORLD_89 = 249,
K_WORLD_90 = 250,
K_WORLD_91 = 251,
K_WORLD_92 = 252,
K_WORLD_93 = 253,
K_WORLD_94 = 254,
K_WORLD_95 = 255, /* 0xFF */
/*@}*/
/** @name Numeric keypad */
/*@{*/
K_KP0 = 256,
K_KP1 = 257,
K_KP2 = 258,
K_KP3 = 259,
K_KP4 = 260,
K_KP5 = 261,
K_KP6 = 262,
K_KP7 = 263,
K_KP8 = 264,
K_KP9 = 265,
K_KP_PERIOD = 266,
K_KP_DIVIDE = 267,
K_KP_MULTIPLY = 268,
K_KP_MINUS = 269,
K_KP_PLUS = 270,
K_KP_ENTER = 271,
K_KP_EQUALS = 272,
/*@}*/
/** @name Arrows + Home/End pad */
/*@{*/
K_UP = 273,
K_DOWN = 274,
K_RIGHT = 275,
K_LEFT = 276,
K_INSERT = 277,
K_HOME = 278,
K_END = 279,
K_PAGEUP = 280,
K_PAGEDOWN = 281,
/*@}*/
/** @name Function keys */
/*@{*/
K_F1 = 282,
K_F2 = 283,
K_F3 = 284,
K_F4 = 285,
K_F5 = 286,
K_F6 = 287,
K_F7 = 288,
K_F8 = 289,
K_F9 = 290,
K_F10 = 291,
K_F11 = 292,
K_F12 = 293,
K_F13 = 294,
K_F14 = 295,
K_F15 = 296,
/*@}*/
/** @name Key state modifier keys */
/*@{*/
K_NUMLOCK = 300,
K_CAPSLOCK = 301,
K_SCROLLOCK = 302,
K_RSHIFT = 303,
K_LSHIFT = 304,
K_RCTRL = 305,
K_LCTRL = 306,
K_RALT = 307,
K_LALT = 308,
K_RMETA = 309,
K_LMETA = 310,
K_LSUPER = 311, /**< Left "Windows" key */
K_RSUPER = 312, /**< Right "Windows" key */
K_MODE = 313, /**< "Alt Gr" key */
K_COMPOSE = 314, /**< Multi-key compose key */
/*@}*/
/** @name Miscellaneous function keys */
/*@{*/
K_HELP = 315,
K_PRINT = 316,
K_SYSREQ = 317,
K_BREAK = 318,
K_MENU = 319,
K_POWER = 320, /**< Power Macintosh power key */
K_EURO = 321, /**< Some european keyboards */
K_UNDO = 322, /**< Atari keyboard has Undo */
/*@}*/
/* Add any other keys here */
K_LAST
};
/** Enumeration of valid key mods (possibly OR'd together) */
enum Mod {
KMOD_NONE = 0x0000,
KMOD_LSHIFT= 0x0001,
KMOD_RSHIFT= 0x0002,
KMOD_LCTRL = 0x0040,
KMOD_RCTRL = 0x0080,
KMOD_LALT = 0x0100,
KMOD_RALT = 0x0200,
KMOD_LMETA = 0x0400,
KMOD_RMETA = 0x0800,
KMOD_NUM = 0x1000,
KMOD_CAPS = 0x2000,
KMOD_MODE = 0x4000,
KMOD_RESERVED = 0x8000,
KMOD_CTRL = (KMOD_LCTRL|KMOD_RCTRL),
KMOD_SHIFT = (KMOD_LSHIFT|KMOD_RSHIFT),
KMOD_ALT = (KMOD_LALT|KMOD_RALT),
KMOD_META = (KMOD_LMETA|KMOD_RMETA)
};
}

@ -1,6 +1,8 @@
void zoom_display(df::zoom_commands command) { void zoom_display(df::zoom_commands command) {
/*
DFHack::DFSDL::DFSDL_SemWait(async_zoom.sem); DFHack::DFSDL::DFSDL_SemWait(async_zoom.sem);
async_zoom.queue.push_back(command); async_zoom.queue.push_back(command);
DFHack::DFSDL::DFSDL_SemPost(async_zoom.sem); DFHack::DFSDL::DFSDL_SemPost(async_zoom.sem);
DFHack::DFSDL::DFSDL_SemPost(async_zoom.sem_fill); DFHack::DFSDL::DFSDL_SemPost(async_zoom.sem_fill);
*/
} }

@ -3,60 +3,19 @@
#include "Export.h" #include "Export.h"
#include "ColorText.h" #include "ColorText.h"
namespace DFHack struct SDL_Surface;
{ struct SDL_Rect;
// SDL stand-in type definitions struct SDL_PixelFormat;
typedef signed short SINT16; union SDL_Event;
typedef void DFSDL_sem;
typedef void DFSDL_Event;
typedef struct namespace DFHack
{
int16_t x, y;
uint16_t w, h;
} DFSDL_Rect;
typedef struct
{
void *palette; // SDL_Palette*
uint8_t BitsPerPixel;
uint8_t BytesPerPixel;
uint8_t Rloss;
uint8_t Gloss;
uint8_t Bloss;
uint8_t Aloss;
uint8_t Rshift;
uint8_t Gshift;
uint8_t Bshift;
uint8_t Ashift;
uint32_t Rmask;
uint32_t Gmask;
uint32_t Bmask;
uint32_t Amask;
uint32_t colorkey;
uint8_t alpha;
} DFSDL_PixelFormat;
typedef struct
{ {
uint32_t flags;
DFSDL_PixelFormat* format;
int w, h;
int pitch;
void* pixels;
void* userdata; // as far as i could see DF doesnt use this
int locked;
void* lock_data;
DFSDL_Rect clip_rect;
void* map;
int refcount;
} DFSDL_Surface;
// =========
struct DFTileSurface struct DFTileSurface
{ {
bool paintOver; // draw over original tile? bool paintOver; // draw over original tile?
DFSDL_Surface* surface; // from where it should be drawn SDL_Surface* surface; // from where it should be drawn
DFSDL_Rect* rect; // from which coords (NULL to draw whole surface) SDL_Rect* rect; // from which coords (NULL to draw whole surface)
DFSDL_Rect* dstResize; // if not NULL dst rect will be resized (x/y/w/h will be added to original dst) SDL_Rect* dstResize; // if not NULL dst rect will be resized (x/y/w/h will be added to original dst)
}; };
/** /**
@ -79,17 +38,15 @@ bool init(DFHack::color_ostream &out);
*/ */
void cleanup(); void cleanup();
DFHACK_EXPORT DFSDL_Surface * DFIMG_Load(const char *file); DFHACK_EXPORT SDL_Surface * DFIMG_Load(const char *file);
DFHACK_EXPORT int DFSDL_SetAlpha(DFSDL_Surface *surface, uint32_t flag, uint8_t alpha); DFHACK_EXPORT SDL_Surface * DFSDL_CreateRGBSurface(uint32_t flags, int width, int height, int depth, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask);
DFHACK_EXPORT DFSDL_Surface * DFSDL_GetVideoSurface(void); DFHACK_EXPORT SDL_Surface * DFSDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask);
DFHACK_EXPORT DFSDL_Surface * DFSDL_CreateRGBSurface(uint32_t flags, int width, int height, int depth, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask); DFHACK_EXPORT int DFSDL_UpperBlit(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect);
DFHACK_EXPORT DFSDL_Surface * DFSDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask); DFHACK_EXPORT SDL_Surface * DFSDL_ConvertSurface(SDL_Surface *src, const SDL_PixelFormat *fmt, uint32_t flags);
DFHACK_EXPORT int DFSDL_UpperBlit(DFSDL_Surface *src, const DFSDL_Rect *srcrect, DFSDL_Surface *dst, DFSDL_Rect *dstrect); DFHACK_EXPORT void DFSDL_FreeSurface(SDL_Surface *surface);
DFHACK_EXPORT DFSDL_Surface * DFSDL_ConvertSurface(DFSDL_Surface *src, const DFSDL_PixelFormat *fmt, uint32_t flags); // DFHACK_EXPORT int DFSDL_SemWait(SDL_sem *sem);
DFHACK_EXPORT void DFSDL_FreeSurface(DFSDL_Surface *surface); // DFHACK_EXPORT int DFSDL_SemPost(SDL_sem *sem);
DFHACK_EXPORT int DFSDL_SemWait(DFSDL_sem *sem); DFHACK_EXPORT int DFSDL_PushEvent(SDL_Event *event);
DFHACK_EXPORT int DFSDL_SemPost(DFSDL_sem *sem);
DFHACK_EXPORT int DFSDL_PushEvent(DFSDL_Event *event);
} }

@ -33,6 +33,7 @@ distribution.
#include "MemAccess.h" #include "MemAccess.h"
#include "DataDefs.h" #include "DataDefs.h"
#include "df/building_tradedepotst.h"
#include "df/item.h" #include "df/item.h"
#include "df/item_type.h" #include "df/item_type.h"
#include "df/general_ref.h" #include "df/general_ref.h"
@ -199,6 +200,8 @@ DFHACK_EXPORT bool checkMandates(df::item *item);
DFHACK_EXPORT bool canTrade(df::item *item); DFHACK_EXPORT bool canTrade(df::item *item);
/// Checks whether the item and all items it contains, if any, can be traded /// Checks whether the item and all items it contains, if any, can be traded
DFHACK_EXPORT bool canTradeWithContents(df::item *item); DFHACK_EXPORT bool canTradeWithContents(df::item *item);
/// marks the given item for trade at the given depot
DFHACK_EXPORT bool markForTrade(df::item *item, df::building_tradedepotst *depot);
/// Checks whether the item is an assigned hauling vehicle /// Checks whether the item is an assigned hauling vehicle
DFHACK_EXPORT bool isRouteVehicle(df::item *item); DFHACK_EXPORT bool isRouteVehicle(df::item *item);

@ -191,7 +191,7 @@ namespace DFHack
} }
/// Wrapper to call enabler->zoom_display from plugins /// Wrapper to call enabler->zoom_display from plugins
DFHACK_EXPORT void zoom(df::zoom_commands cmd); //DFHACK_EXPORT void zoom(df::zoom_commands cmd);
/// Returns the state of [GRAPHICS:YES/NO] /// Returns the state of [GRAPHICS:YES/NO]
DFHACK_EXPORT bool inGraphicsMode(); DFHACK_EXPORT bool inGraphicsMode();
@ -229,6 +229,9 @@ namespace DFHack
DFHACK_EXPORT bool hasActiveScreens(Plugin *p); DFHACK_EXPORT bool hasActiveScreens(Plugin *p);
DFHACK_EXPORT void raise(df::viewscreen *screen); DFHACK_EXPORT void raise(df::viewscreen *screen);
// returns a new set with text interface keys from the text buffer added in (if any)
DFHACK_EXPORT std::set<df::interface_key> add_text_keys(const std::set<df::interface_key>& keys);
/// Retrieve the string representation of the bound key. /// Retrieve the string representation of the bound key.
DFHACK_EXPORT std::string getKeyDisplay(df::interface_key key); DFHACK_EXPORT std::string getKeyDisplay(df::interface_key key);

@ -46,6 +46,16 @@ DFHACK_EXPORT long getIconsTexposStart();
*/ */
DFHACK_EXPORT long getOnOffTexposStart(); DFHACK_EXPORT long getOnOffTexposStart();
/**
* Get the first texpos for the pathable 32x32 sprites. It's a 2x1 grid.
*/
DFHACK_EXPORT long getMapPathableTexposStart();
/**
* Get the first texpos for the unsuspend 32x32 sprites. It's a 4x1 grid.
*/
DFHACK_EXPORT long getMapUnsuspendTexposStart();
/** /**
* Get the first texpos for the control panel icons. 10x2 grid. * Get the first texpos for the control panel icons. 10x2 grid.
*/ */

@ -1552,8 +1552,7 @@ function CycleHotkeyLabel:setOption(value_or_index, call_on_change)
end end
end end
if not option_idx then if not option_idx then
error(('cannot find option with value or index: "%s"') option_idx = 1
:format(value_or_index))
end end
local old_option_idx = self.option_idx local old_option_idx = self.option_idx
self.option_idx = option_idx self.option_idx = option_idx
@ -2392,9 +2391,15 @@ local function rangeslider_do_drag(self, width_per_idx)
end end
end end
if new_left_idx and new_left_idx ~= self.get_left_idx_fn() then if new_left_idx and new_left_idx ~= self.get_left_idx_fn() then
if not new_right_idx and new_left_idx > self.get_right_idx_fn() then
self.on_right_change(new_left_idx)
end
self.on_left_change(new_left_idx) self.on_left_change(new_left_idx)
end end
if new_right_idx and new_right_idx ~= self.get_right_idx_fn() then if new_right_idx and new_right_idx ~= self.get_right_idx_fn() then
if new_right_idx < self.get_left_idx_fn() then
self.on_left_change(new_right_idx)
end
self.on_right_change(new_right_idx) self.on_right_change(new_right_idx)
end end
end end

@ -14,29 +14,27 @@ using namespace DFHack;
static DFLibrary *g_sdl_handle = nullptr; static DFLibrary *g_sdl_handle = nullptr;
static DFLibrary *g_sdl_image_handle = nullptr; static DFLibrary *g_sdl_image_handle = nullptr;
static const std::vector<std::string> SDL_LIBS { static const std::vector<std::string> SDL_LIBS {
"SDL.dll", "SDL2.dll",
"SDL.framework/Versions/A/SDL", "SDL.framework/Versions/A/SDL",
"SDL.framework/SDL", "SDL.framework/SDL",
"libSDL-1.2.so.0" "libSDL2-2.0.so.0"
}; };
static const std::vector<std::string> SDL_IMAGE_LIBS { static const std::vector<std::string> SDL_IMAGE_LIBS {
"SDL_image.dll", "SDL2_image.dll",
"SDL_image.framework/Versions/A/SDL_image", "SDL_image.framework/Versions/A/SDL_image",
"SDL_image.framework/SDL_image", "SDL_image.framework/SDL_image",
"libSDL_image-1.2.so.0" "libSDL2_image-2.0.so.0"
}; };
DFSDL_Surface * (*g_IMG_Load)(const char *) = nullptr; SDL_Surface * (*g_IMG_Load)(const char *) = nullptr;
int (*g_SDL_SetAlpha)(DFSDL_Surface *, uint32_t, uint8_t) = nullptr; SDL_Surface * (*g_SDL_CreateRGBSurface)(uint32_t, int, int, int, uint32_t, uint32_t, uint32_t, uint32_t) = nullptr;
DFSDL_Surface * (*g_SDL_GetVideoSurface)(void) = nullptr; SDL_Surface * (*g_SDL_CreateRGBSurfaceFrom)(void *pixels, int width, int height, int depth, int pitch, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask) = nullptr;
DFSDL_Surface * (*g_SDL_CreateRGBSurface)(uint32_t, int, int, int, uint32_t, uint32_t, uint32_t, uint32_t) = nullptr; int (*g_SDL_UpperBlit)(SDL_Surface *, const SDL_Rect *, SDL_Surface *, SDL_Rect *) = nullptr;
DFSDL_Surface * (*g_SDL_CreateRGBSurfaceFrom)(void *pixels, int width, int height, int depth, int pitch, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask) = nullptr; SDL_Surface * (*g_SDL_ConvertSurface)(SDL_Surface *, const SDL_PixelFormat *, uint32_t) = nullptr;
int (*g_SDL_UpperBlit)(DFSDL_Surface *, const DFSDL_Rect *, DFSDL_Surface *, DFSDL_Rect *) = nullptr; void (*g_SDL_FreeSurface)(SDL_Surface *) = nullptr;
DFSDL_Surface * (*g_SDL_ConvertSurface)(DFSDL_Surface *, const DFSDL_PixelFormat *, uint32_t) = nullptr; // int (*g_SDL_SemWait)(DFSDL_sem *) = nullptr;
void (*g_SDL_FreeSurface)(DFSDL_Surface *) = nullptr; // int (*g_SDL_SemPost)(DFSDL_sem *) = nullptr;
int (*g_SDL_SemWait)(DFSDL_sem *) = nullptr; int (*g_SDL_PushEvent)(SDL_Event *) = nullptr;
int (*g_SDL_SemPost)(DFSDL_sem *) = nullptr;
int (*g_SDL_PushEvent)(DFSDL_Event *) = nullptr;
bool DFSDL::init(color_ostream &out) { bool DFSDL::init(color_ostream &out) {
for (auto &lib_str : SDL_LIBS) { for (auto &lib_str : SDL_LIBS) {
@ -65,15 +63,13 @@ bool DFSDL::init(color_ostream &out) {
} }
bind(g_sdl_image_handle, IMG_Load); bind(g_sdl_image_handle, IMG_Load);
bind(g_sdl_handle, SDL_SetAlpha);
bind(g_sdl_handle, SDL_GetVideoSurface);
bind(g_sdl_handle, SDL_CreateRGBSurface); bind(g_sdl_handle, SDL_CreateRGBSurface);
bind(g_sdl_handle, SDL_CreateRGBSurfaceFrom); bind(g_sdl_handle, SDL_CreateRGBSurfaceFrom);
bind(g_sdl_handle, SDL_UpperBlit); bind(g_sdl_handle, SDL_UpperBlit);
bind(g_sdl_handle, SDL_ConvertSurface); bind(g_sdl_handle, SDL_ConvertSurface);
bind(g_sdl_handle, SDL_FreeSurface); bind(g_sdl_handle, SDL_FreeSurface);
bind(g_sdl_handle, SDL_SemWait); // bind(g_sdl_handle, SDL_SemWait);
bind(g_sdl_handle, SDL_SemPost); // bind(g_sdl_handle, SDL_SemPost);
bind(g_sdl_handle, SDL_PushEvent); bind(g_sdl_handle, SDL_PushEvent);
#undef bind #undef bind
@ -93,46 +89,38 @@ void DFSDL::cleanup() {
} }
} }
DFSDL_Surface * DFSDL::DFIMG_Load(const char *file) { SDL_Surface * DFSDL::DFIMG_Load(const char *file) {
return g_IMG_Load(file); return g_IMG_Load(file);
} }
int DFSDL::DFSDL_SetAlpha(DFSDL_Surface *surface, uint32_t flag, uint8_t alpha) { SDL_Surface * DFSDL::DFSDL_CreateRGBSurface(uint32_t flags, int width, int height, int depth, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask) {
return g_SDL_SetAlpha(surface, flag, alpha);
}
DFSDL_Surface * DFSDL::DFSDL_GetVideoSurface(void) {
return g_SDL_GetVideoSurface();
}
DFSDL_Surface * DFSDL::DFSDL_CreateRGBSurface(uint32_t flags, int width, int height, int depth, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask) {
return g_SDL_CreateRGBSurface(flags, width, height, depth, Rmask, Gmask, Bmask, Amask); return g_SDL_CreateRGBSurface(flags, width, height, depth, Rmask, Gmask, Bmask, Amask);
} }
DFSDL_Surface * DFSDL::DFSDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask) { SDL_Surface * DFSDL::DFSDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask) {
return g_SDL_CreateRGBSurfaceFrom(pixels, width, height, depth, pitch, Rmask, Gmask, Bmask, Amask); return g_SDL_CreateRGBSurfaceFrom(pixels, width, height, depth, pitch, Rmask, Gmask, Bmask, Amask);
} }
int DFSDL::DFSDL_UpperBlit(DFSDL_Surface *src, const DFSDL_Rect *srcrect, DFSDL_Surface *dst, DFSDL_Rect *dstrect) { int DFSDL::DFSDL_UpperBlit(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect) {
return g_SDL_UpperBlit(src, srcrect, dst, dstrect); return g_SDL_UpperBlit(src, srcrect, dst, dstrect);
} }
DFSDL_Surface * DFSDL::DFSDL_ConvertSurface(DFSDL_Surface *src, const DFSDL_PixelFormat *fmt, uint32_t flags) { SDL_Surface * DFSDL::DFSDL_ConvertSurface(SDL_Surface *src, const SDL_PixelFormat *fmt, uint32_t flags) {
return g_SDL_ConvertSurface(src, fmt, flags); return g_SDL_ConvertSurface(src, fmt, flags);
} }
void DFSDL::DFSDL_FreeSurface(DFSDL_Surface *surface) { void DFSDL::DFSDL_FreeSurface(SDL_Surface *surface) {
g_SDL_FreeSurface(surface); g_SDL_FreeSurface(surface);
} }
int DFSDL::DFSDL_SemWait(DFSDL_sem *sem) { // int DFSDL::DFSDL_SemWait(DFSDL_sem *sem) {
return g_SDL_SemWait(sem); // return g_SDL_SemWait(sem);
} // }
int DFSDL::DFSDL_SemPost(DFSDL_sem *sem) { // int DFSDL::DFSDL_SemPost(DFSDL_sem *sem) {
return g_SDL_SemPost(sem); // return g_SDL_SemPost(sem);
} // }
int DFSDL::DFSDL_PushEvent(DFSDL_Event *event) { int DFSDL::DFSDL_PushEvent(SDL_Event *event) {
return g_SDL_PushEvent(event); return g_SDL_PushEvent(event);
} }

@ -200,6 +200,12 @@ DEFINE_GET_FOCUS_STRING_HANDLER(dwarfmode)
case df::enums::info_interface_mode_type::JUSTICE: case df::enums::info_interface_mode_type::JUSTICE:
newFocusString += '/' + enum_item_key(game->main_interface.info.justice.current_mode); newFocusString += '/' + enum_item_key(game->main_interface.info.justice.current_mode);
break; break;
case df::enums::info_interface_mode_type::WORK_ORDERS:
if (game->main_interface.info.work_orders.conditions.open)
newFocusString += "/Conditions";
else
newFocusString += "/Default";
break;
default: default:
break; break;
} }
@ -210,6 +216,11 @@ DEFINE_GET_FOCUS_STRING_HANDLER(dwarfmode)
newFocusString = baseFocus; newFocusString = baseFocus;
newFocusString += "/ViewSheets"; newFocusString += "/ViewSheets";
newFocusString += '/' + enum_item_key(game->main_interface.view_sheets.active_sheet); newFocusString += '/' + enum_item_key(game->main_interface.view_sheets.active_sheet);
if (game->main_interface.view_sheets.active_sheet == df::view_sheet_type::BUILDING) {
auto bld = df::building::find(game->main_interface.view_sheets.viewing_bldid);
if (bld)
newFocusString += '/' + enum_item_key(bld->getType());
}
focusStrings.push_back(newFocusString); focusStrings.push_back(newFocusString);
} }
@ -322,6 +333,10 @@ DEFINE_GET_FOCUS_STRING_HANDLER(dwarfmode)
if (game->main_interface.trade.open) { if (game->main_interface.trade.open) {
newFocusString = baseFocus; newFocusString = baseFocus;
newFocusString += "/Trade"; newFocusString += "/Trade";
if (game->main_interface.trade.choosing_merchant)
newFocusString += "/ChoosingMerchant";
else
newFocusString += "/Default";
focusStrings.push_back(newFocusString); focusStrings.push_back(newFocusString);
} }
if (game->main_interface.job_details.open) { if (game->main_interface.job_details.open) {
@ -337,6 +352,10 @@ DEFINE_GET_FOCUS_STRING_HANDLER(dwarfmode)
if (game->main_interface.diplomacy.open) { if (game->main_interface.diplomacy.open) {
newFocusString = baseFocus; newFocusString = baseFocus;
newFocusString += "/Diplomacy"; newFocusString += "/Diplomacy";
if (game->main_interface.diplomacy.taking_requests)
newFocusString += "/Requests";
else
newFocusString += "/Default";
focusStrings.push_back(newFocusString); focusStrings.push_back(newFocusString);
} }
if (game->main_interface.petitions.open) { if (game->main_interface.petitions.open) {
@ -367,6 +386,7 @@ DEFINE_GET_FOCUS_STRING_HANDLER(dwarfmode)
if (game->main_interface.unit_selector.open) { if (game->main_interface.unit_selector.open) {
newFocusString = baseFocus; newFocusString = baseFocus;
newFocusString += "/UnitSelector"; newFocusString += "/UnitSelector";
newFocusString += '/' + enum_item_key(game->main_interface.unit_selector.context);
focusStrings.push_back(newFocusString); focusStrings.push_back(newFocusString);
} }
if (game->main_interface.announcement_alert.open) { if (game->main_interface.announcement_alert.open) {

@ -39,6 +39,7 @@ distribution.
using namespace std; using namespace std;
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include "modules/Job.h"
#include "modules/MapCache.h" #include "modules/MapCache.h"
#include "modules/Materials.h" #include "modules/Materials.h"
#include "modules/Items.h" #include "modules/Items.h"
@ -48,6 +49,7 @@ using namespace std;
#include "df/body_part_template_flags.h" #include "df/body_part_template_flags.h"
#include "df/building.h" #include "df/building.h"
#include "df/building_actual.h" #include "df/building_actual.h"
#include "df/building_tradedepotst.h"
#include "df/caste_raw.h" #include "df/caste_raw.h"
#include "df/creature_raw.h" #include "df/creature_raw.h"
#include "df/general_ref.h" #include "df/general_ref.h"
@ -1637,6 +1639,42 @@ bool Items::canTradeWithContents(df::item *item)
return true; return true;
} }
bool Items::markForTrade(df::item *item, df::building_tradedepotst *depot) {
CHECK_NULL_POINTER(item);
CHECK_NULL_POINTER(depot);
// validate that the depot is in a good state
if (depot->getBuildStage() < depot->getMaxBuildStage())
return false;
if (depot->jobs.size() && depot->jobs[0]->job_type == df::job_type::DestroyBuilding)
return false;
auto href = df::allocate<df::general_ref_building_holderst>();
if (!href)
return false;
auto job = new df::job();
job->job_type = df::job_type::BringItemToDepot;
job->pos = df::coord(depot->centerx, depot->centery, depot->z);
// job <-> item link
if (!Job::attachJobItem(job, item, df::job_item_ref::Hauled)) {
delete job;
delete href;
return false;
}
// job <-> building link
href->building_id = depot->id;
depot->jobs.push_back(job);
job->general_refs.push_back(href);
// add to job list
Job::linkIntoWorld(job);
return true;
}
bool Items::isRouteVehicle(df::item *item) bool Items::isRouteVehicle(df::item *item)
{ {
CHECK_NULL_POINTER(item); CHECK_NULL_POINTER(item);

@ -78,7 +78,6 @@ namespace DFHack {
DBG_DECLARE(core, screen, DebugCategory::LINFO); DBG_DECLARE(core, screen, DebugCategory::LINFO);
} }
/* /*
* Screen painting API. * Screen painting API.
*/ */
@ -106,9 +105,11 @@ df::coord2d Screen::getWindowSize()
return df::coord2d(gps->dimx, gps->dimy); return df::coord2d(gps->dimx, gps->dimy);
} }
/*
void Screen::zoom(df::zoom_commands cmd) { void Screen::zoom(df::zoom_commands cmd) {
enabler->zoom_display(cmd); enabler->zoom_display(cmd);
} }
*/
bool Screen::inGraphicsMode() bool Screen::inGraphicsMode()
{ {
@ -584,12 +585,25 @@ void Hide::merge() {
} }
} } } }
std::set<df::interface_key> Screen::add_text_keys(const std::set<df::interface_key>& keys) {
std::set<df::interface_key> combined_keys(keys);
if (df::global::enabler->last_text_input[0]) {
char c = df::global::enabler->last_text_input[0];
df::interface_key key = charToKey(c);
DEBUG(screen).print("adding character %c as interface key %ld\n", c, key);
combined_keys.emplace(key);
}
return combined_keys;
}
string Screen::getKeyDisplay(df::interface_key key) string Screen::getKeyDisplay(df::interface_key key)
{ {
if (enabler) int c = keyToChar(key);
if (c != -1)
return string(1, c);
if (key >= df::interface_key::CUSTOM_SHIFT_A && key <= df::interface_key::CUSTOM_SHIFT_Z)
return string(1, 'A' + (key - df::interface_key::CUSTOM_SHIFT_A));
return enabler->GetKeyDisplay(key); return enabler->GetKeyDisplay(key);
return "?";
} }
int Screen::keyToChar(df::interface_key key) int Screen::keyToChar(df::interface_key key)
@ -938,7 +952,7 @@ int dfhack_lua_viewscreen::do_input(lua_State *L)
} }
lua_pushvalue(L, -2); lua_pushvalue(L, -2);
Lua::PushInterfaceKeys(L, *keys); Lua::PushInterfaceKeys(L, Screen::add_text_keys(*keys));
lua_call(L, 2, 0); lua_call(L, 2, 0);
self->update_focus(L, -1); self->update_focus(L, -1);
@ -1021,6 +1035,7 @@ void dfhack_lua_viewscreen::feed(std::set<df::interface_key> *keys)
lua_pushlightuserdata(Lua::Core::State, keys); lua_pushlightuserdata(Lua::Core::State, keys);
safe_call_lua(do_input, 1, 0); safe_call_lua(do_input, 1, 0);
df::global::enabler->last_text_input[0] = '\0';
} }
void dfhack_lua_viewscreen::onShow() void dfhack_lua_viewscreen::onShow()

@ -8,6 +8,8 @@
#include "df/enabler.h" #include "df/enabler.h"
#include <SDL_surface.h>
using df::global::enabler; using df::global::enabler;
using namespace DFHack; using namespace DFHack;
using namespace DFHack::DFSDL; using namespace DFHack::DFSDL;
@ -23,6 +25,8 @@ static long g_green_pin_texpos_start = -1;
static long g_red_pin_texpos_start = -1; static long g_red_pin_texpos_start = -1;
static long g_icons_texpos_start = -1; static long g_icons_texpos_start = -1;
static long g_on_off_texpos_start = -1; static long g_on_off_texpos_start = -1;
static long g_pathable_texpos_start = -1;
static long g_unsuspend_texpos_start = -1;
static long g_control_panel_texpos_start = -1; static long g_control_panel_texpos_start = -1;
static long g_thin_borders_texpos_start = -1; static long g_thin_borders_texpos_start = -1;
static long g_medium_borders_texpos_start = -1; static long g_medium_borders_texpos_start = -1;
@ -37,26 +41,34 @@ static long g_window_borders_texpos_start = -1;
// //
// It uses the same pixel format (RGBA, R at lowest address) regardless of // It uses the same pixel format (RGBA, R at lowest address) regardless of
// hardware. // hardware.
DFSDL_Surface * canonicalize_format(DFSDL_Surface *src) { SDL_Surface * canonicalize_format(SDL_Surface *src) {
DFSDL_PixelFormat fmt; SDL_PixelFormat fmt;
fmt.palette = NULL; fmt.palette = NULL;
fmt.BitsPerPixel = 32; fmt.BitsPerPixel = 32;
fmt.BytesPerPixel = 4; fmt.BytesPerPixel = 4;
fmt.Rloss = fmt.Gloss = fmt.Bloss = fmt.Aloss = 0; fmt.Rloss = fmt.Gloss = fmt.Bloss = fmt.Aloss = 0;
//#if SDL_BYTEORDER == SDL_BIG_ENDIAN #if SDL_BYTEORDER == SDL_BIG_ENDIAN
// fmt.Rshift = 24; fmt.Gshift = 16; fmt.Bshift = 8; fmt.Ashift = 0; fmt.Rshift = 24; fmt.Gshift = 16; fmt.Bshift = 8; fmt.Ashift = 0;
//#else #else
fmt.Rshift = 0; fmt.Gshift = 8; fmt.Bshift = 16; fmt.Ashift = 24; fmt.Rshift = 0; fmt.Gshift = 8; fmt.Bshift = 16; fmt.Ashift = 24;
//#endif #endif
fmt.Rmask = 255 << fmt.Rshift; fmt.Rmask = 255 << fmt.Rshift;
fmt.Gmask = 255 << fmt.Gshift; fmt.Gmask = 255 << fmt.Gshift;
fmt.Bmask = 255 << fmt.Bshift; fmt.Bmask = 255 << fmt.Bshift;
fmt.Amask = 255 << fmt.Ashift; fmt.Amask = 255 << fmt.Ashift;
fmt.colorkey = 0;
fmt.alpha = 255;
DFSDL_Surface *tgt = DFSDL_ConvertSurface(src, &fmt, 0); // SDL_SWSURFACE SDL_Surface *tgt = DFSDL_ConvertSurface(src, &fmt, SDL_SWSURFACE);
DFSDL_FreeSurface(src); DFSDL_FreeSurface(src);
for (int x = 0; x < tgt->w; ++x) {
for (int y = 0; y < tgt->h; ++y) {
Uint8* p = (Uint8*)tgt->pixels + y * tgt->pitch + x * 4;
if (p[3] == 0) {
for (int c = 0; c < 3; c++) {
p[c] = 0;
}
}
}
}
return tgt; return tgt;
} }
@ -64,30 +76,30 @@ const uint32_t TILE_WIDTH_PX = 8;
const uint32_t TILE_HEIGHT_PX = 12; const uint32_t TILE_HEIGHT_PX = 12;
static size_t load_textures(color_ostream & out, const char * fname, static size_t load_textures(color_ostream & out, const char * fname,
long *texpos_start) { long *texpos_start,
DFSDL_Surface *s = DFIMG_Load(fname); int tile_w = TILE_WIDTH_PX,
int tile_h = TILE_HEIGHT_PX) {
SDL_Surface *s = DFIMG_Load(fname);
if (!s) { if (!s) {
out.printerr("unable to load textures from '%s'\n", fname); out.printerr("unable to load textures from '%s'\n", fname);
return 0; return 0;
} }
s = canonicalize_format(s); s = canonicalize_format(s);
DFSDL_SetAlpha(s, 0, 255); int dimx = s->w / tile_w;
int dimx = s->w / TILE_WIDTH_PX; int dimy = s->h / tile_h;
int dimy = s->h / TILE_HEIGHT_PX;
long count = 0; long count = 0;
for (int y = 0; y < dimy; y++) { for (int y = 0; y < dimy; y++) {
for (int x = 0; x < dimx; x++) { for (int x = 0; x < dimx; x++) {
DFSDL_Surface *tile = DFSDL_CreateRGBSurface(0, // SDL_SWSURFACE SDL_Surface *tile = DFSDL_CreateRGBSurface(0, // SDL_SWSURFACE
TILE_WIDTH_PX, TILE_HEIGHT_PX, 32, tile_w, tile_h, 32,
s->format->Rmask, s->format->Gmask, s->format->Bmask, s->format->Rmask, s->format->Gmask, s->format->Bmask,
s->format->Amask); s->format->Amask);
DFSDL_SetAlpha(tile, 0,255); SDL_Rect vp;
DFSDL_Rect vp; vp.x = tile_w * x;
vp.x = TILE_WIDTH_PX * x; vp.y = tile_h * y;
vp.y = TILE_HEIGHT_PX * y; vp.w = tile_w;
vp.w = TILE_WIDTH_PX; vp.h = tile_h;
vp.h = TILE_HEIGHT_PX;
DFSDL_UpperBlit(s, &vp, tile, NULL); DFSDL_UpperBlit(s, &vp, tile, NULL);
if (!count++) if (!count++)
*texpos_start = enabler->textures.raws.size(); *texpos_start = enabler->textures.raws.size();
@ -129,6 +141,10 @@ void Textures::init(color_ostream &out) {
&g_icons_texpos_start); &g_icons_texpos_start);
g_num_dfhack_textures += load_textures(out, "hack/data/art/on-off.png", g_num_dfhack_textures += load_textures(out, "hack/data/art/on-off.png",
&g_on_off_texpos_start); &g_on_off_texpos_start);
g_num_dfhack_textures += load_textures(out, "hack/data/art/pathable.png",
&g_pathable_texpos_start, 32, 32);
g_num_dfhack_textures += load_textures(out, "hack/data/art/unsuspend.png",
&g_unsuspend_texpos_start, 32, 32);
g_num_dfhack_textures += load_textures(out, "hack/data/art/control-panel.png", g_num_dfhack_textures += load_textures(out, "hack/data/art/control-panel.png",
&g_control_panel_texpos_start); &g_control_panel_texpos_start);
g_num_dfhack_textures += load_textures(out, "hack/data/art/border-thin.png", g_num_dfhack_textures += load_textures(out, "hack/data/art/border-thin.png",
@ -161,7 +177,7 @@ void Textures::cleanup() {
auto &raws = textures.raws; auto &raws = textures.raws;
size_t texpos_end = g_dfhack_logo_texpos_start + g_num_dfhack_textures; size_t texpos_end = g_dfhack_logo_texpos_start + g_num_dfhack_textures;
for (size_t idx = g_dfhack_logo_texpos_start; idx <= texpos_end; ++idx) { for (size_t idx = g_dfhack_logo_texpos_start; idx <= texpos_end; ++idx) {
DFSDL_FreeSurface((DFSDL_Surface *)raws[idx]); DFSDL_FreeSurface((SDL_Surface *)raws[idx]);
raws[idx] = NULL; raws[idx] = NULL;
} }
@ -193,6 +209,14 @@ long Textures::getOnOffTexposStart() {
return g_on_off_texpos_start; return g_on_off_texpos_start;
} }
long Textures::getMapPathableTexposStart() {
return g_pathable_texpos_start;
}
long Textures::getMapUnsuspendTexposStart() {
return g_unsuspend_texpos_start;
}
long Textures::getControlPanelTexposStart() { long Textures::getControlPanelTexposStart() {
return g_control_panel_texpos_start; return g_control_panel_texpos_start;
} }

@ -1 +1 @@
Subproject commit 6c722a0f745f8953fa24fe3177ca72146b3a5f42 Subproject commit 5da8a785cf176f831a56f934ec8ec6069a965ecf

@ -388,21 +388,37 @@ struct dug_tile_info {
df::tiletype tt = map.tiletypeAt(pos); df::tiletype tt = map.tiletypeAt(pos);
tmat = tileMaterial(tt); tmat = tileMaterial(tt);
itype = df::item_type::BOULDER;
imat = -1;
df::tiletype_shape shape = tileShape(tt);
if (shape == df::tiletype_shape::WALL || shape == df::tiletype_shape::FORTIFICATION) {
switch (tmat) {
case df::tiletype_material::STONE:
case df::tiletype_material::MINERAL:
case df::tiletype_material::FEATURE:
imat = map.baseMaterialAt(pos).mat_index;
break;
case df::tiletype_material::LAVA_STONE:
{
MaterialInfo mi;
if (mi.findInorganic("OBSIDIAN"))
imat = mi.index;
return; // itype should always be BOULDER, regardless of vein
}
default:
break;
}
}
switch (map.BlockAtTile(pos)->veinTypeAt(pos)) { switch (map.BlockAtTile(pos)->veinTypeAt(pos)) {
case df::inclusion_type::CLUSTER_ONE: case df::inclusion_type::CLUSTER_ONE:
case df::inclusion_type::CLUSTER_SMALL: case df::inclusion_type::CLUSTER_SMALL:
itype = df::item_type::ROUGH; itype = df::item_type::ROUGH;
break; break;
default: default:
itype = df::item_type::BOULDER; break;
} }
imat = -1;
if (tileShape(tt) == df::tiletype_shape::WALL
&& (tmat == df::tiletype_material::STONE
|| tmat == df::tiletype_material::MINERAL
|| tmat == df::tiletype_material::FEATURE))
imat = map.baseMaterialAt(pos).mat_index;
} }
}; };
@ -415,7 +431,6 @@ static bool is_diggable(MapExtras::MapCache &map, const DFCoord &pos,
case df::tiletype_material::RIVER: case df::tiletype_material::RIVER:
case df::tiletype_material::TREE: case df::tiletype_material::TREE:
case df::tiletype_material::ROOT: case df::tiletype_material::ROOT:
case df::tiletype_material::LAVA_STONE:
case df::tiletype_material::MAGMA: case df::tiletype_material::MAGMA:
case df::tiletype_material::HFS: case df::tiletype_material::HFS:
case df::tiletype_material::UNDERWORLD_GATE: case df::tiletype_material::UNDERWORLD_GATE:
@ -444,15 +459,6 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map,
return false; return false;
} }
/** The algorithm process seems to be:
* for each tile
* check for a designation
* if a designation exists send it to dig_tile
*
* dig_tile (below) then digs the layer below the channel designated tile
* thereby changing it and causing its designation to be lost
* */
df::tiletype target_type = df::tiletype::Void; df::tiletype target_type = df::tiletype::Void;
switch(designation) { switch(designation) {
case df::tile_dig_designation::Default: case df::tile_dig_designation::Default:

@ -323,31 +323,7 @@ public:
bool designate(color_ostream& out, df::item* item) override { bool designate(color_ostream& out, df::item* item) override {
if (!depot) if (!depot)
return false; return false;
return Items::markForTrade(item, depot);
auto href = df::allocate<df::general_ref_building_holderst>();
if (!href)
return false;
auto job = new df::job();
job->job_type = df::job_type::BringItemToDepot;
job->pos = df::coord(depot->centerx, depot->centery, depot->z);
// job <-> item link
if (!Job::attachJobItem(job, item, df::job_item_ref::Hauled)) {
delete job;
delete href;
return false;
}
// job <-> building link
href->building_id = depot->id;
depot->jobs.push_back(job);
job->general_refs.push_back(href);
// add to job list
Job::linkIntoWorld(job);
return true;
} }
private: private:

@ -66,7 +66,7 @@ OrdersOverlay = defclass(OrdersOverlay, overlay.OverlayWidget)
OrdersOverlay.ATTRS{ OrdersOverlay.ATTRS{
default_pos={x=53,y=-6}, default_pos={x=53,y=-6},
default_enabled=true, default_enabled=true,
viewscreens='dwarfmode/Info/WORK_ORDERS', viewscreens='dwarfmode/Info/WORK_ORDERS/Default',
frame={w=30, h=4}, frame={w=30, h=4},
} }
@ -142,6 +142,7 @@ function OrdersOverlay:init()
end end
function OrdersOverlay:onInput(keys) function OrdersOverlay:onInput(keys)
if df.global.game.main_interface.job_details.open then return end
if keys.CUSTOM_ALT_M then if keys.CUSTOM_ALT_M then
self.minimized = not self.minimized self.minimized = not self.minimized
return true return true
@ -151,6 +152,11 @@ function OrdersOverlay:onInput(keys)
end end
end end
function OrdersOverlay:render(dc)
if df.global.game.main_interface.job_details.open then return end
OrdersOverlay.super.render(self, dc)
end
OVERLAY_WIDGETS = { OVERLAY_WIDGETS = {
overlay=OrdersOverlay, overlay=OrdersOverlay,
} }

@ -597,6 +597,10 @@ function TitleVersionOverlay:init()
table.insert(text, {text='Pre-release build', pen=COLOR_LIGHTRED}) table.insert(text, {text='Pre-release build', pen=COLOR_LIGHTRED})
end end
for _,t in ipairs(text) do
self.frame.w = math.max(self.frame.w, #t)
end
self:addviews{ self:addviews{
widgets.Label{ widgets.Label{
frame={t=0, l=0}, frame={t=0, l=0},

@ -76,7 +76,7 @@ struct viewscreen_overlay : T {
[&](lua_State *L) { [&](lua_State *L) {
Lua::Push(L, T::_identity.getName()); Lua::Push(L, T::_identity.getName());
Lua::Push(L, this); Lua::Push(L, this);
Lua::PushInterfaceKeys(L, *input); Lua::PushInterfaceKeys(L, Screen::add_text_keys(*input));
}, [&](lua_State *L) { }, [&](lua_State *L) {
input_is_handled = lua_toboolean(L, -1); input_is_handled = lua_toboolean(L, -1);
}); });

@ -41,7 +41,7 @@ static void paintScreen(df::coord target, bool skip_unrevealed = false) {
long pathable_tile_texpos = df::global::init->load_bar_texpos[1]; long pathable_tile_texpos = df::global::init->load_bar_texpos[1];
long unpathable_tile_texpos = df::global::init->load_bar_texpos[4]; long unpathable_tile_texpos = df::global::init->load_bar_texpos[4];
long on_off_texpos = Textures::getOnOffTexposStart(); long on_off_texpos = Textures::getMapPathableTexposStart();
if (on_off_texpos > 0) { if (on_off_texpos > 0) {
pathable_tile_texpos = on_off_texpos + 0; pathable_tile_texpos = on_off_texpos + 0;
unpathable_tile_texpos = on_off_texpos + 1; unpathable_tile_texpos = on_off_texpos + 1;

@ -14,8 +14,6 @@
#include "PluginManager.h" #include "PluginManager.h"
#include "RemoteFortressReader.pb.h" #include "RemoteFortressReader.pb.h"
#include "RemoteServer.h" #include "RemoteServer.h"
#include "SDL_events.h"
#include "SDL_keyboard.h"
#include "TileTypes.h" #include "TileTypes.h"
#include "VersionInfo.h" #include "VersionInfo.h"
#if DF_VERSION_INT > 34011 #if DF_VERSION_INT > 34011
@ -126,6 +124,9 @@
#include "dwarf_control.h" #include "dwarf_control.h"
#include "item_reader.h" #include "item_reader.h"
#include <SDL_events.h>
#include <SDL_keyboard.h>
using namespace DFHack; using namespace DFHack;
using namespace df::enums; using namespace df::enums;
using namespace RemoteFortressReader; using namespace RemoteFortressReader;
@ -2894,13 +2895,12 @@ static command_result CopyScreen(color_ostream &stream, const EmptyMessage *in,
static command_result PassKeyboardEvent(color_ostream &stream, const KeyboardEvent *in) static command_result PassKeyboardEvent(color_ostream &stream, const KeyboardEvent *in)
{ {
#if DF_VERSION_INT > 34011 #if DF_VERSION_INT > 34011
SDL::Event e; SDL_Event e;
e.key.type = in->type(); e.key.type = in->type();
e.key.state = in->state(); e.key.state = in->state();
e.key.ksym.mod = (SDL::Mod)in->mod(); e.key.keysym.mod = in->mod();
e.key.ksym.scancode = in->scancode(); e.key.keysym.scancode = (SDL_Scancode)in->scancode();
e.key.ksym.sym = (SDL::Key)in->sym(); e.key.keysym.sym = in->sym();
e.key.ksym.unicode = in->unicode();
DFHack::DFSDL::DFSDL_PushEvent(&e); DFHack::DFSDL::DFSDL_PushEvent(&e);
#endif #endif
return CR_OK; return CR_OK;

@ -1 +1 @@
Subproject commit 04e3165b025353219e12a8b2531907c43fb5cdb9 Subproject commit ee8217978d25bc8f9c3efa21156dd8ff99896f68