Opened 2 years ago

Closed 11 months ago

Last modified 11 months ago

#13335 closed defect (fixed)

AGS: Quest for Glory II: Trial by Fire Remake - Winning Keapon Laffin's Game causes crash

Reported by: bliznik Owned by: tag2015
Priority: normal Component: Engine: AGS
Version: Keywords: AGD:QFG2
Cc: Game: Quest for Glory 2


Winning the Wizard-only game against Keapon Laffin causes the game to crash. Upon winning, right after the "cloud/thunder" animation, the game will crash out. I've been able to replicate this three times.

System is Windows. ScummVM version is 2.6.0git3339-g5cb8202d9bc. Game is the AGD Interactive version of Quest for Glory II.

The crash log doesn't provide any data. There are 3 error messages about the sound not working properly (e.g., "Audio stream did not support seeking!"), but those error messages occur far before I even talk to Keapon Laffin, so I don't think those error messages relate to what causes the crash.

Attachments (2)

scummvm.log (3.0 KB ) - added by bliznik 2 years ago.
qfg2agdi.005 (1.5 MB ) - added by bliznik 20 months ago.
savegame right before winning the game and crashing

Download all attachments as: .zip

Change History (11)

by bliznik, 2 years ago

Attachment: scummvm.log added

by bliznik, 20 months ago

Attachment: qfg2agdi.005 added

savegame right before winning the game and crashing

comment:1 by i30817, 19 months ago

Upstream doesn't show this problem, either winning or losing the game, just in case someone wanted to waste time like me to report upstream.

comment:2 by i30817, 19 months ago

Seems to be a bit random now i tried it on scummvm itself. First loss without a debugger didn't trigger it, second loss with one did. Here is a backtrace:

Thread 1 "scummvm" received signal SIGSEGV, Segmentation fault.
0x00005555558b5b5a in AGS3::AGS::Shared::Bitmap::GetWidth (this=0x0) at ./engines/ags/shared/gfx/allegro_bitmap.h:113
113			return _alBitmap->w;
(gdb) bt
#0  0x00005555558b5b5a in AGS3::AGS::Shared::Bitmap::GetWidth() const
    (this=0x0) at ./engines/ags/shared/gfx/allegro_bitmap.h:113
#1  0x0000555555b0ace3 in AGS3::AGS::Engine::ALSW::ALSoftwareBitmap::ALSoftwareBitmap(AGS3::AGS::Shared::Bitmap*, bool, bool)
    (this=0x555558abbf50, bmp=0x0, opaque=true, hasAlpha=false)
    at ./engines/ags/engine/gfx/ali_3d_scummvm.h:96
#2  0x0000555555b08294 in AGS3::AGS::Engine::ALSW::ScummVMRendererGraphicsDriver::CreateDDBFromBitmap(AGS3::AGS::Shared::Bitmap*, bool, bool)
    (this=0x555557f2d8e0, bitmap=0x0, hasAlpha=false, opaque=true)
    at engines/ags/engine/gfx/ali_3d_scummvm.cpp:234
#3  0x0000555555b0aed4 in AGS3::AGS::Engine::ALSW::ScummVMRendererGraphicsDriver::GetSharedDDB(unsigned int, AGS3::AGS::Shared::Bitmap*, bool, bool)
    (this=0x555557f2d8e0, bitmap=0x0, hasAlpha=false, opaque=true)
    at ./engines/ags/engine/gfx/ali_3d_scummvm.h:185
#4  0x000055555591094d in AGS3::recycle_ddb_sprite(AGS3::AGS::Engine::IDriverDependantBitmap*, unsigned int, AGS3::AGS::Shared::Bitmap*, bool, bool)
    (ddb=0x0, sprite_id=4294967295, source=0x0, has_alpha=false, opaque=true)
    at engines/ags/engine/ac/draw.cpp:775
#5  0x0000555555919f70 in AGS3::recycle_ddb_bitmap(AGS3::AGS::Engine::IDriverDependantBitmap*, AGS3::AGS::Shared::Bitmap*, bool, bool)
    (ddb=0x0, source=0x0, has_alpha=false, opaque=true)
    at ./engines/ags/engine/ac/draw.h:156
#6  0x0000555555915428 in AGS3::prepare_room_sprites() ()
--Type <RET> for more, q to quit, c to continue without paging--
    at engines/ags/engine/ac/draw.cpp:1706
#7  0x0000555555916fd1 in AGS3::construct_room_view() ()
    at engines/ags/engine/ac/draw.cpp:2051
#8  0x0000555555917e84 in AGS3::construct_game_scene(bool) (full_redraw=true)
    at engines/ags/engine/ac/draw.cpp:2181
#9  0x0000555555921c74 in AGS3::create_savegame_screenshot() ()
    at engines/ags/engine/ac/game.cpp:838
#10 0x0000555555921f10 in AGS3::save_game(int, char const*)
    (slotn=0, descript=0x7fffffffb8f0 "Autosave")
    at engines/ags/engine/ac/game.cpp:883
#11 0x000055555589e3bf in AGS::AGSEngine::saveGameState(int, Common::String const&, bool) (this=0x555557f437f0, slot=0, desc=..., isAutosave=true)
    at engines/ags/ags.cpp:274
#12 0x0000555555b1b75d in Engine::saveAutosaveIfEnabled() (this=0x555557f437f0)
    at engines/engine.cpp:595
#13 0x0000555555b1b1b6 in Engine::handleAutoSave() (this=0x555557f437f0)
    at engines/engine.cpp:542
#14 0x0000555555bdeb63 in DefaultEventManager::pollEvent(Common::Event&)
    (this=0x555556c879a0, event=...)
    at backends/events/default/default-events.cpp:87
#15 0x00005555558a099d in AGS::EventsManager::pollEvents()
    (this=0x555557f31000) at engines/ags/events.cpp:45
#16 0x00005555559a71ad in AGS3::update_polled_stuff_if_runtime() ()
--Type <RET> for more, q to quit, c to continue without paging--
    at engines/ags/engine/main/game_run.cpp:1042
#17 0x00005555558ec86b in AGS3::AGS::Shared::load_room(AGS3::AGS::Shared::String const&, AGS3::AGS::Shared::RoomStruct*, bool, AGS3::std::vector<AGS3::SpriteInfo> const&)
    (filename=..., room=0x55555818a100, game_is_hires=false, sprinfos=...)
    at engines/ags/shared/game/room_struct.cpp:233
#18 0x0000555555959448 in AGS3::load_new_room(int, AGS3::CharacterInfo*)
    (newnum=30, forchar=0x5555583774f0) at engines/ags/engine/ac/room.cpp:439
#19 0x000055555595bb4e in AGS3::new_room(int, AGS3::CharacterInfo*)
    (newnum=30, forchar=0x5555583774f0) at engines/ags/engine/ac/room.cpp:921
#20 0x00005555559c10aa in AGS3::post_script_cleanup() ()
    at engines/ags/engine/script/script.cpp:511
#21 0x00005555559c07dd in AGS3::RunScriptFunction(AGS3::ccInstance*, char const*, unsigned long, AGS3::RuntimeScriptValue const*)
    (sci=0x5555599b19b0, tsname=0x55555687c620 <AGS3::scfunctionname> "on_event", numParam=0, params=0x0) at engines/ags/engine/script/script.cpp:374
#22 0x00005555559c093a in AGS3::RunScriptFunctionInRoom(char const*, unsigned long, AGS3::RuntimeScriptValue const*)
    (tsname=0x5555571ba900 "room_b", param_count=0, params=0x0)
    at engines/ags/engine/script/script.cpp:399
#23 0x00005555559c0b86 in AGS3::RunScriptFunctionAuto(AGS3::ScriptInstType, char const*, unsigned long, AGS3::RuntimeScriptValue const*)
    (sc_inst=AGS3::kScInstRoom, tsname=0x5555571ba900 "room_b", param_count=0, p--Type <RET> for more, q to quit, c to continue without paging--
arams=0x0) at engines/ags/engine/script/script.cpp:435
#24 0x00005555559c0317 in AGS3::QueueScriptFunction(AGS3::ScriptInstType, char const*, unsigned long, AGS3::RuntimeScriptValue const*)
    (sc_inst=AGS3::kScInstRoom, fn_name=0x5555571ba900 "room_b", param_count=0, params=0x0) at engines/ags/engine/script/script.cpp:282
#25 0x00005555559bfc10 in AGS3::run_interaction_script(AGS3::AGS::Shared::InteractionScripts*, int, int) (nint=0x5555579ab940, evnt=6, chkAny=-1)
    at engines/ags/engine/script/script.cpp:190
#26 0x0000555555ac0313 in AGS3::process_event(AGS3::EventHappened const*)
    (evp=0x555558910ee4) at engines/ags/engine/ac/event.cpp:180
#27 0x0000555555ac1351 in AGS3::processallevents() ()
    at engines/ags/engine/ac/event.cpp:365
#28 0x00005555559a61d4 in AGS3::game_loop_update_events() ()
    at engines/ags/engine/main/game_run.cpp:657
#29 0x00005555559a6833 in AGS3::UpdateGameOnce(bool, AGS3::AGS::Engine::IDriverDependantBitmap*, int, int)
    (checkControls=true, extraBitmap=0x0, extraX=0, extraY=0)
    at engines/ags/engine/main/game_run.cpp:789
#30 0x00005555559a6d64 in AGS3::GameTick() ()
    at engines/ags/engine/main/game_run.cpp:938
#31 0x00005555559a7107 in AGS3::RunGameUntilAborted() ()
    at engines/ags/engine/main/game_run.cpp:1032
#32 0x00005555559a78ef in AGS3::initialize_start_and_play_game(int, int)
--Type <RET> for more, q to quit, c to continue without paging--
    (override_start_room=0, loadSave=-1)
    at engines/ags/engine/main/game_start.cpp:129
#33 0x000055555599fa91 in AGS3::initialize_engine(AGS3::std::map<AGS3::AGS::Shared::String, AGS3::std::map<AGS3::AGS::Shared::String, AGS3::AGS::Shared::String, Common::Less<AGS3::AGS::Shared::String> >, Common::Less<AGS3::AGS::Shared::String> > const&) (startup_opts=...) at engines/ags/engine/main/engine.cpp:1195
#34 0x000055555589dd93 in AGS::AGSEngine::run() (this=0x555557f437f0)
    at engines/ags/ags.cpp:195
#35 0x0000555555875171 in runGame(Plugin const*, Plugin const*, OSystem&, Common::String const&)
    (plugin=0x555556bdfeb0, enginePlugin=0x555556bdd220, system=..., debugLevels=...) at base/main.cpp:318
#36 0x0000555555876ab5 in scummvm_main(int, char const* const*)
    (argc=1, argv=0x7fffffffdde8) at base/main.cpp:619
#37 0x000055555587210b in main(int, char**) (argc=1, argv=0x7fffffffdde8)
    at backends/platform/sdl/posix/posix-main.cpp:44

comment:3 by i30817, 19 months ago

Here is a savegame. Unfortunately you can't save in the game itself, so it's just a bit of time savings (click the talk icon on the hero to 'challenge to a game')

comment:4 by tag2015, 11 months ago

Does the crash still occur?

in reply to:  4 comment:5 by lwcorp, 11 months ago

Replying to tag2015:

Does the crash still occur?

Since the savegame must be before the game, if only we had AI to play it...

But if anyone reading this likes arcade sequences inside quests, you may want to assist (in both the latest stable, which came out months after this submission, and latest daily).

Version 0, edited 11 months ago by lwcorp (next)

comment:6 by PushmePullyu, 11 months ago

It looks like the problem occurred when an auto save was triggered during loading of a new room after the wizard game:
old engines/ags/shared/game/room_struct.cpp (from 5d9ae41cd6569f046ec2113e7d3bd213a90e5cce):

AGS3::AGS::Shared::load_room(...) {
  room->Free(); // <----------------------- room background frames are zeroed here
  room->InitDefaults();  // <-------------- and not set here

  update_polled_stuff_if_runtime(); // <--- this can trigger a queued auto save event
  /* room loading code is here */ // <----- before the room is loaded here

The auto save code would eventually call "AGS3::create_savegame_screenshot()".
This lead to an attempt to draw the current room with background frames set to 0, thus causing the crash.

If this is correct, the bug should be fixed since commit c366ce5eefbd01435f063a4efe9d828a1d648f0c
(which removes the "update_polled_stuff_if_runtime()" call).

comment:7 by tag2015, 11 months ago

Wow, thanks a lot for looking into this!
During the minigame, saving is disabled, so an autosave would indeed get triggered as soon as you left the room (unless you spent a really short time in the minigame, depends on what the autosave interval is set to) and cause the crash when creating the screenshot before the new room is completely loaded.
The backtrace seems to corroborate your idea, so I'll close this for now :)

comment:8 by tag2015, 11 months ago

Owner: set to tag2015
Resolution: fixed
Status: newclosed

comment:9 by bliznik, 11 months ago

I just tested this on last night's build. I was able to win the game without the game crashing. thanks for the fix!

Note: See TracTickets for help on using tickets.