Black screen when working on vehicle

I can’t recall the exact instance, but it happens when working on a vehicle (repairing, installing, removing) and an event asks you to stop what you’re doing (events like monster seen, becoming tired, etc). Sometimes, instead of displaying the Y/N prompt the whole screen turns black.

Knowing the probable cause I managed to bypass this by pressing Y when asked for the first time, and I’ve been doing so since then. With that said, this should be looked into, as it looks like a “crash” while it’s in fact just the screen not updating the display properly.

I confirmed the bug in the version 0.5 stable.
When I craft liquid (such as clean water), if I spot a monster
just before crafting is done, I get a blank screen.

  • game::complete_craft() calls game::handle_liquid()
  • game::handle_liquid() calls game::inv_type()
  • game::inv_type() calls erase() and game::refresh_all()
  • game::refresh_all() calls game::draw()
  • game::draw() calls game::mon_info()
  • game::mon_info() calls game::cancel_activity_query()
  • game::cancel_activity_query() calls query_yn()
  • query_yn() calls getch()
  • getch() implicitly calls refresh() and erases the screen
    If there is no monster, no problem is found because game::mon_info()
    calls refresh() (this erases the screen) and game::do_turn() immediately
    calls game::draw() again.

The fix is:

  • game::draw() calls game::mon_info() at the end
  • game::refresh_all() calls game::draw() at the end
  • game::mon_info() calls game::cancel_activity_query() at the end
  • game::inv_type() calls refresh() as soon as it calls erase()

— a/game.cpp
+++ b/game.cpp
@@ -3028,7 +3028,6 @@
werase(w_terrain);
draw_ter();
draw_footsteps();

  • mon_info();
    // Draw Status
    draw_HP();
    werase(w_status);
    @@ -3077,6 +3076,8 @@
    wrefresh(w_status);
    // Draw messages
    write_msg();
  • // mon_info() must be called last because it can call cancel_activity_query()
  • mon_info();
    }

bool game::isBetween(int test, int down, int up)
@@ -3142,13 +3143,14 @@
void game::refresh_all()
{
m.reset_vehicle_cache();

  • draw();
    draw_minimap();
    draw_HP();
    wrefresh(w_moninfo);
    wrefresh(w_messages);
    werase(w_void);
    wrefresh(w_void);
    +// draw() must be called last because it calls mon_info()
  • draw();
    refresh();
    }

@@ -3726,21 +3728,6 @@
}
}

  • if (newseen > mostseen) {

  • if (u.activity.type == ACT_REFILL_VEHICLE)

  • cancel_activity_query(“Monster Spotted!”);

  • cancel_activity_query(“Monster spotted!”);

  • turnssincelastmon = 0;

  • if (run_mode == 1)

  • run_mode = 2; // Stop movement!

  • } else if (autosafemode && newseen == 0) { // Auto-safemode

  • turnssincelastmon++;

  • if(turnssincelastmon >= OPTIONS[OPT_AUTOSAFEMODETURNS] && run_mode == 0)

  • run_mode = 1;

  • }

  • mostseen = newseen;
    nc_color tmpcol;
    // Print the direction headings
    // Reminder:
    @@ -3873,6 +3860,24 @@

    wrefresh(w_moninfo);
    refresh();

+// cancel_activity_query() must be called after drawing is done
+// because it can call query_yn()

  • if (newseen > mostseen) {
  • if (u.activity.type == ACT_REFILL_VEHICLE)
  • cancel_activity_query(“Monster Spotted!”);
  • cancel_activity_query(“Monster spotted!”);
  • turnssincelastmon = 0;
  • if (run_mode == 1)
  • run_mode = 2; // Stop movement!
  • } else if (autosafemode && newseen == 0) { // Auto-safemode
  • turnssincelastmon++;
  • if(turnssincelastmon >= OPTIONS[OPT_AUTOSAFEMODETURNS] && run_mode == 0)
  • run_mode = 1;
  • }
  • mostseen = newseen;
    }

void game::cleanup_dead()
— a/inventory_ui.cpp
+++ b/inventory_ui.cpp
@@ -281,6 +281,7 @@
werase(w_inv);
delwin(w_inv);
erase();

  • refresh();
    refresh_all();
    return (char)ch;
    }

It looks as only the *seen has to be taken from context. I know it’s not about refresh because there’s no refreshing at the end of it, only a query left behind the “black screen” being written about, and it’s cancelled with a simple ESC. It’s fairly similar to the buggy examine view call, it calls some functions aren’t drawn so they leave buggy pixels. For me, it’s only test & run work.