From 2106f45840ced9f2217bbc4c9724ac57cfaf53bb Mon Sep 17 00:00:00 2001 From: ALONSO Laurent Date: Tue, 26 Oct 2021 10:31:06 +0200 Subject: [PATCH] Scenario Editor: try to correct a problem when displaying terrain in zoom out mode, Mac: add hack to avoid crashing when receiving an apple event, + various minor modifications --- src/dialogxml/dialogs/3choice.hpp | 1 + src/dialogxml/dialogs/pictchoice.hpp | 1 + src/dialogxml/widgets/pict.hpp | 1 + src/fileio/fileio.hpp | 2 ++ src/fileio/fileio_party.cpp | 2 +- src/fileio/fileio_scen.cpp | 2 +- src/fileio/resmgr/resmgr.hpp | 2 ++ src/game/boe.appleevents.mm | 10 +++++- src/game/boe.main.cpp | 13 ++++++-- src/gfx/gfxsheets.hpp | 1 + src/pcedit/pc.appleevents.mm | 34 +++++++++++-------- src/pcedit/pc.main.cpp | 22 ++++++++++++ src/scenario/area.hpp | 2 ++ src/scenario/item.hpp | 1 + src/scenario/monster_abilities.hpp | 2 ++ src/scenario/special.hpp | 2 ++ src/scenedit/scen.actions.cpp | 3 -- src/scenedit/scen.appleevents.mm | 36 ++++++++++---------- src/scenedit/scen.graphics.cpp | 50 +++++++++++++++++----------- src/scenedit/scen.main.cpp | 26 +++++++++++++++ src/sounds.hpp | 2 ++ src/tools/cursors.hpp | 2 ++ src/tools/winutil.hpp | 2 ++ 23 files changed, 159 insertions(+), 60 deletions(-) diff --git a/src/dialogxml/dialogs/3choice.hpp b/src/dialogxml/dialogs/3choice.hpp index 75d2e4fc..a6f0aff1 100644 --- a/src/dialogxml/dialogs/3choice.hpp +++ b/src/dialogxml/dialogs/3choice.hpp @@ -14,6 +14,7 @@ #include #include +#include "global.hpp" #include "keycodes.hpp" #include "choicedlog.hpp" #include "button.hpp" diff --git a/src/dialogxml/dialogs/pictchoice.hpp b/src/dialogxml/dialogs/pictchoice.hpp index 8c0a0566..fdd4c2eb 100644 --- a/src/dialogxml/dialogs/pictchoice.hpp +++ b/src/dialogxml/dialogs/pictchoice.hpp @@ -13,6 +13,7 @@ #include #include +#include "global.hpp" #include "dialog.hpp" #include "ledgroup.hpp" #include "pictypes.hpp" diff --git a/src/dialogxml/widgets/pict.hpp b/src/dialogxml/widgets/pict.hpp index d529d0f3..cf3fc5c6 100644 --- a/src/dialogxml/widgets/pict.hpp +++ b/src/dialogxml/widgets/pict.hpp @@ -16,6 +16,7 @@ #include #include +#include "global.hpp" #include "control.hpp" #include "pictypes.hpp" #include "texture.hpp" diff --git a/src/fileio/fileio.hpp b/src/fileio/fileio.hpp index e1221eeb..61991dfb 100644 --- a/src/fileio/fileio.hpp +++ b/src/fileio/fileio.hpp @@ -15,6 +15,8 @@ #include #include +#include "global.hpp" + class cScenario; class cUniverse; diff --git a/src/fileio/fileio_party.cpp b/src/fileio/fileio_party.cpp index 0662a674..117a4b4f 100644 --- a/src/fileio/fileio_party.cpp +++ b/src/fileio/fileio_party.cpp @@ -12,7 +12,7 @@ #include #include "strdlog.hpp" -#include "gzstream.h" +#include "gzstream/gzstream.h" #include "universe.hpp" #include "gfxsheets.hpp" diff --git a/src/fileio/fileio_scen.cpp b/src/fileio/fileio_scen.cpp index 01a252b2..d9a54ec7 100644 --- a/src/fileio/fileio_scen.cpp +++ b/src/fileio/fileio_scen.cpp @@ -20,7 +20,7 @@ #include "special_parse.hpp" #include "gfxsheets.hpp" #include "mathutil.hpp" -#include "gzstream.h" +#include "gzstream/gzstream.h" #include "tarball.hpp" #include "porting.hpp" diff --git a/src/fileio/resmgr/resmgr.hpp b/src/fileio/resmgr/resmgr.hpp index 0e84ca69..f82b0af3 100644 --- a/src/fileio/resmgr/resmgr.hpp +++ b/src/fileio/resmgr/resmgr.hpp @@ -16,6 +16,8 @@ #include #include +#include "global.hpp" + namespace ResMgr { namespace fs = boost::filesystem; diff --git a/src/game/boe.appleevents.mm b/src/game/boe.appleevents.mm index 3c26d08c..50601a16 100644 --- a/src/game/boe.appleevents.mm +++ b/src/game/boe.appleevents.mm @@ -23,6 +23,7 @@ extern void post_load(); extern bool ae_loading, All_Done, party_in_memory, finished_init; extern eGameMode overall_mode; extern cUniverse univ; +extern bool pending_quit; extern fs::path pending_file_to_load; typedef NSAppleEventDescriptor AEDescr; @@ -57,7 +58,13 @@ void set_up_apple_events(int, char*[]) { All_Done = true; return NSTerminateNow; } - + // REMOVEME when we solve the causes of the crash + // note: this is actually very bad because we will cancel a shutdown, + // and this does not work if a dialog is opened, ... + // but at least this does not lead to a crash + pending_quit=true; + return NSTerminateCancel; +#if 0 if(overall_mode == MODE_TOWN || overall_mode == MODE_OUTDOORS || (overall_mode == MODE_STARTUP && party_in_memory)) { std::string choice = cChoiceDlog("quit-confirm-save", {"save", "quit", "cancel"}).show(); if(choice == "cancel") return NSTerminateCancel; @@ -70,5 +77,6 @@ void set_up_apple_events(int, char*[]) { All_Done = true; return NSTerminateNow; +#endif } @end diff --git a/src/game/boe.main.cpp b/src/game/boe.main.cpp index 21e99062..c7134273 100644 --- a/src/game/boe.main.cpp +++ b/src/game/boe.main.cpp @@ -105,13 +105,15 @@ cDrawableManager drawable_mgr; sf::Clock animTimer; extern long anim_ticks; +fs::path pending_file_to_load=fs::path(); + static void init_boe(int, char*[]); static void showWelcome(); #ifdef __APPLE__ eMenuChoice menuChoice=eMenuChoice::MENU_CHOICE_NONE; short menuChoiceId=-1; -fs::path pending_file_to_load=fs::path(); +bool pending_quit=false; #endif int main(int argc, char* argv[]) { @@ -124,7 +126,7 @@ int main(int argc, char* argv[]) { if(!get_bool_pref("GameRunBefore")) showWelcome(); - else if(get_bool_pref("GiveIntroHint", true)) + else if(!ae_loading && pending_file_to_load.empty() && get_bool_pref("GiveIntroHint", true)) tip_of_day(); set_pref("GameRunBefore", true); finished_init = true; @@ -213,7 +215,9 @@ static void init_ui() { } void init_boe(int argc, char* argv[]) { +#ifdef __APPLE__ set_up_apple_events(argc, argv); +#endif init_directories(argv[0]); #ifdef __APPLE__ init_menubar(); // Do this first of all because otherwise a default File and Window menu will be seen @@ -269,6 +273,11 @@ void handle_events() { while(!All_Done) { bool need_redraw=false; #ifdef __APPLE__ + if (pending_quit) { + pending_quit=false; + handle_menu_choice(eMenu::QUIT); + if (All_Done) break; + } if (!pending_file_to_load.empty()) { // TODO: What if they're already in a scenario? It should ask for confirmation, right? do_load(pending_file_to_load); diff --git a/src/gfx/gfxsheets.hpp b/src/gfx/gfxsheets.hpp index 3920fb0f..26d71bc3 100644 --- a/src/gfx/gfxsheets.hpp +++ b/src/gfx/gfxsheets.hpp @@ -13,6 +13,7 @@ #include #include #include +#include "global.hpp" #include "location.hpp" #include "texture.hpp" diff --git a/src/pcedit/pc.appleevents.mm b/src/pcedit/pc.appleevents.mm index 72b4ae4d..92b5eb68 100644 --- a/src/pcedit/pc.appleevents.mm +++ b/src/pcedit/pc.appleevents.mm @@ -8,15 +8,15 @@ #include "universe.hpp" // Include before Cocoa because the Cocoa header defines things that cause compilation errors in here #include +#include #include #include "fileio.hpp" #include "pc.menus.hpp" #include "pc.fileio.hpp" -extern bool verify_restore_quit(std::string dlog); -extern bool All_Done, party_in_scen, scen_items_loaded; -extern cUniverse univ; -extern fs::path file_in_mem; +extern bool All_Done, party_in_scen; +extern bool pending_quit; +extern fs::path pending_file_to_load; @interface AppleEventHandler : NSObject -(BOOL)application:(NSApplication*) app openFile:(NSString*) file; @@ -33,22 +33,30 @@ void set_up_apple_events(int, char*[]) { @implementation AppleEventHandler -(BOOL)application:(NSApplication*) app openFile:(NSString*) file { (void) app; // Suppress "unused parameter" warning - - std::string fileName=file.fileSystemRepresentation; - if(load_party(fileName, univ)) { - file_in_mem = fileName; - party_in_scen = !univ.party.scen_name.empty(); - if(!party_in_scen) load_base_item_defs(); - scen_items_loaded = true; - menu_activate(); + if(file == nil) { + std::cerr << "Error: filename was nil" << std::endl; + return NO; } - return TRUE; + pending_file_to_load=file.fileSystemRepresentation; + return YES; } -(NSApplicationTerminateReply)applicationShouldTerminate: (NSApplication*)sender { (void) sender; // Suppress "unused parameter" warning + // REMOVEME when we solve the causes of the crash + // note: this is actually very bad because we will cancel a shutdown, + // and this does not work if a dialog is opened, ... + // but at least this does not lead to a crash + if (!party_in_scen) { + All_Done = true; + return NSTerminateNow; + } + pending_quit=true; + return NSTerminateCancel; +#if 0 All_Done = verify_restore_quit("save-quit"); return All_Done ? NSTerminateNow : NSTerminateCancel; +#endif } @end diff --git a/src/pcedit/pc.main.cpp b/src/pcedit/pc.main.cpp index d505069b..cbe1f46e 100644 --- a/src/pcedit/pc.main.cpp +++ b/src/pcedit/pc.main.cpp @@ -29,8 +29,11 @@ #ifdef __APPLE__ short menuChoiceId=-1; +bool pending_quit=false; #endif +fs::path pending_file_to_load=fs::path(); + cUniverse univ; rectangle pc_area_buttons[6][4] ; // 0 - whole 1 - pic 2 - name 3 - stat strs 4,5 - later @@ -190,6 +193,25 @@ void handle_events() { } #ifdef __APPLE__ + if (pending_quit) { + pending_quit=false; + handle_menu_choice(eMenu::QUIT); + if (All_Done) + break; + } + if (!pending_file_to_load.empty()) { + if (verify_restore_quit("save-open")) { + // FIXME: do not dupplicate this code + if (load_party(pending_file_to_load, univ)) { + file_in_mem = pending_file_to_load; + party_in_scen = !univ.party.scen_name.empty(); + if(!party_in_scen) load_base_item_defs(); + scen_items_loaded = true; + } + menu_activate(); + } + pending_file_to_load.clear(); + } if (menuChoiceId>=0) { need_redraw=true; handle_menu_choice(eMenu(menuChoiceId)); diff --git a/src/scenario/area.hpp b/src/scenario/area.hpp index d3619ce1..c4290688 100644 --- a/src/scenario/area.hpp +++ b/src/scenario/area.hpp @@ -13,6 +13,8 @@ #include #include +#include "global.hpp" + #include "vector2d.hpp" #include "location.hpp" #include "special.hpp" diff --git a/src/scenario/item.hpp b/src/scenario/item.hpp index a196667d..357fdc99 100644 --- a/src/scenario/item.hpp +++ b/src/scenario/item.hpp @@ -12,6 +12,7 @@ #include #include +#include "global.hpp" #include "location.hpp" #include "item_abilities.hpp" #include "item_variety.hpp" diff --git a/src/scenario/monster_abilities.hpp b/src/scenario/monster_abilities.hpp index bd2fbf9d..5dca3bb5 100644 --- a/src/scenario/monster_abilities.hpp +++ b/src/scenario/monster_abilities.hpp @@ -9,6 +9,8 @@ #ifndef BoE_DATA_MONSTER_ABILITIES_HPP #define BoE_DATA_MONSTER_ABILITIES_HPP +#include "global.hpp" + #include "damage.hpp" #include "fields.hpp" #include "spell.hpp" diff --git a/src/scenario/special.hpp b/src/scenario/special.hpp index 560e2132..e00241ff 100644 --- a/src/scenario/special.hpp +++ b/src/scenario/special.hpp @@ -12,6 +12,8 @@ #include #include #include + +#include "global.hpp" #include "location.hpp" namespace legacy { struct special_node_type; }; diff --git a/src/scenedit/scen.actions.cpp b/src/scenedit/scen.actions.cpp index fc48cba1..a87278bb 100644 --- a/src/scenedit/scen.actions.cpp +++ b/src/scenedit/scen.actions.cpp @@ -59,7 +59,6 @@ extern std::shared_ptr right_sbar, pal_sbar; extern cOutdoors* current_terrain; extern location cur_out; extern sf::RenderWindow mainPtr; -bool small_any_drawn = false; extern bool change_made; rectangle left_buttons[NLS][2]; // 0 - whole, 1 - blue button @@ -2321,7 +2320,6 @@ void set_up_main_screen() { void start_town_edit() { std::ostringstream strb; - small_any_drawn = false; cen_x = town->max_dim / 2; cen_y = town->max_dim / 2; reset_lb(); @@ -2351,7 +2349,6 @@ void start_town_edit() { void start_out_edit() { std::ostringstream strb; - small_any_drawn = false; cen_x = 24; cen_y = 24; reset_lb(); diff --git a/src/scenedit/scen.appleevents.mm b/src/scenedit/scen.appleevents.mm index eebe2c63..0ee34bbc 100644 --- a/src/scenedit/scen.appleevents.mm +++ b/src/scenedit/scen.appleevents.mm @@ -15,16 +15,12 @@ #include "scen.actions.hpp" #include "scen.townout.hpp" -//extern bool ae_loading, startup_loaded, All_Done, party_in_memory, finished_init; -extern cScenario scenario; -extern cOutdoors* current_terrain; -extern location cur_out; -extern bool change_made, ae_loading; +extern bool pending_quit, change_made, All_Done; +extern fs::path pending_file_to_load; @interface AppleEventHandler : NSObject -(BOOL)application:(NSApplication*) app openFile:(NSString*) file; -// TODO: Handle quit event by putting up quit dialog -//-(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*) sender; +-(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*) sender; @end void set_up_apple_events(int argc, char* argv[]); // Suppress "no prototype" warning @@ -35,25 +31,27 @@ void set_up_apple_events(int, char*[]) { } // TODO: What if they're already in a scenario? It should ask for confirmation, right? -// (Need to figure out cChoiceDlog bug first, though, as it would crash here just like it does on the quit event.) @implementation AppleEventHandler -(BOOL)application:(NSApplication*) app openFile:(NSString*) file { (void) app; // Suppress "unused parameter" warning if(file == nil) { std::cerr << "Error: filename was nil" << std::endl; - return FALSE; + return NO; } - - std::string fileName=file.fileSystemRepresentation; + pending_file_to_load=file.fileSystemRepresentation; + return YES; +} - if(load_scenario(fileName, scenario)) { - set_current_town(scenario.last_town_edited); - cur_out = scenario.last_out_edited; - current_terrain = scenario.outdoors[cur_out.x][cur_out.y]; - change_made = false; - ae_loading = true; - set_up_main_screen(); +-(NSApplicationTerminateReply)applicationShouldTerminate: (NSApplication*)sender { + // REMOVEME when we solve the causes of the crash + // note: this is actually very bad because we will cancel a shutdown, + // and this does not work if a dialog is opened, ... + // but at least this does not lead to a crash + if (!change_made) { + All_Done = true; + return NSTerminateNow; } - return TRUE; + pending_quit=true; + return NSTerminateCancel; } @end diff --git a/src/scenedit/scen.graphics.cpp b/src/scenedit/scen.graphics.cpp index ff575256..24833141 100644 --- a/src/scenedit/scen.graphics.cpp +++ b/src/scenedit/scen.graphics.cpp @@ -82,9 +82,6 @@ rectangle terrain_rect = {0,0,340,272}; std::string current_string[2]; extern rectangle terrain_rects[256]; -unsigned char small_what_drawn[64][64]; -extern bool small_any_drawn; - static short get_small_icon(ter_num_t ter){ short icon = -1; auto const &ter_type=scenario.get_terrain(ter); @@ -930,37 +927,50 @@ void draw_terrain(){ } clip_rect(mainPtr, terrain_rect); - small_any_drawn = false; //if(cur_viewing_mode == 0) // draw_frames(); } else { + // fixme: the bounds are now correct and the scrolling must be fluid, + // however, the procedure which displays is still bad tileImage(mainPtr, terrain_rect,bg[17]); frame_rect(mainPtr, terrain_rect, sf::Color::Black); // Width available: 64 4x4 tiles, 42 6x6 tiles, or 21 12x12 tiles -- 256 pixels // Height available: 81 4x4 tiles, 54 6x6 tiles, or 27 12x12 tiles -- 324 pixels - short size = mini_map_scales[cur_viewing_mode - 1]; - int max_dim = (editing_town ? town->max_dim : 48); - int xMin = 0, yMin = 0, xMax = max_dim, yMax = max_dim; - if(cen_x + 5 > 256 / size) { - xMin = cen_x + 5 - (256 / size); - xMax = cen_x + 5; - } else xMax = std::min(xMax, 256 / size); - if(cen_y + 5 > 324 / size) { - yMin = cen_y + 5 - (324 / size); - yMax = cen_y + 5; - } else yMax = std::min(yMax, 324 / size); - // std::cout << "Drawing map for x = " << xMin << "..." << xMax << " and y = " << yMin << "..." << yMax << std::endl; + short const size = cur_viewing_mode<3 ? mini_map_scales[cur_viewing_mode - 1] : 12; + int const max_dim = (editing_town ? town->max_dim : 48); + int const xNumTiles=(256 / size); + int xMin = cen_x-(xNumTiles/2), xMax = xMin+xNumTiles; + if (xMin<0) { + xMin=0; + xMax=std::min(xNumTiles, max_dim); + cen_x=(xNumTiles/2); + } + else if (xMax>max_dim) { + xMax=max_dim; + xMin=std::max(0, xMax-xNumTiles); + cen_x=xMin+(xNumTiles/2); + } + int const yNumTiles=(324 / size); + int yMin = cen_y-(yNumTiles/2), yMax = yMin+yNumTiles; + if (yMin<0) { + yMin=0; + yMax=std::min(yNumTiles, max_dim); + cen_y=(yNumTiles/2); + } + else if (yMax>max_dim) { + yMax=max_dim; + yMin=std::max(0, yMax-yNumTiles); + cen_y=yMin+(yNumTiles/2); + } for(short q = xMin; q < xMax; q++) for(short r = yMin; r < yMax; r++) { - if(q - xMin < 0 || q - xMin >= max_dim || r - yMin < 0 || r - yMin >= max_dim) + if(q < 0 || q >= max_dim || r < 0 || r >= max_dim) t_to_draw = 90; - else t_to_draw = editing_town ? town->terrain(q,r) : current_terrain->terrain[q][r]; + else t_to_draw = editing_town ? town->terrain(q,r) : current_terrain->terrain(q,r); draw_one_tiny_terrain_spot(q-xMin,r-yMin,t_to_draw,size,is_road(q,r)); - small_what_drawn[q][r] = t_to_draw; } - small_any_drawn = true; } } diff --git a/src/scenedit/scen.main.cpp b/src/scenedit/scen.main.cpp index f4edc924..56fd2624 100644 --- a/src/scenedit/scen.main.cpp +++ b/src/scenedit/scen.main.cpp @@ -36,8 +36,11 @@ #ifdef __APPLE__ short menuChoiceId=-1; +bool pending_quit=false; #endif +fs::path pending_file_to_load=fs::path(); + /* Globals */ bool All_Done = false; bool changed_display_mode = false; @@ -249,6 +252,29 @@ void handle_events() { } #ifdef __APPLE__ + if (pending_quit) { + pending_quit=false; + handle_menu_choice(eMenu::QUIT); + if (All_Done) + break; + } + if (!pending_file_to_load.empty() && save_check("save-before-load")) { + // FIXME: do not dupplicate this code another time + if(load_scenario(pending_file_to_load, scenario)) { + cur_town = scenario.last_town_edited; + town = scenario.towns[cur_town]; + cur_out = scenario.last_out_edited; + current_terrain = scenario.outdoors[cur_out.x][cur_out.y]; + overall_mode = MODE_MAIN_SCREEN; + change_made = false; + set_up_main_screen(); + } else + set_up_start_screen(); // Failed to load file, dump to start + extern cUndoList undo_list; + undo_list.clear(); + update_edit_menu(); + pending_file_to_load.clear(); + } if (menuChoiceId>=0) { need_redraw = true; handle_menu_choice(eMenu(menuChoiceId)); diff --git a/src/sounds.hpp b/src/sounds.hpp index 8c6d901b..fcf8b40b 100644 --- a/src/sounds.hpp +++ b/src/sounds.hpp @@ -12,6 +12,8 @@ #include #include +#include "global.hpp" + void init_snd_tool(); bool sound_going(snd_num_t which_s); void play_sound(snd_num_t which, sf::Time delay = sf::Time()); diff --git a/src/tools/cursors.hpp b/src/tools/cursors.hpp index 27077958..fa121dc8 100644 --- a/src/tools/cursors.hpp +++ b/src/tools/cursors.hpp @@ -12,6 +12,8 @@ #include #include +#include "global.hpp" + enum cursor_type { wand_curs = 0, eyedropper_curs = 1, diff --git a/src/tools/winutil.hpp b/src/tools/winutil.hpp index 9c6b7d56..e191deab 100644 --- a/src/tools/winutil.hpp +++ b/src/tools/winutil.hpp @@ -13,6 +13,8 @@ #include #include +#include "global.hpp" + char keyToChar(sf::Keyboard::Key key, bool isShift); void makeFrontWindow(sf::Window& win);