aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/events/androidsdl/androidsdl-events.cpp23
-rw-r--r--devtools/create_titanic/create_titanic_dat.cpp213
-rw-r--r--dists/msvc10/create_msvc10.bat4
-rw-r--r--dists/msvc11/create_msvc11.bat4
-rw-r--r--dists/msvc12/create_msvc12.bat4
-rw-r--r--dists/msvc9/create_msvc9.bat4
-rw-r--r--engines/adl/adl.cpp22
-rw-r--r--engines/adl/adl.h1
-rw-r--r--engines/adl/adl_v2.cpp74
-rw-r--r--engines/adl/adl_v2.h9
-rw-r--r--engines/adl/adl_v3.cpp229
-rw-r--r--engines/adl/adl_v3.h29
-rw-r--r--engines/adl/adl_v4.cpp258
-rw-r--r--engines/adl/adl_v4.h (renamed from engines/adl/hires2.h)63
-rw-r--r--engines/adl/detection.cpp28
-rw-r--r--engines/adl/detection.h1
-rw-r--r--engines/adl/disk.cpp72
-rw-r--r--engines/adl/disk.h20
-rw-r--r--engines/adl/hires0.cpp311
-rw-r--r--engines/adl/hires1.cpp103
-rw-r--r--engines/adl/hires1.h134
-rw-r--r--engines/adl/hires2.cpp98
-rw-r--r--engines/adl/hires4.cpp271
-rw-r--r--engines/adl/hires6.cpp119
-rw-r--r--engines/adl/hires6.h92
-rw-r--r--engines/adl/module.mk2
-rw-r--r--engines/director/archive.cpp248
-rw-r--r--engines/director/director.cpp245
-rw-r--r--engines/director/director.h9
-rw-r--r--engines/director/frame.cpp98
-rw-r--r--engines/director/frame.h2
-rw-r--r--engines/director/images.cpp33
-rw-r--r--engines/director/lingo/lingo-funcs.cpp23
-rw-r--r--engines/director/lingo/lingo.cpp24
-rw-r--r--engines/director/lingo/lingo.h2
-rw-r--r--engines/director/module.mk1
-rw-r--r--engines/director/score.cpp86
-rw-r--r--engines/director/score.h7
-rw-r--r--engines/director/sprite.cpp11
-rw-r--r--engines/fullpipe/behavior.cpp22
-rw-r--r--engines/fullpipe/fullpipe.cpp5
-rw-r--r--engines/fullpipe/fullpipe.h4
-rw-r--r--engines/fullpipe/gfx.cpp20
-rw-r--r--engines/fullpipe/interaction.cpp4
-rw-r--r--engines/fullpipe/inventory.cpp32
-rw-r--r--engines/fullpipe/lift.cpp5
-rw-r--r--engines/fullpipe/messages.cpp4
-rw-r--r--engines/fullpipe/modal.cpp32
-rw-r--r--engines/fullpipe/motion.cpp40
-rw-r--r--engines/fullpipe/objects.h2
-rw-r--r--engines/fullpipe/scene.cpp2
-rw-r--r--engines/fullpipe/scenes/scene03.cpp8
-rw-r--r--engines/fullpipe/scenes/scene04.cpp9
-rw-r--r--engines/fullpipe/stateloader.cpp4
-rw-r--r--engines/fullpipe/statics.cpp70
-rw-r--r--engines/fullpipe/utils.cpp2
-rw-r--r--engines/kyra/animator_tim.cpp3
-rw-r--r--engines/sci/engine/file.cpp2
-rw-r--r--engines/sci/engine/kernel_tables.h43
-rw-r--r--engines/sci/engine/kfile.cpp9
-rw-r--r--engines/sci/engine/kgraphics32.cpp13
-rw-r--r--engines/sci/engine/savegame.cpp13
-rw-r--r--engines/sci/engine/savegame.h5
-rw-r--r--engines/sci/engine/script_patches.cpp113
-rw-r--r--engines/sci/engine/workarounds.cpp5
-rw-r--r--engines/sci/engine/workarounds.h1
-rw-r--r--engines/sci/graphics/celobj32.cpp17
-rw-r--r--engines/sci/graphics/text32.cpp6
-rw-r--r--engines/sci/sci.cpp9
-rw-r--r--engines/sci/video/robot_decoder.cpp1
-rw-r--r--engines/titanic/carry/bridge_piece.cpp4
-rw-r--r--engines/titanic/carry/carry.h2
-rw-r--r--engines/titanic/carry/glass.h2
-rw-r--r--engines/titanic/carry/maitred_left_arm.cpp33
-rw-r--r--engines/titanic/carry/maitred_left_arm.h7
-rw-r--r--engines/titanic/carry/maitred_right_arm.cpp12
-rw-r--r--engines/titanic/carry/maitred_right_arm.h2
-rw-r--r--engines/titanic/carry/mouth.cpp40
-rw-r--r--engines/titanic/carry/mouth.h4
-rw-r--r--engines/titanic/carry/napkin.cpp1
-rw-r--r--engines/titanic/carry/nose.cpp25
-rw-r--r--engines/titanic/carry/nose.h3
-rw-r--r--engines/titanic/carry/perch.cpp13
-rw-r--r--engines/titanic/carry/perch.h2
-rw-r--r--engines/titanic/carry/phonograph_cylinder.cpp32
-rw-r--r--engines/titanic/carry/photograph.cpp11
-rw-r--r--engines/titanic/carry/plug_in.cpp16
-rw-r--r--engines/titanic/carry/speech_centre.cpp42
-rw-r--r--engines/titanic/carry/speech_centre.h9
-rw-r--r--engines/titanic/carry/vision_centre.cpp29
-rw-r--r--engines/titanic/carry/vision_centre.h4
-rw-r--r--engines/titanic/core/drop_target.h2
-rw-r--r--engines/titanic/core/game_object.cpp14
-rw-r--r--engines/titanic/core/game_object.h27
-rw-r--r--engines/titanic/core/multi_drop_target.cpp21
-rw-r--r--engines/titanic/core/multi_drop_target.h2
-rw-r--r--engines/titanic/core/saveable_object.cpp21
-rw-r--r--engines/titanic/core/tree_item.cpp4
-rw-r--r--engines/titanic/core/turn_on_play_sound.cpp25
-rw-r--r--engines/titanic/core/turn_on_play_sound.h8
-rw-r--r--engines/titanic/core/turn_on_turn_off.cpp49
-rw-r--r--engines/titanic/core/turn_on_turn_off.h13
-rw-r--r--engines/titanic/game/arboretum_gate.cpp201
-rw-r--r--engines/titanic/game/arboretum_gate.h48
-rw-r--r--engines/titanic/game/code_wheel.cpp66
-rw-r--r--engines/titanic/game/code_wheel.h7
-rw-r--r--engines/titanic/game/head_smash_lever.cpp12
-rw-r--r--engines/titanic/game/head_smash_lever.h2
-rw-r--r--engines/titanic/game/long_stick_dispenser.cpp99
-rw-r--r--engines/titanic/game/long_stick_dispenser.h8
-rw-r--r--engines/titanic/game/maitred/maitred_arm_holder.cpp19
-rw-r--r--engines/titanic/game/maitred/maitred_arm_holder.h3
-rw-r--r--engines/titanic/game/maitred/maitred_body.cpp46
-rw-r--r--engines/titanic/game/maitred/maitred_body.h8
-rw-r--r--engines/titanic/game/maitred/maitred_legs.cpp66
-rw-r--r--engines/titanic/game/maitred/maitred_legs.h7
-rw-r--r--engines/titanic/game/maitred/maitred_prod_receptor.cpp81
-rw-r--r--engines/titanic/game/maitred/maitred_prod_receptor.h9
-rw-r--r--engines/titanic/game/missiveomat.cpp295
-rw-r--r--engines/titanic/game/missiveomat.h27
-rw-r--r--engines/titanic/game/missiveomat_button.cpp30
-rw-r--r--engines/titanic/game/missiveomat_button.h8
-rw-r--r--engines/titanic/game/movie_tester.cpp26
-rw-r--r--engines/titanic/game/movie_tester.h6
-rw-r--r--engines/titanic/game/music_console_button.cpp96
-rw-r--r--engines/titanic/game/music_console_button.h4
-rw-r--r--engines/titanic/game/music_room_stop_phonograph_button.cpp40
-rw-r--r--engines/titanic/game/music_room_stop_phonograph_button.h7
-rw-r--r--engines/titanic/game/music_system_lock.cpp28
-rw-r--r--engines/titanic/game/music_system_lock.h3
-rw-r--r--engines/titanic/game/nav_helmet.cpp99
-rw-r--r--engines/titanic/game/nav_helmet.h13
-rw-r--r--engines/titanic/game/nav_helmet_off.cpp49
-rw-r--r--engines/titanic/game/nav_helmet_off.h (renamed from engines/titanic/gfx/chev_switch.h)19
-rw-r--r--engines/titanic/game/nav_helmet_on.cpp49
-rw-r--r--engines/titanic/game/nav_helmet_on.h (renamed from engines/adl/hires0.h)112
-rw-r--r--engines/titanic/game/no_nut_bowl.cpp21
-rw-r--r--engines/titanic/game/no_nut_bowl.h4
-rw-r--r--engines/titanic/game/nose_holder.cpp79
-rw-r--r--engines/titanic/game/nose_holder.h8
-rw-r--r--engines/titanic/game/nut_replacer.cpp16
-rw-r--r--engines/titanic/game/nut_replacer.h3
-rw-r--r--engines/titanic/game/parrot/parrot_lobby_controller.cpp35
-rw-r--r--engines/titanic/game/parrot/parrot_lobby_controller.h2
-rw-r--r--engines/titanic/game/parrot/parrot_lobby_link_updater.cpp78
-rw-r--r--engines/titanic/game/parrot/parrot_lobby_link_updater.h20
-rw-r--r--engines/titanic/game/parrot/parrot_lobby_object.cpp32
-rw-r--r--engines/titanic/game/parrot/parrot_lobby_object.h8
-rw-r--r--engines/titanic/game/parrot/parrot_lobby_view_object.cpp16
-rw-r--r--engines/titanic/game/parrot/parrot_lobby_view_object.h6
-rw-r--r--engines/titanic/game/parrot/parrot_loser.cpp10
-rw-r--r--engines/titanic/game/parrot/parrot_loser.h2
-rw-r--r--engines/titanic/game/parrot/parrot_nut_bowl_actor.cpp78
-rw-r--r--engines/titanic/game/parrot/parrot_nut_bowl_actor.h11
-rw-r--r--engines/titanic/game/parrot/parrot_nut_eater.cpp52
-rw-r--r--engines/titanic/game/parrot/parrot_nut_eater.h5
-rw-r--r--engines/titanic/game/parrot/parrot_perch_holder.cpp45
-rw-r--r--engines/titanic/game/parrot/parrot_perch_holder.h5
-rw-r--r--engines/titanic/game/parrot/parrot_trigger.cpp13
-rw-r--r--engines/titanic/game/parrot/parrot_trigger.h2
-rw-r--r--engines/titanic/game/parrot/player_meets_parrot.cpp6
-rw-r--r--engines/titanic/game/parrot/player_meets_parrot.h1
-rw-r--r--engines/titanic/game/pet/pet.cpp12
-rw-r--r--engines/titanic/game/pet/pet.h2
-rw-r--r--engines/titanic/game/pet/pet_lift.cpp37
-rw-r--r--engines/titanic/game/pet/pet_lift.h2
-rw-r--r--engines/titanic/game/pet/pet_monitor.cpp20
-rw-r--r--engines/titanic/game/pet/pet_pellerator.cpp24
-rw-r--r--engines/titanic/game/pet/pet_pellerator.h3
-rw-r--r--engines/titanic/game/pet/pet_sentinal.cpp29
-rw-r--r--engines/titanic/game/pet/pet_sentinal.h7
-rw-r--r--engines/titanic/game/pet/pet_sounds.cpp28
-rw-r--r--engines/titanic/game/pet/pet_sounds.h8
-rw-r--r--engines/titanic/game/pet/pet_transition.cpp23
-rw-r--r--engines/titanic/game/pet/pet_transition.h2
-rw-r--r--engines/titanic/game/pet/pet_transport.cpp2
-rw-r--r--engines/titanic/game/pet_disabler.cpp15
-rw-r--r--engines/titanic/game/pet_disabler.h3
-rw-r--r--engines/titanic/game/phonograph.cpp120
-rw-r--r--engines/titanic/game/phonograph.h8
-rw-r--r--engines/titanic/game/phonograph_lid.cpp51
-rw-r--r--engines/titanic/game/phonograph_lid.h9
-rw-r--r--engines/titanic/game/pickup/pick_up.cpp14
-rw-r--r--engines/titanic/game/pickup/pick_up.h8
-rw-r--r--engines/titanic/game/pickup/pick_up_bar_glass.cpp51
-rw-r--r--engines/titanic/game/pickup/pick_up_bar_glass.h4
-rw-r--r--engines/titanic/game/pickup/pick_up_hose.cpp67
-rw-r--r--engines/titanic/game/pickup/pick_up_hose.h9
-rw-r--r--engines/titanic/game/pickup/pick_up_lemon.cpp25
-rw-r--r--engines/titanic/game/pickup/pick_up_lemon.h3
-rw-r--r--engines/titanic/game/pickup/pick_up_speech_centre.cpp36
-rw-r--r--engines/titanic/game/pickup/pick_up_speech_centre.h4
-rw-r--r--engines/titanic/game/pickup/pick_up_vis_centre.cpp23
-rw-r--r--engines/titanic/game/pickup/pick_up_vis_centre.h3
-rw-r--r--engines/titanic/game/placeholder/bar_shelf_vis_centre.cpp6
-rw-r--r--engines/titanic/game/placeholder/bar_shelf_vis_centre.h6
-rw-r--r--engines/titanic/game/placeholder/lemon_on_bar.cpp6
-rw-r--r--engines/titanic/game/placeholder/lemon_on_bar.h4
-rw-r--r--engines/titanic/game/placeholder/place_holder.cpp (renamed from engines/titanic/game/placeholder/place_holder_item.cpp)15
-rw-r--r--engines/titanic/game/placeholder/place_holder.h (renamed from engines/titanic/game/placeholder/place_holder_item.h)4
-rw-r--r--engines/titanic/game/placeholder/tv_on_bar.cpp22
-rw-r--r--engines/titanic/game/placeholder/tv_on_bar.h8
-rw-r--r--engines/titanic/game/play_music_button.cpp43
-rw-r--r--engines/titanic/game/play_music_button.h9
-rw-r--r--engines/titanic/game/play_on_act.cpp21
-rw-r--r--engines/titanic/game/play_on_act.h3
-rw-r--r--engines/titanic/game/port_hole.cpp62
-rw-r--r--engines/titanic/game/port_hole.h9
-rw-r--r--engines/titanic/game/record_phonograph_button.cpp32
-rw-r--r--engines/titanic/game/record_phonograph_button.h7
-rw-r--r--engines/titanic/game/replacement_ear.cpp11
-rw-r--r--engines/titanic/game/replacement_ear.h2
-rw-r--r--engines/titanic/game/reserved_table.cpp41
-rw-r--r--engines/titanic/game/reserved_table.h8
-rw-r--r--engines/titanic/game/restaurant_cylinder_holder.cpp108
-rw-r--r--engines/titanic/game/restaurant_cylinder_holder.h13
-rw-r--r--engines/titanic/game/restaurant_phonograph.cpp96
-rw-r--r--engines/titanic/game/restaurant_phonograph.h10
-rw-r--r--engines/titanic/game/sauce_dispensor.cpp112
-rw-r--r--engines/titanic/game/sauce_dispensor.h7
-rw-r--r--engines/titanic/game/search_point.cpp21
-rw-r--r--engines/titanic/game/search_point.h2
-rw-r--r--engines/titanic/game/season_background.cpp103
-rw-r--r--engines/titanic/game/season_background.h13
-rw-r--r--engines/titanic/game/season_barrel.cpp27
-rw-r--r--engines/titanic/game/season_barrel.h9
-rw-r--r--engines/titanic/game/seasonal_adjustment.cpp93
-rw-r--r--engines/titanic/game/seasonal_adjustment.h17
-rw-r--r--engines/titanic/game/service_elevator_window.cpp63
-rw-r--r--engines/titanic/game/service_elevator_window.h4
-rw-r--r--engines/titanic/game/sgt/bedhead.cpp122
-rw-r--r--engines/titanic/game/sgt/bedhead.h40
-rw-r--r--engines/titanic/game/sgt/sgt_doors.cpp61
-rw-r--r--engines/titanic/game/sgt/sgt_doors.h10
-rw-r--r--engines/titanic/game/sgt/sgt_nav.cpp44
-rw-r--r--engines/titanic/game/sgt/sgt_nav.h3
-rw-r--r--engines/titanic/game/sgt/sgt_navigation.cpp79
-rw-r--r--engines/titanic/game/sgt/sgt_navigation.h6
-rw-r--r--engines/titanic/game/sgt/sgt_restaurant_doors.cpp10
-rw-r--r--engines/titanic/game/sgt/sgt_restaurant_doors.h2
-rw-r--r--engines/titanic/game/sgt/sgt_state_control.cpp47
-rw-r--r--engines/titanic/game/sgt/sgt_state_control.h11
-rw-r--r--engines/titanic/game/sgt/sgt_tv.cpp37
-rw-r--r--engines/titanic/game/sgt/sgt_tv.h4
-rw-r--r--engines/titanic/game/sgt/toilet.cpp44
-rw-r--r--engines/titanic/game/sgt/toilet.h4
-rw-r--r--engines/titanic/game/sgt/vase.cpp40
-rw-r--r--engines/titanic/game/sgt/vase.h4
-rw-r--r--engines/titanic/game/sgt/washstand.cpp38
-rw-r--r--engines/titanic/game/sgt/washstand.h4
-rw-r--r--engines/titanic/game/ship_setting.cpp90
-rw-r--r--engines/titanic/game/ship_setting.h10
-rw-r--r--engines/titanic/game/ship_setting_button.cpp58
-rw-r--r--engines/titanic/game/ship_setting_button.h11
-rw-r--r--engines/titanic/game/show_cell_points.cpp37
-rw-r--r--engines/titanic/game/show_cell_points.h9
-rw-r--r--engines/titanic/game/speech_dispensor.cpp106
-rw-r--r--engines/titanic/game/speech_dispensor.h15
-rw-r--r--engines/titanic/game/starling_puret.cpp44
-rw-r--r--engines/titanic/game/starling_puret.h8
-rw-r--r--engines/titanic/game/stop_phonograph_button.cpp19
-rw-r--r--engines/titanic/game/stop_phonograph_button.h2
-rw-r--r--engines/titanic/game/sub_glass.cpp75
-rw-r--r--engines/titanic/game/sub_glass.h16
-rw-r--r--engines/titanic/game/sub_wrapper.cpp44
-rw-r--r--engines/titanic/game/sub_wrapper.h7
-rw-r--r--engines/titanic/game/sweet_bowl.cpp30
-rw-r--r--engines/titanic/game/sweet_bowl.h4
-rw-r--r--engines/titanic/game/third_class_canal.cpp9
-rw-r--r--engines/titanic/game/third_class_canal.h2
-rw-r--r--engines/titanic/game/throw_tv_down_well.cpp63
-rw-r--r--engines/titanic/game/throw_tv_down_well.h12
-rw-r--r--engines/titanic/game/titania_still_control.cpp16
-rw-r--r--engines/titanic/game/titania_still_control.h3
-rw-r--r--engines/titanic/game/tow_parrot_nav.cpp17
-rw-r--r--engines/titanic/game/tow_parrot_nav.h2
-rw-r--r--engines/titanic/game/transport/lift_indicator.cpp12
-rw-r--r--engines/titanic/game/transport/service_elevator.cpp227
-rw-r--r--engines/titanic/game/transport/service_elevator.h16
-rw-r--r--engines/titanic/game/up_lighter.cpp67
-rw-r--r--engines/titanic/game/up_lighter.h7
-rw-r--r--engines/titanic/game/useless_lever.cpp24
-rw-r--r--engines/titanic/game/useless_lever.h3
-rw-r--r--engines/titanic/game/wheel_button.cpp45
-rw-r--r--engines/titanic/game/wheel_button.h8
-rw-r--r--engines/titanic/game/wheel_hotspot.cpp40
-rw-r--r--engines/titanic/game/wheel_hotspot.h3
-rw-r--r--engines/titanic/game/wheel_spin.cpp24
-rw-r--r--engines/titanic/game/wheel_spin.h7
-rw-r--r--engines/titanic/game_manager.cpp2
-rw-r--r--engines/titanic/game_state.cpp6
-rw-r--r--engines/titanic/game_state.h19
-rw-r--r--engines/titanic/gfx/edit_control.cpp4
-rw-r--r--engines/titanic/gfx/move_object_button.cpp15
-rw-r--r--engines/titanic/gfx/move_object_button.h2
-rw-r--r--engines/titanic/gfx/music_control.cpp31
-rw-r--r--engines/titanic/gfx/music_control.h10
-rw-r--r--engines/titanic/gfx/music_slider_pitch.cpp67
-rw-r--r--engines/titanic/gfx/music_slider_pitch.h14
-rw-r--r--engines/titanic/gfx/music_slider_speed.cpp67
-rw-r--r--engines/titanic/gfx/music_slider_speed.h38
-rw-r--r--engines/titanic/gfx/music_switch_inversion.cpp (renamed from engines/titanic/gfx/chev_switch.cpp)55
-rw-r--r--engines/titanic/gfx/music_switch_inversion.h14
-rw-r--r--engines/titanic/gfx/music_switch_reverse.cpp66
-rw-r--r--engines/titanic/gfx/music_switch_reverse.h38
-rw-r--r--engines/titanic/gfx/music_voice_mute.cpp59
-rw-r--r--engines/titanic/gfx/music_voice_mute.h4
-rw-r--r--engines/titanic/gfx/slider_button.cpp43
-rw-r--r--engines/titanic/gfx/slider_button.h6
-rw-r--r--engines/titanic/gfx/status_change_button.cpp11
-rw-r--r--engines/titanic/gfx/status_change_button.h2
-rw-r--r--engines/titanic/gfx/toggle_button.h2
-rw-r--r--engines/titanic/gfx/toggle_switch.cpp32
-rw-r--r--engines/titanic/gfx/toggle_switch.h6
-rw-r--r--engines/titanic/main_game_window.cpp30
-rw-r--r--engines/titanic/main_game_window.h5
-rw-r--r--engines/titanic/messages/messages.h14
-rw-r--r--engines/titanic/messages/pet_messages.h2
-rw-r--r--engines/titanic/messages/service_elevator_door.cpp10
-rw-r--r--engines/titanic/messages/service_elevator_door.h2
-rw-r--r--engines/titanic/module.mk11
-rw-r--r--engines/titanic/moves/enter_exit_mini_lift.cpp4
-rw-r--r--engines/titanic/moves/exit_arboretum.cpp2
-rw-r--r--engines/titanic/moves/move_player_in_parrot_room.cpp21
-rw-r--r--engines/titanic/moves/move_player_in_parrot_room.h3
-rw-r--r--engines/titanic/moves/move_player_to.cpp19
-rw-r--r--engines/titanic/moves/move_player_to.h3
-rw-r--r--engines/titanic/moves/move_player_to_from.cpp21
-rw-r--r--engines/titanic/moves/move_player_to_from.h6
-rw-r--r--engines/titanic/moves/multi_move.cpp28
-rw-r--r--engines/titanic/moves/multi_move.h8
-rw-r--r--engines/titanic/moves/pan_from_pel.cpp20
-rw-r--r--engines/titanic/moves/pan_from_pel.h6
-rw-r--r--engines/titanic/moves/restaurant_pan_handler.cpp30
-rw-r--r--engines/titanic/moves/restaurant_pan_handler.h11
-rw-r--r--engines/titanic/moves/restricted_move.cpp44
-rw-r--r--engines/titanic/moves/restricted_move.h5
-rw-r--r--engines/titanic/moves/scraliontis_table.cpp47
-rw-r--r--engines/titanic/moves/scraliontis_table.h12
-rw-r--r--engines/titanic/moves/trip_down_canal.cpp14
-rw-r--r--engines/titanic/moves/trip_down_canal.h2
-rw-r--r--engines/titanic/npcs/bellbot.cpp3
-rw-r--r--engines/titanic/npcs/doorbot.cpp6
-rw-r--r--engines/titanic/npcs/mobile.h2
-rw-r--r--engines/titanic/npcs/true_talk_npc.cpp29
-rw-r--r--engines/titanic/npcs/true_talk_npc.h13
-rw-r--r--engines/titanic/pet_control/pet_control.cpp11
-rw-r--r--engines/titanic/pet_control/pet_control.h6
-rw-r--r--engines/titanic/pet_control/pet_conversations.h20
-rw-r--r--engines/titanic/pet_control/pet_load_save.h10
-rw-r--r--engines/titanic/pet_control/pet_save.cpp20
-rw-r--r--engines/titanic/sound/music_room.h12
-rw-r--r--engines/titanic/sound/sound_manager.cpp8
-rw-r--r--engines/titanic/sound/sound_manager.h2
-rw-r--r--engines/titanic/sound/titania_speech.cpp8
-rw-r--r--engines/titanic/star_control/surface_fader.cpp6
-rw-r--r--engines/titanic/support/credit_text.cpp110
-rw-r--r--engines/titanic/support/credit_text.h6
-rw-r--r--engines/titanic/support/direct_draw.cpp12
-rw-r--r--engines/titanic/support/direct_draw.h6
-rw-r--r--engines/titanic/support/files_manager.cpp9
-rw-r--r--engines/titanic/support/files_manager.h7
-rw-r--r--engines/titanic/support/font.cpp61
-rw-r--r--engines/titanic/support/font.h6
-rw-r--r--engines/titanic/support/mouse_cursor.cpp8
-rw-r--r--engines/titanic/support/mouse_cursor.h7
-rw-r--r--engines/titanic/support/screen_manager.cpp23
-rw-r--r--engines/titanic/support/screen_manager.h20
-rw-r--r--engines/titanic/support/string_parser.cpp97
-rw-r--r--engines/titanic/support/string_parser.h76
-rw-r--r--engines/titanic/support/video_surface.cpp14
-rw-r--r--engines/titanic/true_talk/title_engine.cpp4
-rw-r--r--engines/titanic/true_talk/title_engine.h14
-rw-r--r--engines/titanic/true_talk/true_talk_manager.cpp8
-rw-r--r--engines/titanic/true_talk/true_talk_manager.h5
-rw-r--r--engines/titanic/true_talk/tt_npc_script.cpp8
-rw-r--r--engines/wage/design.cpp4
-rw-r--r--graphics/primitives.cpp10
378 files changed, 8997 insertions, 2250 deletions
diff --git a/backends/events/androidsdl/androidsdl-events.cpp b/backends/events/androidsdl/androidsdl-events.cpp
index bd8045ec62..7ea8ff1dc1 100644
--- a/backends/events/androidsdl/androidsdl-events.cpp
+++ b/backends/events/androidsdl/androidsdl-events.cpp
@@ -43,17 +43,16 @@ bool AndroidSdlEventSource::handleMouseButtonDown(SDL_Event &ev, Common::Event &
else if (ev.button.button == SDL_BUTTON_MIDDLE) {
event.type = Common::EVENT_MBUTTONDOWN;
- static int show_onscreen=0;
- if (show_onscreen==0) {
- SDL_ANDROID_SetScreenKeyboardShown(0);
- show_onscreen++;
+ static int show_onscreen = 0;
+ if (show_onscreen == 0) {
+ SDL_ANDROID_SetScreenKeyboardShown(0);
+ show_onscreen++;
+ } else if (show_onscreen==1) {
+ SDL_ANDROID_SetScreenKeyboardShown(1);
+ show_onscreen++;
}
- else if (show_onscreen==1) {
- SDL_ANDROID_SetScreenKeyboardShown(1);
- show_onscreen++;
- }
- if (show_onscreen==2)
- show_onscreen=0;
+ if (show_onscreen == 2)
+ show_onscreen = 0;
}
#endif
else
@@ -68,7 +67,9 @@ bool AndroidSdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
if (false) {}
if (ev.key.keysym.sym == SDLK_LCTRL) {
- ev.key.keysym.sym = SDLK_F5;
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd.keycode = Common::KEYCODE_F5;
+ return true;
} else {
// Let the events fall through if we didn't change them, this may not be the best way to
// set it up, but i'm not sure how sdl would like it if we let if fall through then redid it though.
diff --git a/devtools/create_titanic/create_titanic_dat.cpp b/devtools/create_titanic/create_titanic_dat.cpp
index 9186c1ce20..61e5de1149 100644
--- a/devtools/create_titanic/create_titanic_dat.cpp
+++ b/devtools/create_titanic/create_titanic_dat.cpp
@@ -285,6 +285,136 @@ static const FrameRange BARBOT_FRAME_RANGES[60] = {
{ 202, 281 }, { 182, 202 }, { 165, 182 }, { 96, 165 }, { 0, 95 }
};
+static const char *const MISSIVEOMAT_MESSAGES[3] = {
+ "Welcome, Leovinus.\n"
+ "\n"
+ "This is your Missive-O-Mat.\n"
+ "\n"
+ "You have received 1827 Electric Missives.\n"
+ "\n"
+ "For your convenience I have deleted:\n"
+ " 453 things that people you don't know thought it would be "
+ "terribly witty to forward to you,\n"
+ " 63 Missives containing double or triple exclamation marks,\n"
+ " 846 Missives from mailing-lists you once thought might be quite "
+ "interesting and now can't figure out how to cancel,\n"
+ " 962 Chain Missives,\n"
+ " 1034 instructions on how to become a millionaire using butter,\n"
+ " 3 Yassaccan Death Threats (slightly down on last week which is"
+ " pleasing news),\n"
+ " and a Missive from your Mother which I have answered reassuringly.\n"
+ "\n"
+ "I have selected the following Missives for your particular attention. "
+ "You will not need to run Fib-Finder to see why. Something Is Up and I "
+ "suspect those two slippery urchins Brobostigon and Scraliontis are behind it.",
+
+ "Hello Droot. I have evaluated your recent missives.\n"
+ "Contents break down as follows:\n"
+ "\n"
+ "Good news 49%\n"
+ "Bad news 48%\n"
+ "Indifferent news 4%\n"
+ "Petty mailings and Family Missives 5%\n"
+ "Special Offers from the Blerontin Sand Society 1% (note - there's"
+ " a rather pretty dune for hire on p4)\n"
+ "\n"
+ "In general terms you Thrive. You continue to Prosper. Your shares are"
+ " Secure. Your hair, as always, looks Good. Carpet 14 needs cleaning. \n"
+ "\n"
+ "I am pleased to report there have been no further comments about "
+ "foot odor.\n"
+ "\n"
+ "Recommend urgently you sell all fish paste shares as Market jittery.\n"
+ "\n"
+ "As your Great Scheme nears completion I have taken the liberty of"
+ " replying to all non-urgent Missives and list below only communic"
+ "ations with Manager Brobostigon and His Pain in the Ass Loftiness"
+ " Leovinus. \n"
+ "\n"
+ "Beware - Leovinus grows suspicious. Don't take your eye off B"
+ "robostigon. \n"
+ "\n"
+ "Weather for the Launch tomorrow is bright and sunny. Hazy clouds"
+ " will be turned on at eleven. I suggest the red suit with the st"
+ "reamers.\n"
+ "\n"
+ "All money transfers will be completed through alias accounts by m"
+ "oonsup.\n"
+ "\n"
+ "Eat well. Your fish levels are down and you may suffer indecisio"
+ "n flutters mid-morning.\n"
+ "\n"
+ "Here are your Missives...",
+
+ "Hello Antar, this is your Missive-o-Mat.\n"
+ "Not that you need reminding but today is the Glorious Dawning of "
+ "a New Age in Luxury Space Travel.\n"
+ "\n"
+ "Generally my assessment of your position this morning is that you"
+ " are well, albeit not as rich as you would like to be. I hope yo"
+ "ur interesting collaboration with Mr Scraliontis will soon bear f"
+ "ruit. \n"
+ "\n"
+ "I trust your flatulence has eased during the night. Such a distr"
+ "essing condition for a man in your position.\n"
+ "\n"
+ "Most of your Missives are routine construction matters which I ha"
+ "ve dealt with and deleted. All Missives from Mr Scraliontis and "
+ "His Loftiness Leovinus are here."
+};
+
+struct BedheadEntry {
+ const char *_name1;
+ const char *_name2;
+ const char *_name3;
+ const char *_name4;
+ int _startFrame;
+ int _endFrame;
+};
+
+static const BedheadEntry ON_CLOSED[4] = {
+ { "Closed", "Closed", "Open", "Open", 0, 12 },
+ { "Open", "Any", "Any", "RestingUTV", 0, 4 },
+ { "Closed", "Open", "Any", "RestingV", 0, 6 },
+ { "Closed", "Closed", "Closed", "RestingG", 0, 21 }
+};
+static const BedheadEntry ON_RESTING_TV[2] = {
+ { "Any", "Closed", "Open", "Open", 6, 12 },
+ { "Any", "Closed", "Closed", "RestingG", 6, 21 }
+};
+static const BedheadEntry ON_RESTING_UV[2] = {
+ { "Any", "Any", "Open", "Open", 8, 12 },
+ { "Any", "Any", "Closed", "RestingG", 8, 21 }
+};
+static const BedheadEntry ON_CLOSED_WRONG[2] = {
+ { "Any", "Any", "Closed", "OpenWrong", 42, 56 },
+ { "Any", "Any", "Open", "RestingDWrong", 42, 52 }
+};
+
+static const BedheadEntry OFF_OPEN[3] = {
+ { "Closed", "Closed", "Open", "Closed", 27, 41 },
+ { "Any", "Open", "Any", "RestingUV", 27, 29 },
+ { "Open", "Closed", "Any", "RestingTV", 27, 33 }
+};
+static const BedheadEntry OFF_RESTING_UTV[1] = {
+ { "Any", "Any", "Any", "Closed", 36, 41 }
+};
+static const BedheadEntry OFF_RESTING_V[1] = {
+ { "Closed", "Any", "Any", "Closed", 32, 41 }
+};
+static const BedheadEntry OFF_RESTING_G[3] = {
+ { "Closed", "Closed", "Closed", "Closed", 21, 41 },
+ { "Any", "Open", "Closed", "RestingUV", 21, 29 },
+ { "Open", "Closed", "Closed", "RestingTV", 21, 33 }
+};
+static const BedheadEntry OFF_OPEN_WRONG[1] = {
+ { "Any", "Any", "Any", "ClosedWrong", 56, 70 }
+};
+static const BedheadEntry OFF_RESTING_D_WRONG[1] = {
+ { "Any", "Any", "Any", "ClosedWrong", 59, 70 }
+};
+
+
void NORETURN_PRE error(const char *s, ...) {
printf("%s\n", s);
exit(1);
@@ -619,6 +749,86 @@ void writeBarbotFrameRanges() {
dataOffset += size;
}
+void writeMissiveOMatMessages() {
+ outputFile.seek(dataOffset);
+
+ for (int idx = 0; idx < 3; ++idx)
+ outputFile.writeString(MISSIVEOMAT_MESSAGES[idx]);
+
+ uint size = outputFile.size() - dataOffset;
+ writeEntryHeader("TEXT/MISSIVEOMAT/WELCOME", dataOffset, size);
+ dataOffset += size;
+
+ static const int MESSAGES[3] = { 0x5A63C0, 0x5A5BA8, 0x5A4A18 };
+ writeStringArray("TEXT/MISSIVEOMAT/MESSAGES", MESSAGES[_version], 58);
+ static const int FROM[3] = { 0x5A61F0, 0x5A59D8, 0x5A4BE8 };
+ writeStringArray("TEXT/MISSIVEOMAT/FROM", FROM[_version], 58);
+ static const int TO[3] = { 0x5A62D8, 0x5A5AC0, 0x5A4B00 };
+ writeStringArray("TEXT/MISSIVEOMAT/TO", TO[_version], 58);
+}
+
+void writeBedheadGroup(const BedheadEntry *data, int count) {
+ for (int idx = 0; idx < count; ++idx, ++data) {
+ outputFile.writeString(data->_name1);
+ outputFile.writeString(data->_name2);
+ outputFile.writeString(data->_name3);
+ outputFile.writeString(data->_name4);
+ outputFile.writeLong(data->_startFrame);
+ outputFile.writeLong(data->_endFrame);
+ }
+}
+
+void writeBedheadData() {
+ outputFile.seek(dataOffset);
+
+ writeBedheadGroup(ON_CLOSED, 4);
+ writeBedheadGroup(ON_RESTING_TV, 2);
+ writeBedheadGroup(ON_RESTING_UV, 2);
+ writeBedheadGroup(ON_CLOSED_WRONG, 2);
+ writeBedheadGroup(OFF_OPEN, 3);
+ writeBedheadGroup(OFF_RESTING_UTV, 1);
+ writeBedheadGroup(OFF_RESTING_V, 1);
+ writeBedheadGroup(OFF_RESTING_G, 3);
+ writeBedheadGroup(OFF_OPEN_WRONG, 1);
+ writeBedheadGroup(OFF_RESTING_D_WRONG, 1);
+
+ uint size = outputFile.size() - dataOffset;
+ writeEntryHeader("DATA/BEDHEAD", dataOffset, size);
+ dataOffset += size;
+}
+
+void writeParrotLobbyLinkUpdaterEntries() {
+ static const int OFFSETS[3] = { 0x5A5B38, 0x5A5320, 0x5A4360 };
+ static const int COUNTS[5] = { 7, 5, 6, 9, 1 };
+ static const int SKIP[5] = { 36, 36, 40, 36, 0 };
+ uint recordOffset = OFFSETS[_version], linkOffset;
+ byte vals[8];
+
+ outputFile.seek(dataOffset);
+
+ for (int groupNum = 0; groupNum < 4; ++groupNum) {
+ for (int entryNum = 0; entryNum < COUNTS[groupNum];
+ ++entryNum, recordOffset += 36) {
+ inputFile.seek(recordOffset - FILE_DIFF[_version]);
+ linkOffset = inputFile.readUint32LE();
+ for (int idx = 0; idx < 8; ++idx)
+ vals[idx] = inputFile.readUint32LE();
+
+ // Write out the entry
+ inputFile.seek(linkOffset - FILE_DIFF[_version]);
+ outputFile.writeString(inputFile);
+ outputFile.write(vals, 8);
+ }
+
+ // Skip space between groups
+ recordOffset += SKIP[groupNum];
+ }
+
+ uint size = outputFile.size() - dataOffset;
+ writeEntryHeader("DATA/PARROT_LOBBY_LINK_UPDATOR", dataOffset, size);
+ dataOffset += size;
+}
+
void writeHeader() {
// Write out magic string
const char *MAGIC_STR = "SVTN";
@@ -789,6 +999,9 @@ void writeData() {
writeAllUpdateStates();
writeAllScriptPreResponses();
writeBarbotFrameRanges();
+ writeMissiveOMatMessages();
+ writeBedheadData();
+ writeParrotLobbyLinkUpdaterEntries();
}
void createScriptMap() {
diff --git a/dists/msvc10/create_msvc10.bat b/dists/msvc10/create_msvc10.bat
index be0434fc50..53acbff42e 100644
--- a/dists/msvc10/create_msvc10.bat
+++ b/dists/msvc10/create_msvc10.bat
@@ -55,14 +55,14 @@ goto done
echo.
echo Creating project files with all engines enabled (stable and unstable)
echo.
-create_project ..\.. --enable-all-engines --msvc --msvc-version 10 --build-events
+create_project ..\.. --enable-all-engines --disable-fluidsynth --msvc --msvc-version 10 --build-events
goto done
:stable
echo.
echo Creating normal project files, with only the stable engines enabled
echo.
-create_project ..\.. --msvc --msvc-version 10
+create_project ..\.. --disable-fluidsynth --msvc --msvc-version 10
goto done
:tools
diff --git a/dists/msvc11/create_msvc11.bat b/dists/msvc11/create_msvc11.bat
index fc5471f46f..3c3052a5b0 100644
--- a/dists/msvc11/create_msvc11.bat
+++ b/dists/msvc11/create_msvc11.bat
@@ -55,14 +55,14 @@ goto done
echo.
echo Creating project files with all engines enabled (stable and unstable)
echo.
-create_project ..\.. --enable-all-engines --msvc --msvc-version 11 --build-events
+create_project ..\.. --enable-all-engines --disable-fluidsynth --msvc --msvc-version 11 --build-events
goto done
:stable
echo.
echo Creating normal project files, with only the stable engines enabled
echo.
-create_project ..\.. --msvc --msvc-version 11
+create_project ..\.. --disable-fluidsynth --msvc --msvc-version 11
goto done
:tools
diff --git a/dists/msvc12/create_msvc12.bat b/dists/msvc12/create_msvc12.bat
index d99001edb1..449b50ea54 100644
--- a/dists/msvc12/create_msvc12.bat
+++ b/dists/msvc12/create_msvc12.bat
@@ -55,14 +55,14 @@ goto done
echo.
echo Creating project files with all engines enabled (stable and unstable)
echo.
-create_project ..\.. --enable-all-engines --msvc --msvc-version 12 --build-events
+create_project ..\.. --enable-all-engines --disable-fluidsynth --msvc --msvc-version 12 --build-events
goto done
:stable
echo.
echo Creating normal project files, with only the stable engines enabled
echo.
-create_project ..\.. --msvc --msvc-version 12
+create_project ..\.. --disable-fluidsynth --msvc --msvc-version 12
goto done
:tools
diff --git a/dists/msvc9/create_msvc9.bat b/dists/msvc9/create_msvc9.bat
index 34bcccdd7b..005bc084db 100644
--- a/dists/msvc9/create_msvc9.bat
+++ b/dists/msvc9/create_msvc9.bat
@@ -55,14 +55,14 @@ goto done
echo.
echo Creating project files with all engines enabled (stable and unstable)
echo.
-create_project ..\.. --enable-all-engines --msvc --msvc-version 9
+create_project ..\.. --enable-all-engines --disable-fluidsynth --msvc --msvc-version 9
goto done
:stable
echo.
echo Creating normal project files, with only the stable engines enabled
echo.
-create_project ..\.. --msvc --msvc-version 9
+create_project ..\.. --disable-fluidsynth --msvc --msvc-version 9
goto done
:tools
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 19595606e1..9afb2c6700 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -402,6 +402,15 @@ byte AdlEngine::roomArg(byte room) const {
return room;
}
+void AdlEngine::loadDroppedItemOffsets(Common::ReadStream &stream, byte count) {
+ for (uint i = 0; i < count; ++i) {
+ Common::Point p;
+ p.x = stream.readByte();
+ p.y = stream.readByte();
+ _itemOffsets.push_back(p);
+ }
+}
+
void AdlEngine::clearScreen() const {
_display->setMode(DISPLAY_MODE_MIXED);
_display->clear(0x00);
@@ -1263,16 +1272,17 @@ Common::String AdlEngine::toAscii(const Common::String &str) {
}
Common::String AdlEngine::itemStr(uint i) const {
- byte desc = getItem(i).description;
- byte noun = getItem(i).noun;
+ const Item &item(getItem(i));
+
Common::String name = Common::String::format("%d", i);
- if (noun > 0) {
+ if (item.noun > 0) {
name += "/";
- name += _priNouns[noun - 1];
+ name += _priNouns[item.noun - 1];
}
- if (desc > 0) {
+ Common::String desc = getItemDescription(item);
+ if (!desc.empty()) {
name += "/";
- name += toAscii(loadMessage(desc));
+ name += toAscii(desc);
}
return name;
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 89cdabe384..971336ef50 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -247,6 +247,7 @@ protected:
virtual void initState();
virtual byte roomArg(byte room) const;
virtual void advanceClock() { }
+ void loadDroppedItemOffsets(Common::ReadStream &stream, byte count);
// Opcodes
int o1_isItemInRoom(ScriptEnv &e);
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index e18f3339f8..979d794146 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -359,9 +359,83 @@ DataBlockPtr AdlEngine_v2::readDataBlockPtr(Common::ReadStream &f) const {
if (track == 0 && sector == 0 && offset == 0 && size == 0)
return DataBlockPtr();
+ adjustDataBlockPtr(track, sector, offset, size);
+
return _disk->getDataBlock(track, sector, offset, size);
}
+void AdlEngine_v2::loadItems(Common::ReadStream &stream) {
+ byte id;
+ while ((id = stream.readByte()) != 0xff && !stream.eos() && !stream.err()) {
+ Item item = Item();
+ item.id = id;
+ item.noun = stream.readByte();
+ item.room = stream.readByte();
+ item.picture = stream.readByte();
+ item.isLineArt = stream.readByte(); // Disk number in later games
+ item.position.x = stream.readByte();
+ item.position.y = stream.readByte();
+ item.state = stream.readByte();
+ item.description = stream.readByte();
+
+ stream.readByte(); // Struct size
+
+ byte picListSize = stream.readByte();
+
+ // Flag to keep track of what has been drawn on the screen
+ stream.readByte();
+
+ for (uint i = 0; i < picListSize; ++i)
+ item.roomPictures.push_back(stream.readByte());
+
+ _state.items.push_back(item);
+ }
+
+ if (stream.eos() || stream.err())
+ error("Error loading items");
+}
+
+void AdlEngine_v2::loadRooms(Common::ReadStream &stream, byte count) {
+ for (uint i = 0; i < count; ++i) {
+ Room room;
+
+ stream.readByte(); // number
+ for (uint j = 0; j < 6; ++j)
+ room.connections[j] = stream.readByte();
+ room.data = readDataBlockPtr(stream);
+ room.picture = stream.readByte();
+ room.curPicture = stream.readByte();
+ room.isFirstTime = stream.readByte();
+
+ _state.rooms.push_back(room);
+ }
+
+ if (stream.eos() || stream.err())
+ error("Error loading rooms");
+}
+
+void AdlEngine_v2::loadMessages(Common::ReadStream &stream, byte count) {
+ for (uint i = 0; i < count; ++i)
+ _messages.push_back(readDataBlockPtr(stream));
+}
+
+void AdlEngine_v2::loadPictures(Common::ReadStream &stream) {
+ byte picNr;
+ while ((picNr = stream.readByte()) != 0xff) {
+ if (stream.eos() || stream.err())
+ error("Error reading global pic list");
+
+ _pictures[picNr] = readDataBlockPtr(stream);
+ }
+}
+
+void AdlEngine_v2::loadItemPictures(Common::ReadStream &stream, byte count) {
+ for (uint i = 0; i < count; ++i) {
+ stream.readByte(); // number
+ _itemPics.push_back(readDataBlockPtr(stream));
+ }
+}
+
int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
OP_DEBUG_0("\t&& IS_FIRST_TIME()");
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 4a473e9b1f..8f36b5cdb8 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -25,9 +25,6 @@
#include "adl/adl.h"
-// Note: this version of ADL redraws only when necessary, but
-// this is not currently implemented.
-
namespace Common {
class RandomSource;
}
@@ -55,6 +52,12 @@ protected:
void takeItem(byte noun);
virtual DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
+ virtual void adjustDataBlockPtr(byte &track, byte &sector, byte &offset, byte &size) const { }
+ void loadItems(Common::ReadStream &stream);
+ void loadRooms(Common::ReadStream &stream, byte count);
+ void loadMessages(Common::ReadStream &stream, byte count);
+ void loadPictures(Common::ReadStream &stream);
+ void loadItemPictures(Common::ReadStream &stream, byte count);
void checkTextOverflow(char c);
diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index 005478c376..ba9e4a063e 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -20,162 +20,50 @@
*
*/
-#include "common/random.h"
-#include "common/error.h"
-
#include "adl/adl_v3.h"
-#include "adl/display.h"
-#include "adl/graphics.h"
namespace Adl {
AdlEngine_v3::AdlEngine_v3(OSystem *syst, const AdlGameDescription *gd) :
- AdlEngine_v2(syst, gd),
- _curDisk(0) {
-}
-
-Common::String AdlEngine_v3::loadMessage(uint idx) const {
- Common::String str = AdlEngine_v2::loadMessage(idx);
-
- for (uint i = 0; i < str.size(); ++i) {
- const char *xorStr = "AVISDURGAN";
- str.setChar(str[i] ^ xorStr[i % strlen(xorStr)], i);
- }
-
- return str;
+ AdlEngine_v2(syst, gd) {
}
Common::String AdlEngine_v3::getItemDescription(const Item &item) const {
- return _itemDesc[item.id - 1];
+ return _itemDesc[item.description - 1];
}
-void AdlEngine_v3::applyDiskOffset(byte &track, byte &sector) const {
- sector += _diskOffsets[_curDisk].sector;
- if (sector >= 16) {
- sector -= 16;
- ++track;
- }
+void AdlEngine_v3::loadItemDescriptions(Common::SeekableReadStream &stream, byte count) {
+ int32 startPos = stream.pos();
+ uint16 baseAddr = stream.readUint16LE();
- track += _diskOffsets[_curDisk].track;
-}
-
-DataBlockPtr AdlEngine_v3::readDataBlockPtr(Common::ReadStream &f) const {
- byte track = f.readByte();
- byte sector = f.readByte();
- byte offset = f.readByte();
- byte size = f.readByte();
-
- if (f.eos() || f.err())
- error("Error reading DataBlockPtr");
+ // This code assumes that the first pointer points to a string that
+ // directly follows the pointer table
+ assert(baseAddr != 0);
+ baseAddr -= count * 2;
- if (track == 0 && sector == 0 && offset == 0 && size == 0)
- return DataBlockPtr();
+ for (uint i = 0; i < count; ++i) {
+ stream.seek(startPos + i * 2);
+ uint16 offset = stream.readUint16LE();
- applyDiskOffset(track, sector);
+ if (offset > 0) {
+ stream.seek(startPos + offset - baseAddr);
+ _itemDesc.push_back(readString(stream, 0xff));
+ } else
+ _itemDesc.push_back(Common::String());
+ }
- return _disk->getDataBlock(track, sector, offset, size);
+ if (stream.eos() || stream.err())
+ error("Error loading item descriptions");
}
typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine_v3> OpcodeV3;
-#define SetOpcodeTable(x) table = &x;
-#define Opcode(x) table->push_back(new OpcodeV3(this, &AdlEngine_v3::x))
-#define OpcodeUnImpl() table->push_back(new OpcodeV3(this, 0))
void AdlEngine_v3::setupOpcodeTables() {
- Common::Array<const Opcode *> *table = 0;
-
- SetOpcodeTable(_condOpcodes);
- // 0x00
- OpcodeUnImpl();
- Opcode(o2_isFirstTime);
- Opcode(o2_isRandomGT);
- Opcode(o3_isItemInRoom);
- // 0x04
- Opcode(o3_isNounNotInRoom);
- Opcode(o1_isMovesGT);
- Opcode(o1_isVarEQ);
- Opcode(o2_isCarryingSomething);
- // 0x08
- Opcode(o3_isVarGT);
- Opcode(o1_isCurPicEQ);
- Opcode(o3_skipOneCommand);
-
- SetOpcodeTable(_actOpcodes);
- // 0x00
- OpcodeUnImpl();
- Opcode(o1_varAdd);
- Opcode(o1_varSub);
- Opcode(o1_varSet);
- // 0x04
- Opcode(o1_listInv);
- Opcode(o3_moveItem);
- Opcode(o1_setRoom);
- Opcode(o2_setCurPic);
- // 0x08
- Opcode(o2_setPic);
- Opcode(o1_printMsg);
- Opcode(o3_dummy);
- Opcode(o3_setTextMode);
- // 0x0c
- Opcode(o2_moveAllItems);
- Opcode(o1_quit);
- Opcode(o3_dummy);
- Opcode(o2_save);
- // 0x10
- Opcode(o2_restore);
- Opcode(o1_restart);
- Opcode(o3_setDisk);
- Opcode(o3_dummy);
- // 0x14
- Opcode(o1_resetPic);
- Opcode(o1_goDirection<IDI_DIR_NORTH>);
- Opcode(o1_goDirection<IDI_DIR_SOUTH>);
- Opcode(o1_goDirection<IDI_DIR_EAST>);
- // 0x18
- Opcode(o1_goDirection<IDI_DIR_WEST>);
- Opcode(o1_goDirection<IDI_DIR_UP>);
- Opcode(o1_goDirection<IDI_DIR_DOWN>);
- Opcode(o1_takeItem);
- // 0x1c
- Opcode(o1_dropItem);
- Opcode(o1_setRoomPic);
- Opcode(o3_sound);
- OpcodeUnImpl();
- // 0x20
- Opcode(o2_initDisk);
-}
-
-int AdlEngine_v3::o3_isVarGT(ScriptEnv &e) {
- OP_DEBUG_2("\t&& VARS[%d] > %d", e.arg(1), e.arg(2));
-
- if (getVar(e.arg(1)) > e.arg(2))
- return 2;
-
- return -1;
-}
-
-int AdlEngine_v3::o3_skipOneCommand(ScriptEnv &e) {
- OP_DEBUG_0("\t&& SKIP_ONE_COMMAND()");
-
- _skipOneCommand = true;
- setVar(2, 0);
-
- return -1;
-}
-
-// FIXME: Rename "isLineArt" and look at code duplication
-int AdlEngine_v3::o3_isItemInRoom(ScriptEnv &e) {
- OP_DEBUG_2("\t&& GET_ITEM_ROOM(%s) == %s", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
-
- const Item &item = getItem(e.arg(1));
-
- if (e.arg(2) != IDI_ANY && item.isLineArt != _curDisk)
- return -1;
-
- if (item.room == roomArg(e.arg(2)))
- return 2;
-
- return -1;
+ AdlEngine_v2::setupOpcodeTables();
+ delete _condOpcodes[0x04];
+ _condOpcodes[0x04] = new OpcodeV3(this, &AdlEngine_v3::o3_isNounNotInRoom);
+ delete _actOpcodes[0x04];
+ _actOpcodes[0x04] = new OpcodeV3(this, &AdlEngine_v3::o3_listInv);
}
int AdlEngine_v3::o3_isNounNotInRoom(ScriptEnv &e) {
@@ -183,75 +71,28 @@ int AdlEngine_v3::o3_isNounNotInRoom(ScriptEnv &e) {
Common::List<Item>::const_iterator item;
- setVar(24, 0);
+ bool isAnItem = false;
- for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ for (item = _state.items.begin(); item != _state.items.end(); ++item) {
if (item->noun == e.getNoun()) {
- setVar(24, 1);
+ isAnItem = true;
if (item->room == roomArg(e.arg(1)))
return -1;
}
-
- return 1;
-}
-
-int AdlEngine_v3::o3_moveItem(ScriptEnv &e) {
- OP_DEBUG_2("\tSET_ITEM_ROOM(%s, %s)", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
-
- byte room = roomArg(e.arg(2));
-
- Item &item = getItem(e.arg(1));
-
- if (item.room == _roomOnScreen)
- _picOnScreen = 0;
-
- // Set items that move from inventory to a room to state "dropped"
- if (item.room == IDI_ANY && room != IDI_VOID_ROOM)
- item.state = IDI_ITEM_DROPPED;
-
- item.room = room;
- item.isLineArt = _curDisk;
- return 2;
-}
-
-int AdlEngine_v3::o3_dummy(ScriptEnv &e) {
- OP_DEBUG_0("\tDUMMY()");
-
- return 0;
-}
-
-int AdlEngine_v3::o3_setTextMode(ScriptEnv &e) {
- OP_DEBUG_1("\tSET_TEXT_MODE(%d)", e.arg(1));
-
- // TODO
- // 1: 4-line mode
- // 2: 24-line mode
-
- switch (e.arg(1)) {
- case 3:
- // We re-use the restarting flag here, to simulate a long jump
- _isRestarting = true;
- return -1;
}
- return 1;
+ return (isAnItem ? 1 : -1);
}
-int AdlEngine_v3::o3_setDisk(ScriptEnv &e) {
- OP_DEBUG_2("\tSET_DISK(%d, %d)", e.arg(1), e.arg(2));
-
- // TODO
- // Arg 1: disk
- // Arg 2: room
-
- return 2;
-}
+int AdlEngine_v3::o3_listInv(ScriptEnv &e) {
+ OP_DEBUG_0("\tLIST_INVENTORY()");
-int AdlEngine_v3::o3_sound(ScriptEnv &e) {
- OP_DEBUG_0("\tSOUND()");
+ Common::List<Item>::const_iterator item;
- // TODO
+ for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ if (item->room == IDI_ANY)
+ printString(_itemDesc[item->description - 1]);
return 0;
}
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index 61dd5852e7..b0d40f3993 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -25,18 +25,6 @@
#include "adl/adl_v2.h"
-// Note: this version of ADL redraws only when necessary, but
-// this is not currently implemented.
-
-namespace Common {
-class RandomSource;
-}
-
-struct DiskOffset {
- byte track;
- byte sector;
-};
-
namespace Adl {
class AdlEngine_v3 : public AdlEngine_v2 {
@@ -48,27 +36,14 @@ protected:
// AdlEngine
virtual void setupOpcodeTables();
- virtual Common::String loadMessage(uint idx) const;
Common::String getItemDescription(const Item &item) const;
- // AdlEngine_v2
- virtual DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
-
- void applyDiskOffset(byte &track, byte &sector) const;
+ void loadItemDescriptions(Common::SeekableReadStream &stream, byte count);
- int o3_isVarGT(ScriptEnv &e);
- int o3_isItemInRoom(ScriptEnv &e);
int o3_isNounNotInRoom(ScriptEnv &e);
- int o3_skipOneCommand(ScriptEnv &e);
- int o3_moveItem(ScriptEnv &e);
- int o3_dummy(ScriptEnv &e);
- int o3_setTextMode(ScriptEnv &e);
- int o3_setDisk(ScriptEnv &e);
- int o3_sound(ScriptEnv &e);
+ int o3_listInv(ScriptEnv &e);
Common::Array<Common::String> _itemDesc;
- byte _curDisk;
- Common::Array<DiskOffset> _diskOffsets;
};
} // End of namespace Adl
diff --git a/engines/adl/adl_v4.cpp b/engines/adl/adl_v4.cpp
new file mode 100644
index 0000000000..ed20c82513
--- /dev/null
+++ b/engines/adl/adl_v4.cpp
@@ -0,0 +1,258 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/random.h"
+#include "common/error.h"
+
+#include "adl/adl_v4.h"
+#include "adl/display.h"
+#include "adl/graphics.h"
+
+namespace Adl {
+
+AdlEngine_v4::AdlEngine_v4(OSystem *syst, const AdlGameDescription *gd) :
+ AdlEngine_v3(syst, gd),
+ _curDisk(0) {
+}
+
+Common::String AdlEngine_v4::loadMessage(uint idx) const {
+ Common::String str = AdlEngine_v2::loadMessage(idx);
+
+ for (uint i = 0; i < str.size(); ++i) {
+ const char *xorStr = "AVISDURGAN";
+ str.setChar(str[i] ^ xorStr[i % strlen(xorStr)], i);
+ }
+
+ return str;
+}
+
+Common::String AdlEngine_v4::getItemDescription(const Item &item) const {
+ return _itemDesc[item.id - 1];
+}
+
+void AdlEngine_v4::applyDiskOffset(byte &track, byte &sector) const {
+ sector += _diskOffsets[_curDisk].sector;
+ if (sector >= 16) {
+ sector -= 16;
+ ++track;
+ }
+
+ track += _diskOffsets[_curDisk].track;
+}
+
+void AdlEngine_v4::adjustDataBlockPtr(byte &track, byte &sector, byte &offset, byte &size) const {
+ applyDiskOffset(track, sector);
+}
+
+typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine_v4> OpcodeV4;
+#define SetOpcodeTable(x) table = &x;
+#define Opcode(x) table->push_back(new OpcodeV4(this, &AdlEngine_v4::x))
+#define OpcodeUnImpl() table->push_back(new OpcodeV4(this, 0))
+
+void AdlEngine_v4::setupOpcodeTables() {
+ Common::Array<const Opcode *> *table = 0;
+
+ SetOpcodeTable(_condOpcodes);
+ // 0x00
+ OpcodeUnImpl();
+ Opcode(o2_isFirstTime);
+ Opcode(o2_isRandomGT);
+ Opcode(o4_isItemInRoom);
+ // 0x04
+ Opcode(o4_isNounNotInRoom);
+ Opcode(o1_isMovesGT);
+ Opcode(o1_isVarEQ);
+ Opcode(o2_isCarryingSomething);
+ // 0x08
+ Opcode(o4_isVarGT);
+ Opcode(o1_isCurPicEQ);
+ Opcode(o4_skipOneCommand);
+
+ SetOpcodeTable(_actOpcodes);
+ // 0x00
+ OpcodeUnImpl();
+ Opcode(o1_varAdd);
+ Opcode(o1_varSub);
+ Opcode(o1_varSet);
+ // 0x04
+ Opcode(o4_listInv);
+ Opcode(o4_moveItem);
+ Opcode(o1_setRoom);
+ Opcode(o2_setCurPic);
+ // 0x08
+ Opcode(o2_setPic);
+ Opcode(o1_printMsg);
+ Opcode(o4_dummy);
+ Opcode(o4_setTextMode);
+ // 0x0c
+ Opcode(o2_moveAllItems);
+ Opcode(o1_quit);
+ Opcode(o4_dummy);
+ Opcode(o2_save);
+ // 0x10
+ Opcode(o2_restore);
+ Opcode(o1_restart);
+ Opcode(o4_setDisk);
+ Opcode(o4_dummy);
+ // 0x14
+ Opcode(o1_resetPic);
+ Opcode(o1_goDirection<IDI_DIR_NORTH>);
+ Opcode(o1_goDirection<IDI_DIR_SOUTH>);
+ Opcode(o1_goDirection<IDI_DIR_EAST>);
+ // 0x18
+ Opcode(o1_goDirection<IDI_DIR_WEST>);
+ Opcode(o1_goDirection<IDI_DIR_UP>);
+ Opcode(o1_goDirection<IDI_DIR_DOWN>);
+ Opcode(o1_takeItem);
+ // 0x1c
+ Opcode(o1_dropItem);
+ Opcode(o1_setRoomPic);
+ Opcode(o4_sound);
+ OpcodeUnImpl();
+ // 0x20
+ Opcode(o2_initDisk);
+}
+
+int AdlEngine_v4::o4_isVarGT(ScriptEnv &e) {
+ OP_DEBUG_2("\t&& VARS[%d] > %d", e.arg(1), e.arg(2));
+
+ if (getVar(e.arg(1)) > e.arg(2))
+ return 2;
+
+ return -1;
+}
+
+int AdlEngine_v4::o4_skipOneCommand(ScriptEnv &e) {
+ OP_DEBUG_0("\t&& SKIP_ONE_COMMAND()");
+
+ _skipOneCommand = true;
+ setVar(2, 0);
+
+ return -1;
+}
+
+// FIXME: Rename "isLineArt" and look at code duplication
+int AdlEngine_v4::o4_isItemInRoom(ScriptEnv &e) {
+ OP_DEBUG_2("\t&& GET_ITEM_ROOM(%s) == %s", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
+
+ const Item &item = getItem(e.arg(1));
+
+ if (e.arg(2) != IDI_ANY && item.isLineArt != _curDisk)
+ return -1;
+
+ if (item.room == roomArg(e.arg(2)))
+ return 2;
+
+ return -1;
+}
+
+int AdlEngine_v4::o4_isNounNotInRoom(ScriptEnv &e) {
+ OP_DEBUG_1("\t&& NO_SUCH_ITEMS_IN_ROOM(%s)", itemRoomStr(e.arg(1)).c_str());
+
+ Common::List<Item>::const_iterator item;
+
+ setVar(24, 0);
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ if (item->noun == e.getNoun()) {
+ setVar(24, 1);
+
+ if (item->room == roomArg(e.arg(1)))
+ return -1;
+ }
+
+ return 1;
+}
+
+int AdlEngine_v4::o4_listInv(ScriptEnv &e) {
+ OP_DEBUG_0("\tLIST_INVENTORY()");
+
+ Common::List<Item>::const_iterator item;
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ if (item->room == IDI_ANY)
+ printString(_itemDesc[item->id - 1]);
+
+ return 0;
+}
+
+int AdlEngine_v4::o4_moveItem(ScriptEnv &e) {
+ OP_DEBUG_2("\tSET_ITEM_ROOM(%s, %s)", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
+
+ byte room = roomArg(e.arg(2));
+
+ Item &item = getItem(e.arg(1));
+
+ if (item.room == _roomOnScreen)
+ _picOnScreen = 0;
+
+ // Set items that move from inventory to a room to state "dropped"
+ if (item.room == IDI_ANY && room != IDI_VOID_ROOM)
+ item.state = IDI_ITEM_DROPPED;
+
+ item.room = room;
+ item.isLineArt = _curDisk;
+ return 2;
+}
+
+int AdlEngine_v4::o4_dummy(ScriptEnv &e) {
+ OP_DEBUG_0("\tDUMMY()");
+
+ return 0;
+}
+
+int AdlEngine_v4::o4_setTextMode(ScriptEnv &e) {
+ OP_DEBUG_1("\tSET_TEXT_MODE(%d)", e.arg(1));
+
+ // TODO
+ // 1: 4-line mode
+ // 2: 24-line mode
+
+ switch (e.arg(1)) {
+ case 3:
+ // We re-use the restarting flag here, to simulate a long jump
+ _isRestarting = true;
+ return -1;
+ }
+
+ return 1;
+}
+
+int AdlEngine_v4::o4_setDisk(ScriptEnv &e) {
+ OP_DEBUG_2("\tSET_DISK(%d, %d)", e.arg(1), e.arg(2));
+
+ // TODO
+ // Arg 1: disk
+ // Arg 2: room
+
+ return 2;
+}
+
+int AdlEngine_v4::o4_sound(ScriptEnv &e) {
+ OP_DEBUG_0("\tSOUND()");
+
+ // TODO
+
+ return 0;
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/hires2.h b/engines/adl/adl_v4.h
index 50016725d6..79aa824d92 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/adl_v4.h
@@ -20,45 +20,52 @@
*
*/
-#ifndef ADL_HIRES2_H
-#define ADL_HIRES2_H
+#ifndef ADL_ADL_V4_H
+#define ADL_ADL_V4_H
-#include "common/str.h"
-
-#include "adl/adl_v2.h"
-#include "adl/disk.h"
+#include "adl/adl_v3.h"
namespace Common {
-class ReadStream;
-struct Point;
+class RandomSource;
}
+struct DiskOffset {
+ byte track;
+ byte sector;
+};
+
namespace Adl {
-#define IDS_HR2_DISK_IMAGE "WIZARD.DSK"
+class AdlEngine_v4 : public AdlEngine_v3 {
+public:
+ virtual ~AdlEngine_v4() { }
-#define IDI_HR2_NUM_ROOMS 135
-#define IDI_HR2_NUM_MESSAGES 255
-#define IDI_HR2_NUM_VARS 40
-#define IDI_HR2_NUM_ITEM_PICS 38
-#define IDI_HR2_NUM_ITEM_OFFSETS 16
+protected:
+ AdlEngine_v4(OSystem *syst, const AdlGameDescription *gd);
-// Messages used outside of scripts
-#define IDI_HR2_MSG_CANT_GO_THERE 123
-#define IDI_HR2_MSG_DONT_UNDERSTAND 19
-#define IDI_HR2_MSG_ITEM_DOESNT_MOVE 242
-#define IDI_HR2_MSG_ITEM_NOT_HERE 4
-#define IDI_HR2_MSG_THANKS_FOR_PLAYING 239
+ // AdlEngine
+ virtual void setupOpcodeTables();
+ virtual Common::String loadMessage(uint idx) const;
+ Common::String getItemDescription(const Item &item) const;
-class HiRes2Engine : public AdlEngine_v2 {
-public:
- HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd) { }
+ // AdlEngine_v2
+ virtual void adjustDataBlockPtr(byte &track, byte &sector, byte &offset, byte &size) const;
-private:
- // AdlEngine
- void runIntro() const;
- void init();
- void initGameState();
+ void applyDiskOffset(byte &track, byte &sector) const;
+
+ int o4_isVarGT(ScriptEnv &e);
+ int o4_isItemInRoom(ScriptEnv &e);
+ int o4_isNounNotInRoom(ScriptEnv &e);
+ int o4_skipOneCommand(ScriptEnv &e);
+ int o4_listInv(ScriptEnv &e);
+ int o4_moveItem(ScriptEnv &e);
+ int o4_dummy(ScriptEnv &e);
+ int o4_setTextMode(ScriptEnv &e);
+ int o4_setDisk(ScriptEnv &e);
+ int o4_sound(ScriptEnv &e);
+
+ byte _curDisk;
+ Common::Array<DiskOffset> _diskOffsets;
};
} // End of namespace Adl
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index af51f95fe7..10812d79ea 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -76,6 +76,7 @@ static const PlainGameDescriptor adlGames[] = {
{ "hires0", "Hi-Res Adventure #0: Mission Asteroid" },
{ "hires1", "Hi-Res Adventure #1: Mystery House" },
{ "hires2", "Hi-Res Adventure #2: Wizard and the Princess" },
+ { "hires4", "Hi-Res Adventure #4: Ulysses and the Golden Fleece" },
{ "hires6", "Hi-Res Adventure #6: The Dark Crystal" },
{ 0, 0 }
};
@@ -92,7 +93,7 @@ static const AdlGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformApple2,
- ADGF_UNSTABLE,
+ ADGF_TESTING,
GUIO2(GAMEOPTION_COLOR_DEFAULT_OFF, GAMEOPTION_SCANLINES)
},
GAME_TYPE_HIRES1
@@ -106,7 +107,7 @@ static const AdlGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformApple2,
- ADGF_UNSTABLE,
+ ADGF_TESTING,
GUIO2(GAMEOPTION_COLOR_DEFAULT_OFF, GAMEOPTION_SCANLINES)
},
GAME_TYPE_HIRES1
@@ -120,7 +121,7 @@ static const AdlGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformApple2,
- ADGF_UNSTABLE,
+ ADGF_TESTING,
GUIO2(GAMEOPTION_COLOR_DEFAULT_ON, GAMEOPTION_SCANLINES)
},
GAME_TYPE_HIRES2
@@ -134,11 +135,26 @@ static const AdlGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformApple2,
- ADGF_UNSTABLE,
+ ADGF_TESTING,
GUIO2(GAMEOPTION_COLOR_DEFAULT_ON, GAMEOPTION_SCANLINES)
},
GAME_TYPE_HIRES0
},
+ { // Hi-Res Adventure #4: Ulysses and the Golden Fleece - Atari 8-bit - Re-release
+ {
+ "hires4", 0,
+ {
+ { "ULYS1A.XFD", 0, "26365d2b06509fd21e7a7919e33f7199", 92160 },
+ // FIXME: Add sides 1B and 2C
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformAtariST, // FIXME
+ ADGF_UNSTABLE,
+ GUIO2(GAMEOPTION_COLOR_DEFAULT_ON, GAMEOPTION_SCANLINES)
+ },
+ GAME_TYPE_HIRES4
+ },
{ // Hi-Res Adventure #6: The Dark Crystal - Apple II - Roberta Williams Anthology
{
"hires6", 0,
@@ -298,6 +314,7 @@ void AdlMetaEngine::removeSaveState(const char *target, int slot) const {
Engine *HiRes1Engine_create(OSystem *syst, const AdlGameDescription *gd);
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd);
Engine *HiRes0Engine_create(OSystem *syst, const AdlGameDescription *gd);
+Engine *HiRes4Engine_create(OSystem *syst, const AdlGameDescription *gd);
Engine *HiRes6Engine_create(OSystem *syst, const AdlGameDescription *gd);
bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
@@ -316,6 +333,9 @@ bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameD
case GAME_TYPE_HIRES0:
*engine = HiRes0Engine_create(syst, adlGd);
break;
+ case GAME_TYPE_HIRES4:
+ *engine = HiRes4Engine_create(syst, adlGd);
+ break;
case GAME_TYPE_HIRES6:
*engine = HiRes6Engine_create(syst, adlGd);
break;
diff --git a/engines/adl/detection.h b/engines/adl/detection.h
index 533466c094..b4dc3c430f 100644
--- a/engines/adl/detection.h
+++ b/engines/adl/detection.h
@@ -35,6 +35,7 @@ enum GameType {
GAME_TYPE_HIRES0,
GAME_TYPE_HIRES1,
GAME_TYPE_HIRES2,
+ GAME_TYPE_HIRES4,
GAME_TYPE_HIRES6
};
diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index 49e01f9d0f..d429556670 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -28,15 +28,7 @@
namespace Adl {
-#define TRACKS 35
-// The Apple II uses either 13- or 16-sector disks. We currently pad out
-// 13-sector disks, so we set SECTORS_PER_TRACK to 16 here.
-#define SECTORS_PER_TRACK 16
-#define BYTES_PER_SECTOR 256
-#define RAW_IMAGE_SIZE(S) (TRACKS * (S) * BYTES_PER_SECTOR)
-#define NIB_IMAGE_SIZE (RAW_IMAGE_SIZE(13) * 2)
-
-static Common::SeekableReadStream *readImage_DSK(const Common::String &filename) {
+static Common::SeekableReadStream *readImage(const Common::String &filename) {
Common::File *f = new Common::File;
if (!f->open(filename)) {
@@ -44,9 +36,6 @@ static Common::SeekableReadStream *readImage_DSK(const Common::String &filename)
return nullptr;
}
- if (f->size() != RAW_IMAGE_SIZE(16))
- error("Unrecognized DSK image '%s' of size %d bytes", filename.c_str(), f->size());
-
return f;
}
@@ -63,7 +52,7 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
if (!f.open(filename))
return nullptr;
- if (f.size() != NIB_IMAGE_SIZE)
+ if (f.size() != 232960)
error("Unrecognized NIB image '%s' of size %d bytes", filename.c_str(), f.size());
// starting at 0xaa, 32 is invalid (see below)
@@ -73,7 +62,9 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
// we always pad it out
const uint sectorsPerTrack = 16;
- byte *diskImage = (byte *)calloc(RAW_IMAGE_SIZE(sectorsPerTrack), 1);
+ const uint bytesPerSector = 256;
+ const uint imageSize = 35 * sectorsPerTrack * bytesPerSector;
+ byte *const diskImage = (byte *)calloc(imageSize, 1);
bool sawAddress = false;
uint8 volNo, track, sector;
@@ -120,13 +111,13 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
// We should always find the data field after an address field.
// TODO: we ignore volNo?
- byte *output = diskImage + (track * sectorsPerTrack + sector) * BYTES_PER_SECTOR;
+ byte *output = diskImage + (track * sectorsPerTrack + sector) * bytesPerSector;
if (newStyle) {
// We hardcode the DOS 3.3 mapping here. TODO: Do we also need raw/prodos?
int raw2dos[16] = { 0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15 };
sector = raw2dos[sector];
- output = diskImage + (track * sectorsPerTrack + sector) * BYTES_PER_SECTOR;
+ output = diskImage + (track * sectorsPerTrack + sector) * bytesPerSector;
// 6-and-2 uses 342 on-disk bytes
byte inbuffer[342];
@@ -216,42 +207,65 @@ static Common::SeekableReadStream *readImage_NIB(const Common::String &filename)
}
}
- return new Common::MemoryReadStream(diskImage, RAW_IMAGE_SIZE(sectorsPerTrack), DisposeAfterUse::YES);
+ return new Common::MemoryReadStream(diskImage, imageSize, DisposeAfterUse::YES);
}
bool DiskImage::open(const Common::String &filename) {
Common::String lcName(filename);
lcName.toLowercase();
- if (lcName.hasSuffix(".dsk"))
- _stream = readImage_DSK(filename);
- else if (lcName.hasSuffix(".nib"))
+ if (lcName.hasSuffix(".dsk")) {
+ _stream = readImage(filename);
+ _tracks = 35;
+ _sectorsPerTrack = 16;
+ _bytesPerSector = 256;
+ } else if (lcName.hasSuffix(".nib")) {
_stream = readImage_NIB(filename);
+ _tracks = 35;
+ _sectorsPerTrack = 16;
+ _bytesPerSector = 256;
+ } else if (lcName.hasSuffix(".xfd")) {
+ _stream = readImage(filename);
+ _tracks = 40;
+ _sectorsPerTrack = 18;
+ _bytesPerSector = 128;
+ }
+
+ int expectedSize = _tracks * _sectorsPerTrack * _bytesPerSector;
+
+ if (!_stream)
+ return false;
+
+ if (_stream->size() != expectedSize)
+ error("Unrecognized disk image '%s' of size %d bytes (expected %d bytes)", filename.c_str(), _stream->size(), expectedSize);
- return _stream != nullptr;
+ return true;
}
const DataBlockPtr DiskImage::getDataBlock(uint track, uint sector, uint offset, uint size) const {
- return DataBlockPtr(new DiskImage::DataBlock(this, track, sector, offset, size, _mode13));
+ return DataBlockPtr(new DiskImage::DataBlock(this, track, sector, offset, size, _sectorLimit));
}
-Common::SeekableReadStream *DiskImage::createReadStream(uint track, uint sector, uint offset, uint size, uint sectorsPerTrackToRead) const {
- const uint bytesToRead = size * BYTES_PER_SECTOR + BYTES_PER_SECTOR - offset;
+Common::SeekableReadStream *DiskImage::createReadStream(uint track, uint sector, uint offset, uint size, uint sectorLimit) const {
+ const uint bytesToRead = size * _bytesPerSector + _bytesPerSector - offset;
byte *const data = (byte *)malloc(bytesToRead);
uint dataOffset = 0;
- if (sector > sectorsPerTrackToRead - 1)
- error("Sector %i is out of bounds for %i-sector reading", sector, sectorsPerTrackToRead);
+ if (sectorLimit == 0)
+ sectorLimit = _sectorsPerTrack;
+
+ if (sector >= sectorLimit)
+ error("Sector %i is out of bounds for %i-sector reading", sector, sectorLimit);
while (dataOffset < bytesToRead) {
- uint bytesRemInTrack = (sectorsPerTrackToRead - 1 - sector) * BYTES_PER_SECTOR + BYTES_PER_SECTOR - offset;
- _stream->seek((track * SECTORS_PER_TRACK + sector) * BYTES_PER_SECTOR + offset);
+ uint bytesRemInTrack = (sectorLimit - 1 - sector) * _bytesPerSector + _bytesPerSector - offset;
+ _stream->seek((track * _sectorsPerTrack + sector) * _bytesPerSector + offset);
if (bytesToRead - dataOffset < bytesRemInTrack)
bytesRemInTrack = bytesToRead - dataOffset;
if (_stream->read(data + dataOffset, bytesRemInTrack) < bytesRemInTrack)
- error("Error reading disk image");
+ error("Error reading disk image at track %d; sector %d", track, sector);
++track;
diff --git a/engines/adl/disk.h b/engines/adl/disk.h
index 1041f0cebd..653d76ff10 100644
--- a/engines/adl/disk.h
+++ b/engines/adl/disk.h
@@ -74,7 +74,10 @@ class DiskImage {
public:
DiskImage() :
_stream(nullptr),
- _mode13(false) { }
+ _tracks(0),
+ _sectorsPerTrack(0),
+ _bytesPerSector(0),
+ _sectorLimit(0) { }
~DiskImage() {
delete _stream;
@@ -82,32 +85,33 @@ public:
bool open(const Common::String &filename);
const DataBlockPtr getDataBlock(uint track, uint sector, uint offset = 0, uint size = 0) const;
- Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0, uint sectorsPerTrackToRead = 16) const;
- void setMode13(bool enable) { _mode13 = enable; }
+ Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0, uint sectorsUsed = 0) const;
+ void setSectorLimit(uint sectorLimit) { _sectorLimit = sectorLimit; } // Maximum number of sectors to read per track before stepping
protected:
class DataBlock : public Adl::DataBlock {
public:
- DataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size, bool mode13) :
+ DataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size, uint sectorLimit) :
_track(track),
_sector(sector),
_offset(offset),
_size(size),
- _mode13(mode13),
+ _sectorLimit(sectorLimit),
_disk(disk) { }
Common::SeekableReadStream *createReadStream() const {
- return _disk->createReadStream(_track, _sector, _offset, _size, (_mode13 ? 13 : 16));
+ return _disk->createReadStream(_track, _sector, _offset, _size, _sectorLimit);
}
private:
uint _track, _sector, _offset, _size;
- bool _mode13;
+ uint _sectorLimit;
const DiskImage *_disk;
};
Common::SeekableReadStream *_stream;
- bool _mode13; // Older 13-sector format
+ uint _tracks, _sectorsPerTrack, _bytesPerSector;
+ uint _sectorLimit;
};
// Data in plain files
diff --git a/engines/adl/hires0.cpp b/engines/adl/hires0.cpp
index 316f77a9b6..9a0af05d20 100644
--- a/engines/adl/hires0.cpp
+++ b/engines/adl/hires0.cpp
@@ -1,168 +1,143 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/textconsole.h"
-
-#include "adl/hires0.h"
-#include "adl/graphics.h"
-#include "adl/disk.h"
-
-namespace Adl {
-
-void HiRes0Engine::init() {
- _graphics = new Graphics_v2(*_display);
-
- _disk = new DiskImage();
- if (!_disk->open(IDS_HR0_DISK_IMAGE))
- error("Failed to open disk image '" IDS_HR0_DISK_IMAGE "'");
-
- _disk->setMode13(true);
-
- StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x00, 2));
-
- // TODO: all these strings/offsets/etc are the same as hires2
-
- for (uint i = 0; i < IDI_HR0_NUM_MESSAGES; ++i)
- _messages.push_back(readDataBlockPtr(*stream));
-
- // Read parser messages
- stream.reset(_disk->createReadStream(0x1a, 0x1));
- _strings.verbError = readStringAt(*stream, 0x4f);
- _strings.nounError = readStringAt(*stream, 0x8e);
- _strings.enterCommand = readStringAt(*stream, 0xbc);
-
- // Read time string
- stream.reset(_disk->createReadStream(0x19, 0x7, 0xd7));
- _strings_v2.time = readString(*stream, 0xff);
-
- // Read line feeds
- stream.reset(_disk->createReadStream(0x19, 0xb, 0xf8, 1));
- _strings.lineFeeds = readString(*stream);
-
- // Read opcode strings
- stream.reset(_disk->createReadStream(0x1a, 0x6, 0x00, 2));
- _strings_v2.saveInsert = readStringAt(*stream, 0x5f);
- _strings_v2.saveReplace = readStringAt(*stream, 0xe5);
- _strings_v2.restoreInsert = readStringAt(*stream, 0x132);
- _strings_v2.restoreReplace = readStringAt(*stream, 0x1c2);
- _strings.playAgain = readStringAt(*stream, 0x225);
- _strings.pressReturn = readStringAt(*stream, 0x25f);
-
- _messageIds.cantGoThere = IDI_HR0_MSG_CANT_GO_THERE;
- _messageIds.dontUnderstand = IDI_HR0_MSG_DONT_UNDERSTAND;
- _messageIds.itemDoesntMove = IDI_HR0_MSG_ITEM_DOESNT_MOVE;
- _messageIds.itemNotHere = IDI_HR0_MSG_ITEM_NOT_HERE;
- _messageIds.thanksForPlaying = IDI_HR0_MSG_THANKS_FOR_PLAYING;
-
- // Load global picture data
- stream.reset(_disk->createReadStream(0x19, 0xa, 0x80, 0));
- byte picNr;
- while ((picNr = stream->readByte()) != 0xff) {
- if (stream->eos() || stream->err())
- error("Error reading global pic list");
-
- _pictures[picNr] = readDataBlockPtr(*stream);
- }
-
- // Load item picture data
- stream.reset(_disk->createReadStream(0x1e, 0x9, 0x05));
- for (uint i = 0; i < IDI_HR0_NUM_ITEM_PICS; ++i) {
- stream->readByte(); // number
- _itemPics.push_back(readDataBlockPtr(*stream));
- }
-
- // Load commands from executable
- stream.reset(_disk->createReadStream(0x1d, 0x7, 0x00, 2));
- readCommands(*stream, _roomCommands);
-
- stream.reset(_disk->createReadStream(0x1f, 0x7, 0x00, 3));
- readCommands(*stream, _globalCommands);
-
- // Load dropped item offsets
- stream.reset(_disk->createReadStream(0x1b, 0x4, 0x15));
- for (uint i = 0; i < IDI_HR0_NUM_ITEM_OFFSETS; ++i) {
- Common::Point p;
- p.x = stream->readByte();
- p.y = stream->readByte();
- _itemOffsets.push_back(p);
- }
-
- // Load verbs
- stream.reset(_disk->createReadStream(0x19, 0x0, 0x00, 3));
- loadWords(*stream, _verbs, _priVerbs);
-
- // Load nouns
- stream.reset(_disk->createReadStream(0x22, 0x2, 0x00, 2));
- loadWords(*stream, _nouns, _priNouns);
-}
-
-void HiRes0Engine::initGameState() {
- _state.vars.resize(IDI_HR0_NUM_VARS);
-
- StreamPtr stream(_disk->createReadStream(0x21, 0x5, 0x0e, 2));
-
- for (uint i = 0; i < IDI_HR0_NUM_ROOMS; ++i) {
- Room room;
- stream->readByte(); // number
- for (uint j = 0; j < 6; ++j)
- room.connections[j] = stream->readByte();
- room.data = readDataBlockPtr(*stream);
- room.picture = stream->readByte();
- room.curPicture = stream->readByte();
- room.isFirstTime = stream->readByte();
- _state.rooms.push_back(room);
- }
-
- stream.reset(_disk->createReadStream(0x21, 0x0));
-
- byte id;
- while ((id = stream->readByte()) != 0xff) {
- Item item = Item();
- item.id = id;
- item.noun = stream->readByte();
- item.room = stream->readByte();
- item.picture = stream->readByte();
- item.isLineArt = stream->readByte();
- item.position.x = stream->readByte();
- item.position.y = stream->readByte();
- item.state = stream->readByte();
- item.description = stream->readByte();
-
- stream->readByte(); // Struct size
-
- byte picListSize = stream->readByte();
-
- // Flag to keep track of what has been drawn on the screen
- stream->readByte();
-
- for (uint i = 0; i < picListSize; ++i)
- item.roomPictures.push_back(stream->readByte());
-
- _state.items.push_back(item);
- }
-}
-
-Engine *HiRes0Engine_create(OSystem *syst, const AdlGameDescription *gd) {
- return new HiRes0Engine(syst, gd);
-}
-
-} // End of namespace Adl
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/textconsole.h"
+
+#include "adl/adl_v2.h"
+#include "adl/graphics.h"
+#include "adl/disk.h"
+
+namespace Adl {
+
+#define IDS_HR0_DISK_IMAGE "MISSION.NIB"
+
+#define IDI_HR0_NUM_ROOMS 43
+#define IDI_HR0_NUM_MESSAGES 142
+#define IDI_HR0_NUM_VARS 40
+#define IDI_HR0_NUM_ITEM_PICS 2
+#define IDI_HR0_NUM_ITEM_OFFSETS 16
+
+// Messages used outside of scripts
+#define IDI_HR0_MSG_CANT_GO_THERE 110
+#define IDI_HR0_MSG_DONT_UNDERSTAND 112
+#define IDI_HR0_MSG_ITEM_DOESNT_MOVE 114
+#define IDI_HR0_MSG_ITEM_NOT_HERE 115
+#define IDI_HR0_MSG_THANKS_FOR_PLAYING 113
+
+class HiRes0Engine : public AdlEngine_v2 {
+public:
+ HiRes0Engine(OSystem *syst, const AdlGameDescription *gd) :
+ AdlEngine_v2(syst, gd) { }
+ ~HiRes0Engine() { }
+
+private:
+ // AdlEngine
+ void init();
+ void initGameState();
+};
+
+void HiRes0Engine::init() {
+ _graphics = new Graphics_v2(*_display);
+
+ _disk = new DiskImage();
+ if (!_disk->open(IDS_HR0_DISK_IMAGE))
+ error("Failed to open disk image '" IDS_HR0_DISK_IMAGE "'");
+
+ _disk->setSectorLimit(13);
+
+ // TODO: all these strings/offsets/etc are the same as hires2
+
+ StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x00, 2));
+ loadMessages(*stream, IDI_HR0_NUM_MESSAGES);
+
+ // Read parser messages
+ stream.reset(_disk->createReadStream(0x1a, 0x1));
+ _strings.verbError = readStringAt(*stream, 0x4f);
+ _strings.nounError = readStringAt(*stream, 0x8e);
+ _strings.enterCommand = readStringAt(*stream, 0xbc);
+
+ // Read time string
+ stream.reset(_disk->createReadStream(0x19, 0x7, 0xd7));
+ _strings_v2.time = readString(*stream, 0xff);
+
+ // Read line feeds
+ stream.reset(_disk->createReadStream(0x19, 0xb, 0xf8, 1));
+ _strings.lineFeeds = readString(*stream);
+
+ // Read opcode strings
+ stream.reset(_disk->createReadStream(0x1a, 0x6, 0x00, 2));
+ _strings_v2.saveInsert = readStringAt(*stream, 0x5f);
+ _strings_v2.saveReplace = readStringAt(*stream, 0xe5);
+ _strings_v2.restoreInsert = readStringAt(*stream, 0x132);
+ _strings_v2.restoreReplace = readStringAt(*stream, 0x1c2);
+ _strings.playAgain = readStringAt(*stream, 0x225);
+ _strings.pressReturn = readStringAt(*stream, 0x25f);
+
+ _messageIds.cantGoThere = IDI_HR0_MSG_CANT_GO_THERE;
+ _messageIds.dontUnderstand = IDI_HR0_MSG_DONT_UNDERSTAND;
+ _messageIds.itemDoesntMove = IDI_HR0_MSG_ITEM_DOESNT_MOVE;
+ _messageIds.itemNotHere = IDI_HR0_MSG_ITEM_NOT_HERE;
+ _messageIds.thanksForPlaying = IDI_HR0_MSG_THANKS_FOR_PLAYING;
+
+ // Load global picture data
+ stream.reset(_disk->createReadStream(0x19, 0xa, 0x80, 0));
+ loadPictures(*stream);
+
+ // Load item picture data
+ stream.reset(_disk->createReadStream(0x1e, 0x9, 0x05));
+ loadItemPictures(*stream, IDI_HR0_NUM_ITEM_PICS);
+
+ // Load commands from executable
+ stream.reset(_disk->createReadStream(0x1d, 0x7, 0x00, 2));
+ readCommands(*stream, _roomCommands);
+
+ stream.reset(_disk->createReadStream(0x1f, 0x7, 0x00, 3));
+ readCommands(*stream, _globalCommands);
+
+ // Load dropped item offsets
+ stream.reset(_disk->createReadStream(0x1b, 0x4, 0x15));
+ loadDroppedItemOffsets(*stream, IDI_HR0_NUM_ITEM_OFFSETS);
+
+ // Load verbs
+ stream.reset(_disk->createReadStream(0x19, 0x0, 0x00, 3));
+ loadWords(*stream, _verbs, _priVerbs);
+
+ // Load nouns
+ stream.reset(_disk->createReadStream(0x22, 0x2, 0x00, 2));
+ loadWords(*stream, _nouns, _priNouns);
+}
+
+void HiRes0Engine::initGameState() {
+ _state.vars.resize(IDI_HR0_NUM_VARS);
+
+ StreamPtr stream(_disk->createReadStream(0x21, 0x5, 0x0e, 2));
+ loadRooms(*stream, IDI_HR0_NUM_ROOMS);
+
+ stream.reset(_disk->createReadStream(0x21, 0x0));
+ loadItems(*stream);
+}
+
+Engine *HiRes0Engine_create(OSystem *syst, const AdlGameDescription *gd) {
+ return new HiRes0Engine(syst, gd);
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 26565c03c3..217a9013ba 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -27,11 +27,105 @@
#include "common/stream.h"
#include "common/ptr.h"
-#include "adl/hires1.h"
+#include "adl/adl.h"
+#include "adl/graphics.h"
#include "adl/display.h"
namespace Adl {
+#define IDS_HR1_EXE_0 "AUTO LOAD OBJ"
+#define IDS_HR1_EXE_1 "ADVENTURE"
+#define IDS_HR1_LOADER "MYSTERY.HELLO"
+#define IDS_HR1_MESSAGES "MESSAGES"
+
+#define IDI_HR1_NUM_ROOMS 41
+#define IDI_HR1_NUM_PICS 97
+#define IDI_HR1_NUM_VARS 20
+#define IDI_HR1_NUM_ITEM_OFFSETS 21
+#define IDI_HR1_NUM_MESSAGES 168
+
+// Messages used outside of scripts
+#define IDI_HR1_MSG_CANT_GO_THERE 137
+#define IDI_HR1_MSG_DONT_UNDERSTAND 37
+#define IDI_HR1_MSG_ITEM_DOESNT_MOVE 151
+#define IDI_HR1_MSG_ITEM_NOT_HERE 152
+#define IDI_HR1_MSG_THANKS_FOR_PLAYING 140
+#define IDI_HR1_MSG_DONT_HAVE_IT 127
+#define IDI_HR1_MSG_GETTING_DARK 7
+
+#define IDI_HR1_OFS_STR_ENTER_COMMAND 0x5bbc
+#define IDI_HR1_OFS_STR_VERB_ERROR 0x5b4f
+#define IDI_HR1_OFS_STR_NOUN_ERROR 0x5b8e
+#define IDI_HR1_OFS_STR_PLAY_AGAIN 0x5f1e
+#define IDI_HR1_OFS_STR_CANT_GO_THERE 0x6c0a
+#define IDI_HR1_OFS_STR_DONT_HAVE_IT 0x6c31
+#define IDI_HR1_OFS_STR_DONT_UNDERSTAND 0x6c51
+#define IDI_HR1_OFS_STR_GETTING_DARK 0x6c7c
+#define IDI_HR1_OFS_STR_PRESS_RETURN 0x5f68
+#define IDI_HR1_OFS_STR_LINE_FEEDS 0x59d4
+
+#define IDI_HR1_OFS_PD_TEXT_0 0x005d
+#define IDI_HR1_OFS_PD_TEXT_1 0x012b
+#define IDI_HR1_OFS_PD_TEXT_2 0x016d
+#define IDI_HR1_OFS_PD_TEXT_3 0x0259
+
+#define IDI_HR1_OFS_INTRO_TEXT 0x0066
+#define IDI_HR1_OFS_GAME_OR_HELP 0x000f
+
+#define IDI_HR1_OFS_LOGO_0 0x1003
+#define IDI_HR1_OFS_LOGO_1 0x1800
+
+#define IDI_HR1_OFS_ITEMS 0x0100
+#define IDI_HR1_OFS_ROOMS 0x050a
+#define IDI_HR1_OFS_PICS 0x4b03
+#define IDI_HR1_OFS_CMDS_0 0x3c00
+#define IDI_HR1_OFS_CMDS_1 0x3d00
+#define IDI_HR1_OFS_MSGS 0x4d00
+
+#define IDI_HR1_OFS_ITEM_OFFSETS 0x68ff
+#define IDI_HR1_OFS_CORNERS 0x4f00
+
+#define IDI_HR1_OFS_VERBS 0x3800
+#define IDI_HR1_OFS_NOUNS 0x0f00
+
+class HiRes1Engine : public AdlEngine {
+public:
+ HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) :
+ AdlEngine(syst, gd),
+ _files(nullptr),
+ _messageDelay(true) { }
+ ~HiRes1Engine() { delete _files; }
+
+private:
+ // AdlEngine
+ void runIntro() const;
+ void init();
+ void initGameState();
+ void restartGame();
+ void printString(const Common::String &str);
+ Common::String loadMessage(uint idx) const;
+ void printMessage(uint idx);
+ void drawItems();
+ void drawItem(Item &item, const Common::Point &pos);
+ void loadRoom(byte roomNr);
+ void showRoom();
+
+ void wordWrap(Common::String &str) const;
+
+ Files *_files;
+ Common::File _exe;
+ Common::Array<DataBlockPtr> _corners;
+ Common::Array<byte> _roomDesc;
+ bool _messageDelay;
+
+ struct {
+ Common::String cantGoThere;
+ Common::String dontHaveIt;
+ Common::String dontUnderstand;
+ Common::String gettingDark;
+ } _gameStrings;
+};
+
void HiRes1Engine::runIntro() const {
StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_0));
@@ -183,12 +277,7 @@ void HiRes1Engine::init() {
// Load dropped item offsets
stream->seek(IDI_HR1_OFS_ITEM_OFFSETS);
- for (uint i = 0; i < IDI_HR1_NUM_ITEM_OFFSETS; ++i) {
- Common::Point p;
- p.x = stream->readByte();
- p.y = stream->readByte();
- _itemOffsets.push_back(p);
- }
+ loadDroppedItemOffsets(*stream, IDI_HR1_NUM_ITEM_OFFSETS);
// Load right-angle line art
stream->seek(IDI_HR1_OFS_CORNERS);
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
deleted file mode 100644
index c060bc892e..0000000000
--- a/engines/adl/hires1.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ADL_HIRES1_H
-#define ADL_HIRES1_H
-
-#include "common/str.h"
-
-#include "adl/adl.h"
-#include "adl/graphics.h"
-#include "adl/disk.h"
-
-namespace Common {
-class ReadStream;
-struct Point;
-}
-
-namespace Adl {
-
-#define IDS_HR1_EXE_0 "AUTO LOAD OBJ"
-#define IDS_HR1_EXE_1 "ADVENTURE"
-#define IDS_HR1_LOADER "MYSTERY.HELLO"
-#define IDS_HR1_MESSAGES "MESSAGES"
-
-#define IDI_HR1_NUM_ROOMS 41
-#define IDI_HR1_NUM_PICS 97
-#define IDI_HR1_NUM_VARS 20
-#define IDI_HR1_NUM_ITEM_OFFSETS 21
-#define IDI_HR1_NUM_MESSAGES 168
-
-// Messages used outside of scripts
-#define IDI_HR1_MSG_CANT_GO_THERE 137
-#define IDI_HR1_MSG_DONT_UNDERSTAND 37
-#define IDI_HR1_MSG_ITEM_DOESNT_MOVE 151
-#define IDI_HR1_MSG_ITEM_NOT_HERE 152
-#define IDI_HR1_MSG_THANKS_FOR_PLAYING 140
-#define IDI_HR1_MSG_DONT_HAVE_IT 127
-#define IDI_HR1_MSG_GETTING_DARK 7
-
-#define IDI_HR1_OFS_STR_ENTER_COMMAND 0x5bbc
-#define IDI_HR1_OFS_STR_VERB_ERROR 0x5b4f
-#define IDI_HR1_OFS_STR_NOUN_ERROR 0x5b8e
-#define IDI_HR1_OFS_STR_PLAY_AGAIN 0x5f1e
-#define IDI_HR1_OFS_STR_CANT_GO_THERE 0x6c0a
-#define IDI_HR1_OFS_STR_DONT_HAVE_IT 0x6c31
-#define IDI_HR1_OFS_STR_DONT_UNDERSTAND 0x6c51
-#define IDI_HR1_OFS_STR_GETTING_DARK 0x6c7c
-#define IDI_HR1_OFS_STR_PRESS_RETURN 0x5f68
-#define IDI_HR1_OFS_STR_LINE_FEEDS 0x59d4
-
-#define IDI_HR1_OFS_PD_TEXT_0 0x005d
-#define IDI_HR1_OFS_PD_TEXT_1 0x012b
-#define IDI_HR1_OFS_PD_TEXT_2 0x016d
-#define IDI_HR1_OFS_PD_TEXT_3 0x0259
-
-#define IDI_HR1_OFS_INTRO_TEXT 0x0066
-#define IDI_HR1_OFS_GAME_OR_HELP 0x000f
-
-#define IDI_HR1_OFS_LOGO_0 0x1003
-#define IDI_HR1_OFS_LOGO_1 0x1800
-
-#define IDI_HR1_OFS_ITEMS 0x0100
-#define IDI_HR1_OFS_ROOMS 0x050a
-#define IDI_HR1_OFS_PICS 0x4b03
-#define IDI_HR1_OFS_CMDS_0 0x3c00
-#define IDI_HR1_OFS_CMDS_1 0x3d00
-#define IDI_HR1_OFS_MSGS 0x4d00
-
-#define IDI_HR1_OFS_ITEM_OFFSETS 0x68ff
-#define IDI_HR1_OFS_CORNERS 0x4f00
-
-#define IDI_HR1_OFS_VERBS 0x3800
-#define IDI_HR1_OFS_NOUNS 0x0f00
-
-class HiRes1Engine : public AdlEngine {
-public:
- HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) :
- AdlEngine(syst, gd),
- _files(nullptr),
- _messageDelay(true) { }
- ~HiRes1Engine() { delete _files; }
-
-private:
- // AdlEngine
- void runIntro() const;
- void init();
- void initGameState();
- void restartGame();
- void printString(const Common::String &str);
- Common::String loadMessage(uint idx) const;
- void printMessage(uint idx);
- void drawItems();
- void drawItem(Item &item, const Common::Point &pos);
- void loadRoom(byte roomNr);
- void showRoom();
-
- void wordWrap(Common::String &str) const;
-
- Files *_files;
- Common::File _exe;
- Common::Array<DataBlockPtr> _corners;
- Common::Array<byte> _roomDesc;
- bool _messageDelay;
-
- struct {
- Common::String cantGoThere;
- Common::String dontHaveIt;
- Common::String dontUnderstand;
- Common::String gettingDark;
- } _gameStrings;
-};
-
-} // End of namespace Adl
-
-#endif
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 14db237d82..199f457b4f 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -26,18 +26,44 @@
#include "common/file.h"
#include "common/stream.h"
-#include "adl/hires2.h"
+#include "adl/adl_v2.h"
#include "adl/display.h"
#include "adl/graphics.h"
#include "adl/disk.h"
namespace Adl {
+#define IDS_HR2_DISK_IMAGE "WIZARD.DSK"
+
+#define IDI_HR2_NUM_ROOMS 135
+#define IDI_HR2_NUM_MESSAGES 255
+#define IDI_HR2_NUM_VARS 40
+#define IDI_HR2_NUM_ITEM_PICS 38
+#define IDI_HR2_NUM_ITEM_OFFSETS 16
+
+// Messages used outside of scripts
+#define IDI_HR2_MSG_CANT_GO_THERE 123
+#define IDI_HR2_MSG_DONT_UNDERSTAND 19
+#define IDI_HR2_MSG_ITEM_DOESNT_MOVE 242
+#define IDI_HR2_MSG_ITEM_NOT_HERE 4
+#define IDI_HR2_MSG_THANKS_FOR_PLAYING 239
+
+class HiRes2Engine : public AdlEngine_v2 {
+public:
+ HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd) { }
+
+private:
+ // AdlEngine
+ void runIntro() const;
+ void init();
+ void initGameState();
+};
+
void HiRes2Engine::runIntro() const {
// This only works for the 16-sector re-release. The original
// release is not supported at this time, because we don't have
// access to it.
- _disk->setMode13(false);
+ _disk->setSectorLimit(0);
StreamPtr stream(_disk->createReadStream(0x00, 0xd, 0x17, 1));
_display->setMode(DISPLAY_MODE_TEXT);
@@ -50,7 +76,7 @@ void HiRes2Engine::runIntro() const {
_display->printString(str);
delay(2000);
- _disk->setMode13(true);
+ _disk->setSectorLimit(13);
}
void HiRes2Engine::init() {
@@ -60,12 +86,10 @@ void HiRes2Engine::init() {
if (!_disk->open(IDS_HR2_DISK_IMAGE))
error("Failed to open disk image '" IDS_HR2_DISK_IMAGE "'");
- _disk->setMode13(true);
+ _disk->setSectorLimit(13);
StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x00, 4));
-
- for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i)
- _messages.push_back(readDataBlockPtr(*stream));
+ loadMessages(*stream, IDI_HR2_NUM_MESSAGES);
// Read parser messages
stream.reset(_disk->createReadStream(0x1a, 0x1));
@@ -98,20 +122,11 @@ void HiRes2Engine::init() {
// Load global picture data
stream.reset(_disk->createReadStream(0x19, 0xa, 0x80, 0));
- byte picNr;
- while ((picNr = stream->readByte()) != 0xff) {
- if (stream->eos() || stream->err())
- error("Error reading global pic list");
-
- _pictures[picNr] = readDataBlockPtr(*stream);
- }
+ loadPictures(*stream);
// Load item picture data
stream.reset(_disk->createReadStream(0x1e, 0x9, 0x05));
- for (uint i = 0; i < IDI_HR2_NUM_ITEM_PICS; ++i) {
- stream->readByte(); // number
- _itemPics.push_back(readDataBlockPtr(*stream));
- }
+ loadItemPictures(*stream, IDI_HR2_NUM_ITEM_PICS);
// Load commands from executable
stream.reset(_disk->createReadStream(0x1d, 0x7, 0x00, 4));
@@ -122,12 +137,7 @@ void HiRes2Engine::init() {
// Load dropped item offsets
stream.reset(_disk->createReadStream(0x1b, 0x4, 0x15));
- for (uint i = 0; i < IDI_HR2_NUM_ITEM_OFFSETS; ++i) {
- Common::Point p;
- p.x = stream->readByte();
- p.y = stream->readByte();
- _itemOffsets.push_back(p);
- }
+ loadDroppedItemOffsets(*stream, IDI_HR2_NUM_ITEM_OFFSETS);
// Load verbs
stream.reset(_disk->createReadStream(0x19, 0x0, 0x00, 3));
@@ -142,46 +152,10 @@ void HiRes2Engine::initGameState() {
_state.vars.resize(IDI_HR2_NUM_VARS);
StreamPtr stream(_disk->createReadStream(0x21, 0x5, 0x0e, 7));
-
- for (uint i = 0; i < IDI_HR2_NUM_ROOMS; ++i) {
- Room room;
- stream->readByte(); // number
- for (uint j = 0; j < 6; ++j)
- room.connections[j] = stream->readByte();
- room.data = readDataBlockPtr(*stream);
- room.picture = stream->readByte();
- room.curPicture = stream->readByte();
- room.isFirstTime = stream->readByte();
- _state.rooms.push_back(room);
- }
+ loadRooms(*stream, IDI_HR2_NUM_ROOMS);
stream.reset(_disk->createReadStream(0x21, 0x0, 0x00, 2));
-
- byte id;
- while ((id = stream->readByte()) != 0xff) {
- Item item = Item();
- item.id = id;
- item.noun = stream->readByte();
- item.room = stream->readByte();
- item.picture = stream->readByte();
- item.isLineArt = stream->readByte(); // Is this still used in this way?
- item.position.x = stream->readByte();
- item.position.y = stream->readByte();
- item.state = stream->readByte();
- item.description = stream->readByte();
-
- stream->readByte(); // Struct size
-
- byte picListSize = stream->readByte();
-
- // Flag to keep track of what has been drawn on the screen
- stream->readByte();
-
- for (uint i = 0; i < picListSize; ++i)
- item.roomPictures.push_back(stream->readByte());
-
- _state.items.push_back(item);
- }
+ loadItems(*stream);
}
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/hires4.cpp b/engines/adl/hires4.cpp
new file mode 100644
index 0000000000..ddfc868e9a
--- /dev/null
+++ b/engines/adl/hires4.cpp
@@ -0,0 +1,271 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/system.h"
+#include "common/debug.h"
+#include "common/error.h"
+#include "common/file.h"
+#include "common/stream.h"
+
+#include "adl/adl_v3.h"
+#include "adl/detection.h"
+#include "adl/display.h"
+#include "adl/graphics.h"
+#include "adl/disk.h"
+
+namespace Adl {
+
+#define IDI_HR4_NUM_ROOMS 164
+#define IDI_HR4_NUM_MESSAGES 255
+#define IDI_HR4_NUM_VARS 40
+#define IDI_HR4_NUM_ITEM_DESCS 44
+#define IDI_HR4_NUM_ITEM_PICS 41
+#define IDI_HR4_NUM_ITEM_OFFSETS 40
+
+// Messages used outside of scripts
+#define IDI_HR4_MSG_CANT_GO_THERE 110
+#define IDI_HR4_MSG_DONT_UNDERSTAND 112
+#define IDI_HR4_MSG_ITEM_DOESNT_MOVE 114
+#define IDI_HR4_MSG_ITEM_NOT_HERE 115
+#define IDI_HR4_MSG_THANKS_FOR_PLAYING 113
+
+class HiRes4Engine_Atari : public AdlEngine_v3 {
+public:
+ HiRes4Engine_Atari(OSystem *syst, const AdlGameDescription *gd) :
+ AdlEngine_v3(syst, gd),
+ _boot(nullptr),
+ _curDisk(0) { }
+ ~HiRes4Engine_Atari();
+
+private:
+ // AdlEngine
+ void init();
+ void initGameState();
+ void loadRoom(byte roomNr);
+ Common::String formatVerbError(const Common::String &verb) const;
+ Common::String formatNounError(const Common::String &verb, const Common::String &noun) const;
+
+ // AdlEngine_v2
+ void adjustDataBlockPtr(byte &track, byte &sector, byte &offset, byte &size) const;
+
+ Common::SeekableReadStream *createReadStream(DiskImage *disk, byte track, byte sector, byte offset = 0, byte size = 0) const;
+ void loadCommonData();
+ void insertDisk(byte diskNr);
+ void rebindDisk();
+
+ DiskImage *_boot;
+ byte _curDisk;
+};
+
+static const char *const atariDisks[] = { "ULYS1A.XFD", "ULYS1B.XFD", "ULYS2C.XFD" };
+
+HiRes4Engine_Atari::~HiRes4Engine_Atari() {
+ delete _boot;
+}
+
+void HiRes4Engine_Atari::init() {
+ _graphics = new Graphics_v2(*_display);
+
+ _boot = new DiskImage();
+ if (!_boot->open(atariDisks[0]))
+ error("Failed to open disk image '%s'", atariDisks[0]);
+
+ insertDisk(1);
+ loadCommonData();
+
+ StreamPtr stream(createReadStream(_boot, 0x06, 0x2));
+ _strings.verbError = readStringAt(*stream, 0x4f);
+ _strings.nounError = readStringAt(*stream, 0x83);
+ _strings.enterCommand = readStringAt(*stream, 0xa6);
+
+ stream.reset(createReadStream(_boot, 0x05, 0xb, 0xd7));
+ _strings_v2.time = readString(*stream, 0xff);
+
+ stream.reset(createReadStream(_boot, 0x06, 0x7, 0x00, 2));
+ _strings_v2.saveInsert = readStringAt(*stream, 0x62);
+ _strings_v2.saveReplace = readStringAt(*stream, 0xdd);
+ _strings_v2.restoreInsert = readStringAt(*stream, 0x12a);
+ _strings_v2.restoreReplace = readStringAt(*stream, 0x1b8);
+ _strings.playAgain = readStringAt(*stream, 0x21b);
+ // TODO: restart sequence has "insert side a/b" strings
+
+ _messageIds.cantGoThere = IDI_HR4_MSG_CANT_GO_THERE;
+ _messageIds.dontUnderstand = IDI_HR4_MSG_DONT_UNDERSTAND;
+ _messageIds.itemDoesntMove = IDI_HR4_MSG_ITEM_DOESNT_MOVE;
+ _messageIds.itemNotHere = IDI_HR4_MSG_ITEM_NOT_HERE;
+ _messageIds.thanksForPlaying = IDI_HR4_MSG_THANKS_FOR_PLAYING;
+
+ stream.reset(createReadStream(_boot, 0x06, 0xd, 0x12, 2));
+ loadItemDescriptions(*stream, IDI_HR4_NUM_ITEM_DESCS);
+
+ stream.reset(createReadStream(_boot, 0x07, 0x1, 0xf4));
+ loadDroppedItemOffsets(*stream, IDI_HR4_NUM_ITEM_OFFSETS);
+
+ stream.reset(createReadStream(_boot, 0x08, 0xe, 0xa5, 5));
+ readCommands(*stream, _roomCommands);
+
+ stream.reset(createReadStream(_boot, 0x0a, 0x9, 0x00, 3));
+ readCommands(*stream, _globalCommands);
+
+ stream.reset(createReadStream(_boot, 0x05, 0x4, 0x00, 3));
+ loadWords(*stream, _verbs, _priVerbs);
+
+ stream.reset(createReadStream(_boot, 0x03, 0xb, 0x00, 6));
+ loadWords(*stream, _nouns, _priNouns);
+}
+
+void HiRes4Engine_Atari::loadRoom(byte roomNr) {
+ if (roomNr >= 59 && roomNr < 113) {
+ if (_curDisk != 2) {
+ insertDisk(2);
+ rebindDisk();
+ }
+ } else if (_curDisk != 1) {
+ insertDisk(1);
+ rebindDisk();
+ }
+
+ if (roomNr == 121) {
+ // Room 121 is not present in the Atari version. This causes
+ // problems when we're dumping scripts with the debugger, so
+ // we intercept this room load here.
+ // FIXME: Find out if the Apple II version does have this room
+ // FIXME: Implement more generic handling of invalid rooms?
+ debug("Warning: attempt to load non-existent room 121");
+ _roomData.description.clear();
+ _roomData.pictures.clear();
+ _roomData.commands.clear();
+ return;
+ }
+
+ AdlEngine_v3::loadRoom(roomNr);
+}
+
+Common::String HiRes4Engine_Atari::formatVerbError(const Common::String &verb) const {
+ Common::String err = _strings.verbError;
+ for (uint i = 0; i < verb.size(); ++i)
+ err.setChar(verb[i], i + 8);
+ return err;
+}
+
+Common::String HiRes4Engine_Atari::formatNounError(const Common::String &verb, const Common::String &noun) const {
+ Common::String err = _strings.nounError;
+ for (uint i = 0; i < verb.size(); ++i)
+ err.setChar(verb[i], i + 8);
+ for (uint i = 0; i < noun.size(); ++i)
+ err.setChar(noun[i], i + 19);
+ return err;
+}
+
+void HiRes4Engine_Atari::insertDisk(byte diskNr) {
+ if (_curDisk == diskNr)
+ return;
+
+ _curDisk = diskNr;
+
+ delete _disk;
+ _disk = new DiskImage();
+ if (!_disk->open(atariDisks[diskNr]))
+ error("Failed to open disk image '%s'", atariDisks[diskNr]);
+}
+
+void HiRes4Engine_Atari::rebindDisk() {
+ // As room.data is bound to the DiskImage, we need to rebind them here
+ // We cannot simply reload the rooms as that would reset their state
+
+ // FIXME: Remove DataBlockPtr-DiskImage coupling?
+
+ StreamPtr stream(createReadStream(_boot, 0x03, 0x1, 0x0e, 9));
+ for (uint i = 0; i < IDI_HR4_NUM_ROOMS; ++i) {
+ stream->skip(7);
+ _state.rooms[i].data = readDataBlockPtr(*stream);
+ stream->skip(3);
+ }
+
+ // Rebind data that is on both side B and C
+ loadCommonData();
+}
+
+void HiRes4Engine_Atari::loadCommonData() {
+ _messages.clear();
+ StreamPtr stream(createReadStream(_boot, 0x0a, 0x4, 0x00, 3));
+ loadMessages(*stream, IDI_HR4_NUM_MESSAGES);
+
+ _pictures.clear();
+ stream.reset(createReadStream(_boot, 0x05, 0xe, 0x80));
+ loadPictures(*stream);
+
+ _itemPics.clear();
+ stream.reset(createReadStream(_boot, 0x09, 0xe, 0x05));
+ loadItemPictures(*stream, IDI_HR4_NUM_ITEM_PICS);
+}
+
+void HiRes4Engine_Atari::initGameState() {
+ _state.vars.resize(IDI_HR4_NUM_VARS);
+
+ StreamPtr stream(createReadStream(_boot, 0x03, 0x1, 0x0e, 9));
+ loadRooms(*stream, IDI_HR4_NUM_ROOMS);
+
+ stream.reset(createReadStream(_boot, 0x02, 0xc, 0x00, 12));
+ loadItems(*stream);
+
+ // FIXME
+ _display->moveCursorTo(Common::Point(0, 23));
+}
+
+Common::SeekableReadStream *HiRes4Engine_Atari::createReadStream(DiskImage *disk, byte track, byte sector, byte offset, byte size) const {
+ adjustDataBlockPtr(track, sector, offset, size);
+ return disk->createReadStream(track, sector, offset, size);
+}
+
+void HiRes4Engine_Atari::adjustDataBlockPtr(byte &track, byte &sector, byte &offset, byte &size) const {
+ // Convert the Apple II disk offsets in the game, to Atari disk offsets
+ uint sectorIndex = (track * 16 + sector + 1) << 1;
+
+ // Atari uses 128 bytes per sector vs. 256 on the Apple II
+ // Note that size indicates *additional* sectors to read after reading one sector
+ size *= 2;
+
+ if (offset >= 128) {
+ // Offset in the second half of an Apple II sector, skip one sector and adjust offset
+ ++sectorIndex;
+ offset -= 128;
+ } else {
+ // Offset in the first half of an Apple II sector, we need to read one additional sector
+ ++size;
+ }
+
+ // Compute track/sector for Atari's 18 sectors per track (sectorIndex is 1-based)
+ track = (sectorIndex - 1) / 18;
+ sector = (sectorIndex - 1) % 18;
+}
+
+Engine *HiRes4Engine_create(OSystem *syst, const AdlGameDescription *gd) {
+ switch (gd->desc.platform) {
+ case Common::kPlatformAtariST:
+ return new HiRes4Engine_Atari(syst, gd);
+ default:
+ error("Unsupported platform");
+ }
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index e9df7b513a..a1fea05f19 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -27,13 +27,65 @@
#include "common/stream.h"
#include "common/memstream.h"
-#include "adl/hires6.h"
+#include "adl/adl_v4.h"
#include "adl/display.h"
#include "adl/graphics.h"
#include "adl/disk.h"
namespace Adl {
+#define IDI_HR6_NUM_ROOMS 35
+#define IDI_HR6_NUM_MESSAGES 256
+#define IDI_HR6_NUM_VARS 40
+#define IDI_HR6_NUM_ITEM_DESCS 15
+#define IDI_HR6_NUM_ITEM_PICS 15
+#define IDI_HR6_NUM_ITEM_OFFSETS 16
+
+// Messages used outside of scripts
+#define IDI_HR6_MSG_CANT_GO_THERE 249
+#define IDI_HR6_MSG_DONT_UNDERSTAND 247
+#define IDI_HR6_MSG_ITEM_DOESNT_MOVE 253
+#define IDI_HR6_MSG_ITEM_NOT_HERE 254
+#define IDI_HR6_MSG_THANKS_FOR_PLAYING 252
+
+struct DiskDataDesc {
+ byte track;
+ byte sector;
+ byte offset;
+ byte volume;
+};
+
+class HiRes6Engine : public AdlEngine_v4 {
+public:
+ HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) :
+ AdlEngine_v4(syst, gd),
+ _boot(nullptr),
+ _currVerb(0),
+ _currNoun(0) {
+ }
+
+ ~HiRes6Engine() { delete _boot; }
+
+private:
+ // AdlEngine
+ void runIntro() const;
+ void init();
+ void initGameState();
+ void printRoomDescription();
+ void showRoom();
+ Common::String formatVerbError(const Common::String &verb) const;
+ Common::String formatNounError(const Common::String &verb, const Common::String &noun) const;
+
+ // AdlEngine_v2
+ void printString(const Common::String &str);
+
+ void loadDisk(byte disk);
+
+ DiskImage *_boot;
+ byte _currVerb, _currNoun;
+ Common::Array<DiskDataDesc> _diskDataDesc;
+};
+
static const char *disks[] = { "DARK1A.DSK", "DARK1B.NIB", "DARK2A.NIB", "DARK2B.NIB" };
#define SECTORS_PER_TRACK 16
@@ -141,18 +193,12 @@ void HiRes6Engine::init() {
// Item descriptions
stream.reset(loadSectors(_boot, 0x6, 0xb, 2));
- stream->seek(0x34);
- for (uint i = 0; i < IDI_HR6_NUM_ITEM_DESCS; ++i)
- _itemDesc.push_back(readString(*stream, 0xff));
+ stream->seek(0x16);
+ loadItemDescriptions(*stream, IDI_HR6_NUM_ITEM_DESCS);
// Load dropped item offsets
stream.reset(_boot->createReadStream(0x8, 0x9, 0x16));
- for (uint i = 0; i < IDI_HR6_NUM_ITEM_OFFSETS; ++i) {
- Common::Point p;
- p.x = stream->readByte();
- p.y = stream->readByte();
- _itemOffsets.push_back(p);
- }
+ loadDroppedItemOffsets(*stream, IDI_HR6_NUM_ITEM_OFFSETS);
// Location of game data for each disc
stream.reset(_boot->createReadStream(0x5, 0xa, 0x03));
@@ -187,10 +233,7 @@ void HiRes6Engine::loadDisk(byte disk) {
// Load item picture data (indexed on boot disk)
StreamPtr stream(_boot->createReadStream(0xb, 0xd, 0x08));
_itemPics.clear();
- for (uint i = 0; i < IDI_HR6_NUM_ITEM_PICS; ++i) {
- stream->readByte();
- _itemPics.push_back(readDataBlockPtr(*stream));
- }
+ loadItemPictures(*stream, IDI_HR6_NUM_ITEM_PICS);
_curDisk = disk;
@@ -214,19 +257,13 @@ void HiRes6Engine::loadDisk(byte disk) {
// Messages
_messages.clear();
uint count = size / 4;
- for (uint i = 0; i < count; ++i)
- _messages.push_back(readDataBlockPtr(*stream));
+ loadMessages(*stream, count);
break;
}
case 0x4a80: {
// Global pics
_pictures.clear();
- byte picNr;
- while ((picNr = stream->readByte()) != 0xff) {
- if (stream->eos() || stream->err())
- error("Error reading global pic list");
- _pictures[picNr] = readDataBlockPtr(*stream);
- }
+ loadPictures(*stream);
break;
}
case 0x4000:
@@ -243,17 +280,7 @@ void HiRes6Engine::loadDisk(byte disk) {
stream->skip(14); // Skip invalid room 0
_state.rooms.clear();
- for (uint i = 0; i < count; ++i) {
- Room room;
- stream->readByte(); // number
- for (uint j = 0; j < 6; ++j)
- room.connections[j] = stream->readByte();
- room.data = readDataBlockPtr(*stream);
- room.picture = stream->readByte();
- room.curPicture = stream->readByte();
- room.isFirstTime = stream->readByte();
- _state.rooms.push_back(room);
- }
+ loadRooms(*stream, count);
break;
}
case 0x7b00:
@@ -287,31 +314,7 @@ void HiRes6Engine::initGameState() {
StreamPtr stream(_boot->createReadStream(0x3, 0xe, 0x03));
- byte id;
- while ((id = stream->readByte()) != 0xff) {
- Item item = Item();
- item.id = id;
- item.noun = stream->readByte();
- item.room = stream->readByte();
- item.picture = stream->readByte();
- item.isLineArt = stream->readByte(); // Now seems to be disk number
- item.position.x = stream->readByte();
- item.position.y = stream->readByte();
- item.state = stream->readByte();
- item.description = stream->readByte();
-
- stream->readByte(); // Struct size
-
- byte picListSize = stream->readByte();
-
- // Flag to keep track of what has been drawn on the screen
- stream->readByte();
-
- for (uint i = 0; i < picListSize; ++i)
- item.roomPictures.push_back(stream->readByte());
-
- _state.items.push_back(item);
- }
+ loadItems(*stream);
_currVerb = _currNoun = 0;
}
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
deleted file mode 100644
index 0f604d848c..0000000000
--- a/engines/adl/hires6.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ADL_HIRES6_H
-#define ADL_HIRES6_H
-
-#include "common/str.h"
-
-#include "adl/adl_v3.h"
-#include "adl/disk.h"
-
-namespace Common {
-class ReadStream;
-struct Point;
-}
-
-namespace Adl {
-
-#define IDI_HR6_NUM_ROOMS 35
-#define IDI_HR6_NUM_MESSAGES 256
-#define IDI_HR6_NUM_VARS 40
-#define IDI_HR6_NUM_ITEM_DESCS 15
-#define IDI_HR6_NUM_ITEM_PICS 15
-#define IDI_HR6_NUM_ITEM_OFFSETS 16
-
-// Messages used outside of scripts
-#define IDI_HR6_MSG_CANT_GO_THERE 249
-#define IDI_HR6_MSG_DONT_UNDERSTAND 247
-#define IDI_HR6_MSG_ITEM_DOESNT_MOVE 253
-#define IDI_HR6_MSG_ITEM_NOT_HERE 254
-#define IDI_HR6_MSG_THANKS_FOR_PLAYING 252
-
-struct DiskDataDesc {
- byte track;
- byte sector;
- byte offset;
- byte volume;
-};
-
-class HiRes6Engine : public AdlEngine_v3 {
-public:
- HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) :
- AdlEngine_v3(syst, gd),
- _boot(nullptr),
- _currVerb(0),
- _currNoun(0) {
- }
-
- ~HiRes6Engine() { delete _boot; }
-
-private:
- // AdlEngine
- void runIntro() const;
- void init();
- void initGameState();
- void printRoomDescription();
- void showRoom();
- Common::String formatVerbError(const Common::String &verb) const;
- Common::String formatNounError(const Common::String &verb, const Common::String &noun) const;
-
- // AdlEngine_v2
- void printString(const Common::String &str);
-
- void loadDisk(byte disk);
-
- DiskImage *_boot;
- byte _currVerb, _currNoun;
- Common::Array<DiskDataDesc> _diskDataDesc;
-};
-
-} // End of namespace Adl
-
-#endif
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index d17c8569b3..d1de2a6c02 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -4,6 +4,7 @@ MODULE_OBJS := \
adl.o \
adl_v2.o \
adl_v3.o \
+ adl_v4.o \
console.o \
detection.o \
disk.o \
@@ -14,6 +15,7 @@ MODULE_OBJS := \
hires0.o \
hires1.o \
hires2.o \
+ hires4.o \
hires6.o \
speaker.o
diff --git a/engines/director/archive.cpp b/engines/director/archive.cpp
new file mode 100644
index 0000000000..5b22b45734
--- /dev/null
+++ b/engines/director/archive.cpp
@@ -0,0 +1,248 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program 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 General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/macresman.h"
+
+#include "director/director.h"
+#include "director/resource.h"
+#include "director/lingo/lingo.h"
+
+namespace Director {
+
+Archive *DirectorEngine::createArchive() {
+ if (getPlatform() == Common::kPlatformMacintosh) {
+ if (getVersion() < 4)
+ return new MacArchive();
+ else
+ return new RIFXArchive();
+ } else {
+ return new RIFFArchive();
+ }
+}
+
+void DirectorEngine::loadMainArchive() {
+ if (getPlatform() == Common::kPlatformWindows)
+ loadEXE();
+ else
+ loadMac();
+}
+
+void DirectorEngine::cleanupMainArchive() {
+ delete _mainArchive;
+ delete _macBinary;
+}
+
+void DirectorEngine::loadEXE() {
+ Common::SeekableReadStream *exeStream = SearchMan.createReadStreamForMember(getEXEName());
+ if (!exeStream)
+ error("Failed to open EXE '%s'", getEXEName().c_str());
+
+ _lingo->processEvent(kEventStart, 0);
+
+ exeStream->seek(-4, SEEK_END);
+ exeStream->seek(exeStream->readUint32LE());
+
+ switch (getVersion()) {
+ case 3:
+ loadEXEv3(exeStream);
+ break;
+ case 4:
+ loadEXEv4(exeStream);
+ break;
+ case 5:
+ loadEXEv5(exeStream);
+ break;
+ case 7:
+ loadEXEv7(exeStream);
+ break;
+ default:
+ error("Unhandled Windows EXE version %d", getVersion());
+ }
+}
+
+void DirectorEngine::loadEXEv3(Common::SeekableReadStream *stream) {
+ uint16 entryCount = stream->readUint16LE();
+ if (entryCount != 1)
+ error("Unhandled multiple entry v3 EXE");
+
+ stream->skip(5); // unknown
+
+ stream->readUint32LE(); // Main MMM size
+ Common::String mmmFileName = readPascalString(*stream);
+ Common::String directoryName = readPascalString(*stream);
+
+ debugC(1, kDebugLoading, "Main MMM: '%s'", mmmFileName.c_str());
+ debugC(1, kDebugLoading, "Directory Name: '%s'", directoryName.c_str());
+
+ _mainArchive = new RIFFArchive();
+
+ if (!_mainArchive->openFile(mmmFileName))
+ error("Could not open '%s'", mmmFileName.c_str());
+
+ delete stream;
+}
+
+void DirectorEngine::loadEXEv4(Common::SeekableReadStream *stream) {
+ if (stream->readUint32BE() != MKTAG('P', 'J', '9', '3'))
+ error("Invalid projector tag found in v4 EXE");
+
+ uint32 rifxOffset = stream->readUint32LE();
+ /* uint32 fontMapOffset = */ stream->readUint32LE();
+ /* uint32 resourceForkOffset1 = */ stream->readUint32LE();
+ /* uint32 resourceForkOffset2 = */ stream->readUint32LE();
+ stream->readUint32LE(); // graphics DLL offset
+ stream->readUint32LE(); // sound DLL offset
+ /* uint32 rifxOffsetAlt = */ stream->readUint32LE(); // equivalent to rifxOffset
+
+ loadEXERIFX(stream, rifxOffset);
+}
+
+void DirectorEngine::loadEXEv5(Common::SeekableReadStream *stream) {
+ if (stream->readUint32LE() != MKTAG('P', 'J', '9', '5'))
+ error("Invalid projector tag found in v5 EXE");
+
+ uint32 rifxOffset = stream->readUint32LE();
+ stream->readUint32LE(); // unknown
+ stream->readUint32LE(); // unknown
+ stream->readUint32LE(); // unknown
+ /* uint16 screenWidth = */ stream->readUint16LE();
+ /* uint16 screenHeight = */ stream->readUint16LE();
+ stream->readUint32LE(); // unknown
+ stream->readUint32LE(); // unknown
+ /* uint32 fontMapOffset = */ stream->readUint32LE();
+
+ loadEXERIFX(stream, rifxOffset);
+}
+
+void DirectorEngine::loadEXEv7(Common::SeekableReadStream *stream) {
+ if (stream->readUint32LE() != MKTAG('P', 'J', '0', '0'))
+ error("Invalid projector tag found in v7 EXE");
+
+ uint32 rifxOffset = stream->readUint32LE();
+ stream->readUint32LE(); // unknown
+ stream->readUint32LE(); // unknown
+ stream->readUint32LE(); // unknown
+ stream->readUint32LE(); // unknown
+ stream->readUint32LE(); // some DLL offset
+
+ loadEXERIFX(stream, rifxOffset);
+}
+
+void DirectorEngine::loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset) {
+ _mainArchive = new RIFXArchive();
+
+ if (!_mainArchive->openStream(stream, offset))
+ error("Failed to load RIFX from EXE");
+}
+
+void DirectorEngine::loadMac() {
+ if (getVersion() < 4) {
+ // The data is part of the resource fork of the executable
+ _mainArchive = new MacArchive();
+
+ if (!_mainArchive->openFile(getEXEName()))
+ error("Failed to open Mac binary '%s'", getEXEName().c_str());
+ } else {
+ // The RIFX is located in the data fork of the executable
+ _macBinary = new Common::MacResManager();
+
+ if (!_macBinary->open(getEXEName()) || !_macBinary->hasDataFork())
+ error("Failed to open Mac binary '%s'", getEXEName().c_str());
+
+ Common::SeekableReadStream *dataFork = _macBinary->getDataFork();
+ _mainArchive = new RIFXArchive();
+
+ // First we need to detect PPC vs. 68k
+
+ uint32 tag = dataFork->readUint32BE();
+ uint32 startOffset;
+
+ if (SWAP_BYTES_32(tag) == MKTAG('P', 'J', '9', '3') || tag == MKTAG('P', 'J', '9', '5') || tag == MKTAG('P', 'J', '0', '0')) {
+ // PPC: The RIFX shares the data fork with the binary
+ startOffset = dataFork->readUint32BE();
+ } else {
+ // 68k: The RIFX is the only thing in the data fork
+ startOffset = 0;
+ }
+
+ if (!_mainArchive->openStream(dataFork, startOffset))
+ error("Failed to load RIFX from Mac binary");
+ }
+}
+
+void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
+ Archive *shardcst = createArchive();
+
+ debugC(1, kDebugLoading, "Loading Shared cast '%s'", filename.c_str());
+
+ shardcst->openFile(filename);
+
+ _sharedDIB = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
+ _sharedSTXT = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
+ _sharedSound = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
+ _sharedBMP = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
+
+ Score *castScore = new Score(this, shardcst);
+
+ castScore->loadConfig(*shardcst->getResource(MKTAG('V','W','C','F'), 1024));
+ castScore->loadCastData(*shardcst->getResource(MKTAG('V','W','C','R'), 1024));
+
+ _sharedCasts = &castScore->_casts;
+
+ Common::Array<uint16> dib = shardcst->getResourceIDList(MKTAG('D','I','B',' '));
+ if (dib.size() != 0) {
+ debugC(3, kDebugLoading, "Loading %d DIBs", dib.size());
+
+ for (Common::Array<uint16>::iterator iterator = dib.begin(); iterator != dib.end(); ++iterator) {
+ debugC(3, kDebugLoading, "Shared DIB %d", *iterator);
+ _sharedDIB->setVal(*iterator, shardcst->getResource(MKTAG('D','I','B',' '), *iterator));
+ }
+ }
+
+ Common::Array<uint16> stxt = shardcst->getResourceIDList(MKTAG('S','T','X','T'));
+ if (stxt.size() != 0) {
+ debugC(3, kDebugLoading, "Loading %d STXTs", stxt.size());
+
+ for (Common::Array<uint16>::iterator iterator = stxt.begin(); iterator != stxt.end(); ++iterator) {
+ debugC(3, kDebugLoading, "Shared STXT %d", *iterator);
+ _sharedSTXT->setVal(*iterator, shardcst->getResource(MKTAG('S','T','X','T'), *iterator));
+ }
+ }
+
+ Common::Array<uint16> bmp = shardcst->getResourceIDList(MKTAG('B','I','T','D'));
+ if (bmp.size() != 0) {
+ debugC(3, kDebugLoading, "Loading %d BITDs", bmp.size());
+ for (Common::Array<uint16>::iterator iterator = bmp.begin(); iterator != bmp.end(); ++iterator) {
+ _sharedBMP->setVal(*iterator, shardcst->getResource(MKTAG('B','I','T','D'), *iterator));
+ }
+ }
+
+ Common::Array<uint16> sound = shardcst->getResourceIDList(MKTAG('S','N','D',' '));
+ if (stxt.size() != 0) {
+ debugC(3, kDebugLoading, "Loading %d SNDs", sound.size());
+ for (Common::Array<uint16>::iterator iterator = sound.begin(); iterator != sound.end(); ++iterator) {
+ _sharedSound->setVal(*iterator, shardcst->getResource(MKTAG('S','N','D',' '), *iterator));
+ }
+ }
+}
+
+} // End of namespace Director
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index 9aeba7150b..40796f0b9f 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -23,14 +23,11 @@
#include "common/config-manager.h"
#include "common/debug-channels.h"
#include "common/error.h"
-#include "common/macresman.h"
#include "graphics/macgui/macwindowmanager.h"
#include "director/director.h"
-#include "director/images.h"
#include "director/resource.h"
-#include "director/score.h"
#include "director/sound.h"
#include "director/lingo/lingo.h"
@@ -41,6 +38,7 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
DebugMan.addDebugChannel(kDebugLingoExec, "lingoexec", "Lingo Execution");
DebugMan.addDebugChannel(kDebugLingoCompile, "lingocompile", "Lingo Compilation");
DebugMan.addDebugChannel(kDebugLoading, "loading", "Loading");
+ DebugMan.addDebugChannel(kDebugImages, "images", "Image drawing");
if (!_mixer->isReady())
error("Sound initialization failed");
@@ -49,6 +47,14 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
syncSoundSettings();
_sharedCasts = nullptr;
+
+ _currentScore = nullptr;
+ _soundManager = nullptr;
+ _currentPalette = nullptr;
+ _currentPaletteLength = 0;
+ _lingo = nullptr;
+
+ _sharedCasts = nullptr;
_sharedSound = nullptr;
_sharedBMP = nullptr;
_sharedSTXT = nullptr;
@@ -72,22 +78,18 @@ DirectorEngine::~DirectorEngine() {
delete _sharedBMP;
delete _sharedSTXT;
delete _sharedDIB;
- delete _movies;
- delete _mainArchive;
- delete _macBinary;
+ delete _currentScore;
+
+ cleanupMainArchive();
+
delete _soundManager;
delete _lingo;
- delete _currentScore;
- delete _currentPalette;
}
Common::Error DirectorEngine::run() {
debug("Starting v%d Director game", getVersion());
- //FIXME
- _sharedMMM = "SHARDCST.MMM";
-
_currentPalette = nullptr;
_macBinary = nullptr;
@@ -111,12 +113,10 @@ Common::Error DirectorEngine::run() {
//_mainArchive = new RIFFArchive();
//_mainArchive->openFile("bookshelf_example.mmm");
- if (getPlatform() == Common::kPlatformWindows)
- loadEXE();
- else
- loadMac();
+ loadMMMNames(ConfMan.get("path"));
+ loadMainArchive();
- _currentScore = new Score(this);
+ _currentScore = new Score(this, _mainArchive);
debug(0, "Score name %s", _currentScore->getMacName().c_str());
_currentScore->loadArchive();
@@ -128,6 +128,13 @@ Common::Error DirectorEngine::run() {
Common::HashMap<Common::String, Score *> DirectorEngine::loadMMMNames(Common::String folder) {
Common::FSNode directory(folder);
Common::FSList movies;
+ const char *sharedMMMname;
+
+ if (getPlatform() == Common::kPlatformWindows)
+ sharedMMMname = "SHARDCST.MMM";
+ else
+ sharedMMMname = "Shared Cast*";
+
Common::HashMap<Common::String, Score *> nameMap;
if (!directory.getChildren(movies, Common::FSNode::kListFilesOnly))
@@ -135,14 +142,16 @@ Common::HashMap<Common::String, Score *> DirectorEngine::loadMMMNames(Common::St
if (!movies.empty()) {
for (Common::FSList::const_iterator i = movies.begin(); i != movies.end(); ++i) {
- if (i->getName() == _sharedMMM) {
- loadSharedCastsFrom(i->getPath());
+ debugC(2, kDebugLoading, "File: %s", i->getName().c_str());
+ if (Common::matchString(i->getName().c_str(), sharedMMMname, true)) {
+ loadSharedCastsFrom(i->getName());
continue;
}
- RIFFArchive *arc = new RIFFArchive();
- arc->openFile(i->getPath());
- Score *sc = new Score(this);
+ Archive *arc = createArchive();
+
+ arc->openFile(i->getName());
+ Score *sc = new Score(this, arc);
nameMap[sc->getMacName()] = sc;
}
}
@@ -150,144 +159,6 @@ Common::HashMap<Common::String, Score *> DirectorEngine::loadMMMNames(Common::St
return nameMap;
}
-void DirectorEngine::loadEXE() {
- Common::SeekableReadStream *exeStream = SearchMan.createReadStreamForMember(getEXEName());
- if (!exeStream)
- error("Failed to open EXE '%s'", getEXEName().c_str());
-
- _lingo->processEvent(kEventStart, 0);
-
- exeStream->seek(-4, SEEK_END);
- exeStream->seek(exeStream->readUint32LE());
-
- switch (getVersion()) {
- case 3:
- loadEXEv3(exeStream);
- break;
- case 4:
- loadEXEv4(exeStream);
- break;
- case 5:
- loadEXEv5(exeStream);
- break;
- case 7:
- loadEXEv7(exeStream);
- break;
- default:
- error("Unhandled Windows EXE version %d", getVersion());
- }
-}
-
-void DirectorEngine::loadEXEv3(Common::SeekableReadStream *stream) {
- uint16 entryCount = stream->readUint16LE();
- if (entryCount != 1)
- error("Unhandled multiple entry v3 EXE");
-
- stream->skip(5); // unknown
-
- stream->readUint32LE(); // Main MMM size
- Common::String mmmFileName = readPascalString(*stream);
- Common::String directoryName = readPascalString(*stream);
-
- debug("Main MMM: '%s'", mmmFileName.c_str());
- debug("Directory Name: '%s'", directoryName.c_str());
-
- _mainArchive = new RIFFArchive();
-
- if (!_mainArchive->openFile(mmmFileName))
- error("Could not open '%s'", mmmFileName.c_str());
-
- delete stream;
-}
-
-void DirectorEngine::loadEXEv4(Common::SeekableReadStream *stream) {
- if (stream->readUint32BE() != MKTAG('P', 'J', '9', '3'))
- error("Invalid projector tag found in v4 EXE");
-
- uint32 rifxOffset = stream->readUint32LE();
- /* uint32 fontMapOffset = */ stream->readUint32LE();
- /* uint32 resourceForkOffset1 = */ stream->readUint32LE();
- /* uint32 resourceForkOffset2 = */ stream->readUint32LE();
- stream->readUint32LE(); // graphics DLL offset
- stream->readUint32LE(); // sound DLL offset
- /* uint32 rifxOffsetAlt = */ stream->readUint32LE(); // equivalent to rifxOffset
-
- loadEXERIFX(stream, rifxOffset);
-}
-
-void DirectorEngine::loadEXEv5(Common::SeekableReadStream *stream) {
- if (stream->readUint32LE() != MKTAG('P', 'J', '9', '5'))
- error("Invalid projector tag found in v5 EXE");
-
- uint32 rifxOffset = stream->readUint32LE();
- stream->readUint32LE(); // unknown
- stream->readUint32LE(); // unknown
- stream->readUint32LE(); // unknown
- /* uint16 screenWidth = */ stream->readUint16LE();
- /* uint16 screenHeight = */ stream->readUint16LE();
- stream->readUint32LE(); // unknown
- stream->readUint32LE(); // unknown
- /* uint32 fontMapOffset = */ stream->readUint32LE();
-
- loadEXERIFX(stream, rifxOffset);
-}
-
-void DirectorEngine::loadEXEv7(Common::SeekableReadStream *stream) {
- if (stream->readUint32LE() != MKTAG('P', 'J', '0', '0'))
- error("Invalid projector tag found in v7 EXE");
-
- uint32 rifxOffset = stream->readUint32LE();
- stream->readUint32LE(); // unknown
- stream->readUint32LE(); // unknown
- stream->readUint32LE(); // unknown
- stream->readUint32LE(); // unknown
- stream->readUint32LE(); // some DLL offset
-
- loadEXERIFX(stream, rifxOffset);
-}
-
-void DirectorEngine::loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset) {
- _mainArchive = new RIFXArchive();
-
- if (!_mainArchive->openStream(stream, offset))
- error("Failed to load RIFX from EXE");
-}
-
-void DirectorEngine::loadMac() {
- if (getVersion() < 4) {
- // The data is part of the resource fork of the executable
- _mainArchive = new MacArchive();
-
- if (!_mainArchive->openFile(getEXEName()))
- error("Failed to open Mac binary '%s'", getEXEName().c_str());
- } else {
- // The RIFX is located in the data fork of the executable
- _macBinary = new Common::MacResManager();
-
- if (!_macBinary->open(getEXEName()) || !_macBinary->hasDataFork())
- error("Failed to open Mac binary '%s'", getEXEName().c_str());
-
- Common::SeekableReadStream *dataFork = _macBinary->getDataFork();
- _mainArchive = new RIFXArchive();
-
- // First we need to detect PPC vs. 68k
-
- uint32 tag = dataFork->readUint32BE();
- uint32 startOffset;
-
- if (SWAP_BYTES_32(tag) == MKTAG('P', 'J', '9', '3') || tag == MKTAG('P', 'J', '9', '5') || tag == MKTAG('P', 'J', '0', '0')) {
- // PPC: The RIFX shares the data fork with the binary
- startOffset = dataFork->readUint32BE();
- } else {
- // 68k: The RIFX is the only thing in the data fork
- startOffset = 0;
- }
-
- if (!_mainArchive->openStream(dataFork, startOffset))
- error("Failed to load RIFX from Mac binary");
- }
-}
-
Common::String DirectorEngine::readPascalString(Common::SeekableReadStream &stream) {
byte length = stream.readByte();
Common::String x;
@@ -303,60 +174,4 @@ void DirectorEngine::setPalette(byte *palette, uint16 count) {
_currentPaletteLength = count;
}
-void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
- Archive *shardcst;
-
- if (getVersion() < 4) {
- shardcst = new RIFFArchive();
- } else {
- shardcst = new RIFXArchive();
- }
-
- shardcst->openFile(filename);
-
- Score *castScore = new Score(this);
- Common::SeekableSubReadStreamEndian *castStream = shardcst->getResource(MKTAG('V','W','C','R'), 1024);
-
- castScore->loadCastData(*castStream);
- *_sharedCasts = castScore->_casts;
-
- Common::Array<uint16> dib = shardcst->getResourceIDList(MKTAG('D','I','B',' '));
-
- if (dib.size() != 0) {
- Common::Array<uint16>::iterator iterator;
- for (iterator = dib.begin(); iterator != dib.end(); ++iterator) {
- debug(3, "Shared DIB %d", *iterator);
- _sharedDIB->setVal(*iterator, shardcst->getResource(MKTAG('D','I','B',' '), *iterator));
- }
- }
-
- Common::Array<uint16> stxt = shardcst->getResourceIDList(MKTAG('S','T','X','T'));
-
- if (stxt.size() != 0) {
- Common::Array<uint16>::iterator iterator;
- for (iterator = stxt.begin(); iterator != stxt.end(); ++iterator) {
- debug(3, "Shared STXT %d", *iterator);
- _sharedSTXT->setVal(*iterator, shardcst->getResource(MKTAG('S','T','X','T'), *iterator));
- }
- }
-
- Common::Array<uint16> bmp = shardcst->getResourceIDList(MKTAG('B','I','T','D'));
-
- if (bmp.size() != 0) {
- Common::Array<uint16>::iterator iterator;
- for (iterator = bmp.begin(); iterator != bmp.end(); ++iterator) {
- _sharedBMP->setVal(*iterator, shardcst->getResource(MKTAG('B','I','T','D'), *iterator));
- }
- }
-
- Common::Array<uint16> sound = shardcst->getResourceIDList(MKTAG('S','N','D',' '));
-
- if (stxt.size() != 0) {
- Common::Array<uint16>::iterator iterator;
- for (iterator = sound.begin(); iterator != sound.end(); ++iterator) {
- _sharedSound->setVal(*iterator, shardcst->getResource(MKTAG('S','N','D',' '), *iterator));
- }
- }
-}
-
} // End of namespace Director
diff --git a/engines/director/director.h b/engines/director/director.h
index 23519f135e..4cb8640d5b 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -54,7 +54,8 @@ struct Cast;
enum {
kDebugLingoExec = 1 << 0,
kDebugLingoCompile = 1 << 1,
- kDebugLoading = 1 << 2
+ kDebugLoading = 1 << 2,
+ kDebugImages = 1 << 3
};
@@ -79,6 +80,11 @@ public:
const byte *getPalette() const { return _currentPalette; }
uint16 getPaletteColorCount() const { return _currentPaletteLength; }
void loadSharedCastsFrom(Common::String filename);
+
+ void loadMainArchive();
+ Archive *createArchive();
+ void cleanupMainArchive();
+
Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *getSharedDIB() const { return _sharedDIB; }
Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *getSharedBMP() const { return _sharedBMP; }
Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *getSharedSTXT() const { return _sharedSTXT; }
@@ -107,7 +113,6 @@ private:
Common::String readPascalString(Common::SeekableReadStream &stream);
- Common::String _sharedMMM;
Common::HashMap<int, Cast *> *_sharedCasts;
Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *_sharedDIB;
Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *_sharedSTXT;
diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 018cb7983c..3d5d8b6a4b 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -51,6 +51,8 @@ Frame::Frame(DirectorEngine *vm) {
_skipFrameFlag = 0;
_blend = 0;
+ _palette = NULL;
+
_sprites.resize(CHANNEL_COUNT);
for (uint16 i = 0; i < _sprites.size(); i++) {
@@ -75,6 +77,8 @@ Frame::Frame(const Frame &frame) {
_blend = frame._blend;
_palette = new PaletteInfo();
+ debugC(1, kDebugLoading, "Frame. action: %d transType: %d transDuration: %d", _actionId, _transType, _transDuration);
+
_sprites.resize(CHANNEL_COUNT);
for (uint16 i = 0; i < CHANNEL_COUNT; i++) {
@@ -435,7 +439,7 @@ void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) {
continue;
}
- Image::ImageDecoder *img = getImageFrom(_sprites[i]->_castId, _sprites[i]->_width, _sprites[i]->_height);
+ Image::ImageDecoder *img = getImageFrom(_sprites[i]->_castId);
if (!img) {
warning("Image with id %d not found", _sprites[i]->_castId);
@@ -467,6 +471,10 @@ void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) {
case kInkTypeCopy:
surface.blitFrom(*img->getSurface(), Common::Point(x, y));
break;
+ case kInkTypeTransparent:
+ //FIXME: is it always white (last entry in pallette)?
+ surface.transBlitFrom(*img->getSurface(), Common::Point(x, y), _vm->getPaletteColorCount() - 1);
+ break;
case kInkTypeBackgndTrans:
drawBackgndTransSprite(surface, *img->getSurface(), drawRect);
break;
@@ -516,25 +524,7 @@ void Frame::renderButton(Graphics::ManagedSurface &surface, uint16 spriteId) {
}
}
-static const int corrections[] = {
- 1026, 27, 27, // Macro
- 1027, 164, 170, // House
- 1028, 154, 154, // Macromind Director
- 1029, 158, 158, // Upper inscription
- 1030, 54, 54, // lift
- 1031, 116, 116, // Lower inscription
- 1032, 113, 113, // Lower inscription 2
- 1039, 50, 50,
- 1041, 110, 110, // descr
- 1042, 120, 121, // descr 2
- 1065, 27, 27, // car
- 1109, 104, 112, // taxi
- 1110, 90, 96, // taxi
- 1111, 74, 80, // taxi
- 0, 0, 0
-};
-
-Image::ImageDecoder *Frame::getImageFrom(uint16 spriteId, int w, int h) {
+Image::ImageDecoder *Frame::getImageFrom(uint16 spriteId) {
uint16 imgId = spriteId + 1024;
Image::ImageDecoder *img = NULL;
@@ -551,30 +541,27 @@ Image::ImageDecoder *Frame::getImageFrom(uint16 spriteId, int w, int h) {
}
if (_vm->_currentScore->getArchive()->hasResource(MKTAG('B', 'I', 'T', 'D'), imgId)) {
+ Common::SeekableReadStream *pic = _vm->_currentScore->getArchive()->getResource(MKTAG('B', 'I', 'T', 'D'), imgId);
+
if (_vm->getVersion() < 4) {
- bool c = false;
- for (int i = 0; corrections[i]; i += 3)
- if (corrections[i] == imgId) {
- w = corrections[i + 2];
- c = true;
- break;
- }
+ BitmapCast *bc = static_cast<BitmapCast *>(_vm->_currentScore->_casts[spriteId]);
+ int w = bc->initialRect.width(), h = bc->initialRect.height();
- if (!c)
- warning("%d, %d, %d,", imgId, w, w);
+ debugC(2, kDebugImages, "id: %d, w: %d, h: %d, flags: %x, some: %x, unk1: %d, unk2: %d",
+ imgId, w, h, bc->flags, bc->someFlaggyThing, bc->unk1, bc->unk2);
img = new BITDDecoder(w, h);
} else {
img = new Image::BitmapDecoder();
}
if (debugChannelSet(8, kDebugLoading)) {
- Common::SeekableReadStream *s = _vm->_currentScore->getArchive()->getResource(MKTAG('B', 'I', 'T', 'D'), imgId);
+ Common::SeekableReadStream *s = pic;
byte buf[1024];
int n = s->read(buf, 1024);
Common::hexdump(buf, n);
}
- img->loadStream(*_vm->_currentScore->getArchive()->getResource(MKTAG('B', 'I', 'T', 'D'), imgId));
+ img->loadStream(*pic);
return img;
}
@@ -725,7 +712,7 @@ void Frame::drawReverseSprite(Graphics::ManagedSurface &target, const Graphics::
}
void Frame::drawMatteSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect) {
- //Like background trans, but all white pixels NOT ENCLOSED by coloured pixels are transparent
+ // Like background trans, but all white pixels NOT ENCLOSED by coloured pixels are transparent
Graphics::Surface tmp;
tmp.copyFrom(sprite);
@@ -747,31 +734,38 @@ void Frame::drawMatteSprite(Graphics::ManagedSurface &target, const Graphics::Su
}
if (whiteColor == -1) {
- warning("No white color for Matte image");
- whiteColor = *(byte *)tmp.getBasePtr(0, 0);
- }
+ debugC(1, kDebugImages, "No white color for Matte image");
- Graphics::FloodFill ff(&tmp, whiteColor, 0, true);
+ for (int yy = 0; yy < tmp.h; yy++) {
+ const byte *src = (const byte *)tmp.getBasePtr(0, yy);
+ byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + yy);
- for (int yy = 0; yy < tmp.h; yy++) {
- ff.addSeed(0, yy);
- ff.addSeed(tmp.w - 1, yy);
- }
+ for (int xx = 0; xx < drawRect.width(); xx++, src++, dst++)
+ *dst = *src;
+ }
+ } else {
+ Graphics::FloodFill ff(&tmp, whiteColor, 0, true);
- for (int xx = 0; xx < tmp.w; xx++) {
- ff.addSeed(xx, 0);
- ff.addSeed(xx, tmp.h - 1);
- }
- ff.fillMask();
+ for (int yy = 0; yy < tmp.h; yy++) {
+ ff.addSeed(0, yy);
+ ff.addSeed(tmp.w - 1, yy);
+ }
- for (int yy = 0; yy < tmp.h; yy++) {
- const byte *src = (const byte *)tmp.getBasePtr(0, yy);
- const byte *mask = (const byte *)ff.getMask()->getBasePtr(0, yy);
- byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + yy);
+ for (int xx = 0; xx < tmp.w; xx++) {
+ ff.addSeed(xx, 0);
+ ff.addSeed(xx, tmp.h - 1);
+ }
+ ff.fillMask();
- for (int xx = 0; xx < drawRect.width(); xx++, src++, dst++, mask++)
- if (*mask == 0)
- *dst = *src;
+ for (int yy = 0; yy < tmp.h; yy++) {
+ const byte *src = (const byte *)tmp.getBasePtr(0, yy);
+ const byte *mask = (const byte *)ff.getMask()->getBasePtr(0, yy);
+ byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + yy);
+
+ for (int xx = 0; xx < drawRect.width(); xx++, src++, dst++, mask++)
+ if (*mask == 0)
+ *dst = *src;
+ }
}
tmp.free();
diff --git a/engines/director/frame.h b/engines/director/frame.h
index c06157c2cc..8c6f82f493 100644
--- a/engines/director/frame.h
+++ b/engines/director/frame.h
@@ -118,7 +118,7 @@ private:
void readPaletteInfo(Common::SeekableSubReadStreamEndian &stream);
void readSprite(Common::SeekableSubReadStreamEndian &stream, uint16 offset, uint16 size);
void readMainChannels(Common::SeekableSubReadStreamEndian &stream, uint16 offset, uint16 size);
- Image::ImageDecoder *getImageFrom(uint16 spriteID, int w, int h);
+ Image::ImageDecoder *getImageFrom(uint16 spriteID);
void drawBackgndTransSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect);
void drawMatteSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect);
void drawGhostSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect);
diff --git a/engines/director/images.cpp b/engines/director/images.cpp
index db429af7e9..cd8223ae8e 100644
--- a/engines/director/images.cpp
+++ b/engines/director/images.cpp
@@ -21,8 +21,10 @@
*/
#include "common/substream.h"
+#include "common/debug.h"
#include "common/textconsole.h"
+#include "director/director.h"
#include "director/images.h"
namespace Director {
@@ -103,12 +105,16 @@ bool DIBDecoder::loadStream(Common::SeekableReadStream &stream) {
****************************/
BITDDecoder::BITDDecoder(int w, int h) {
- int oldw = w;
- //w += 8 - (w + 7) % 8;
-
- //warning("W: %d -> %d, %d", oldw, w, h);
_surface = new Graphics::Surface();
- _surface->create(w, h, Graphics::PixelFormat::createFormatCLUT8());
+
+ // We make the surface pitch a multiple of 16.
+ int pitch = w;
+ if (w % 16)
+ pitch += 16 - (w % 16);
+
+ // HACK: Create a padded surface by adjusting w after create()
+ _surface->create(pitch, h, Graphics::PixelFormat::createFormatCLUT8());
+ _surface->w = w;
_palette = new byte[256 * 3];
@@ -137,6 +143,21 @@ void BITDDecoder::loadPalette(Common::SeekableReadStream &stream) {
bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
int x = 0, y = 0;
+ // If the stream has exactly the required number of bits for this image,
+ // we assume it is uncompressed.
+ if (stream.size() * 8 == _surface->pitch * _surface->h) {
+ debugC(3, kDebugImages, "Skipping compression");
+ for (y = 0; y < _surface->h; y++) {
+ for (x = 0; x < _surface->pitch; ) {
+ byte color = stream.readByte();
+ for (int c = 0; c < 8; c++)
+ *((byte *)_surface->getBasePtr(x++, y)) = (color & (1 << (7 - c))) ? 0 : 0xff;
+ }
+ }
+
+ return true;
+ }
+
while (y < _surface->h) {
int n = stream.readSByte();
int count;
@@ -167,7 +188,7 @@ bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
for (int c = 0; c < 8; c++) {
*((byte *)_surface->getBasePtr(x, y)) = (color & (1 << (7 - c))) ? 0 : 0xff;
x++;
- if (x == _surface->w) {
+ if (x == _surface->pitch) {
y++;
x = 0;
break;
diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index 2189f1f7aa..e22044c1e9 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -20,29 +20,6 @@
*
*/
-// Heavily inspired by hoc
-// Copyright (C) AT&T 1995
-// All Rights Reserved
-//
-// Permission to use, copy, modify, and distribute this software and
-// its documentation for any purpose and without fee is hereby
-// granted, provided that the above copyright notice appear in all
-// copies and that both that the copyright notice and this
-// permission notice and warranty disclaimer appear in supporting
-// documentation, and that the name of AT&T or any of its entities
-// not be used in advertising or publicity pertaining to
-// distribution of the software without specific, written prior
-// permission.
-//
-// AT&T DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
-// IN NO EVENT SHALL AT&T OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
-// SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
-// IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
-// THIS SOFTWARE.
-
#include "director/lingo/lingo.h"
#include "common/file.h"
#include "audio/decoders/wave.h"
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 529738043c..17e8ea44fe 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -108,6 +108,8 @@ Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
_exitRepeat = false;
+ _localvars = NULL;
+
warning("Lingo Inited");
}
@@ -248,11 +250,31 @@ void Lingo::executeScript(ScriptType type, uint16 id) {
cleanLocalVars();
}
+ScriptType Lingo::event2script(LEvent ev) {
+ if (_vm->getVersion() < 4) {
+ switch (ev) {
+ //case kEventStartMovie: // We are precompiling it now
+ // return kMovieScript;
+ case kEventEnterFrame:
+ return kFrameScript;
+ default:
+ return kNoneScript;
+ }
+ }
+
+ return kNoneScript;
+}
+
void Lingo::processEvent(LEvent event, int entityId) {
if (!_eventHandlerTypes.contains(event))
error("processEvent: Unknown event %d for entity %d", event, entityId);
- debug(2, "STUB: processEvent(%s) for %d", _eventHandlerTypes[event], entityId);
+ ScriptType st = event2script(event);
+
+ if (st != kNoneScript)
+ executeScript(st, entityId + 1);
+ else
+ debugC(8, kDebugLingoExec, "STUB: processEvent(%s) for %d", _eventHandlerTypes[event], entityId);
}
int Lingo::alignTypes(Datum &d1, Datum &d2) {
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index a921f49e4b..4dd00417b8 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -176,6 +176,8 @@ public:
void printStack(const char *s);
Common::String decodeInstruction(int pc, int *newPC = NULL);
+ ScriptType event2script(LEvent ev);
+
void processEvent(LEvent event, int entityId);
void initBuiltIns();
diff --git a/engines/director/module.mk b/engines/director/module.mk
index c37e9d9b9b..1ea361590a 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -1,6 +1,7 @@
MODULE := engines/director
MODULE_OBJS = \
+ archive.o \
detection.o \
director.o \
frame.o \
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 9b4f57245d..6d6d02274c 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -87,16 +87,26 @@ static byte defaultPalette[768] = {
204, 51, 255, 204, 102, 255, 204, 153, 255, 204, 204, 255, 204, 255, 255, 255,
0, 255, 255, 51, 255, 255, 102, 255, 255, 153, 255, 255, 204, 255, 255, 255 };
-Score::Score(DirectorEngine *vm) {
+Score::Score(DirectorEngine *vm, Archive *archive) {
_vm = vm;
_surface = new Graphics::ManagedSurface;
_trailSurface = new Graphics::ManagedSurface;
- _movieArchive = _vm->getMainArchive();
+ _movieArchive = archive;
_lingo = _vm->getLingo();
_soundManager = _vm->getSoundManager();
_lingo->processEvent(kEventPrepareMovie, 0);
_movieScriptCount = 0;
_labels = NULL;
+ _font = NULL;
+
+ _versionMinor = _versionMajor = 0;
+ _currentFrameRate = 20;
+ _castArrayStart = _castArrayEnd = 0;
+ _currentFrame = 0;
+ _nextFrameTime = 0;
+ _flags = 0;
+ _stopPlay = false;
+ _stageColor = 0;
if (_movieArchive->hasResource(MKTAG('M','C','N','M'), 0)) {
_macName = _movieArchive->getName(MKTAG('M','C','N','M'), 0).c_str();
@@ -159,11 +169,7 @@ void Score::loadArchive() {
Common::Array<uint16> stxt = _movieArchive->getResourceIDList(MKTAG('S','T','X','T'));
if (stxt.size() > 0) {
- Common::Array<uint16>::iterator iterator;
-
- for (iterator = stxt.begin(); iterator != stxt.end(); ++iterator) {
- loadScriptText(*_movieArchive->getResource(MKTAG('S','T','X','T'), *iterator));
- }
+ loadScriptText(*_movieArchive->getResource(MKTAG('S','T','X','T'), *stxt.begin()));
}
}
@@ -181,8 +187,6 @@ Score::~Score() {
_movieArchive->close();
delete _font;
- delete _movieArchive;
-
delete _labels;
}
@@ -268,6 +272,8 @@ void Score::readVersion(uint32 rid) {
}
void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream) {
+ debugC(1, kDebugLoading, "Score::loadCastData(). start: %d, end: %d", _castArrayStart, _castArrayEnd);
+
for (uint16 id = _castArrayStart; id <= _castArrayEnd; id++) {
byte size = stream.readByte();
if (size == 0)
@@ -440,6 +446,8 @@ void Score::dumpScript(const char *script, ScriptType type, uint16 id) {
char buf[256];
switch (type) {
+ case kNoneScript:
+ error("Incorrect dumpScript() call");
case kFrameScript:
typeName = "frame";
break;
@@ -642,16 +650,17 @@ void Score::loadFontMap(Common::SeekableSubReadStreamEndian &stream) {
}
BitmapCast::BitmapCast(Common::SeekableSubReadStreamEndian &stream) {
- /*byte flags = */ stream.readByte();
- uint16 someFlaggyThing = stream.readUint16();
+ flags = stream.readByte();
+ someFlaggyThing = stream.readUint16();
initialRect = Score::readRect(stream);
boundingRect = Score::readRect(stream);
regY = stream.readUint16();
regX = stream.readUint16();
+ unk1 = unk2 = 0;
if (someFlaggyThing & 0x8000) {
- /*uint16 unk1 =*/ stream.readUint16();
- /*uint16 unk2 =*/ stream.readUint16();
+ unk1 = stream.readUint16();
+ unk2 = stream.readUint16();
}
modified = 0;
}
@@ -664,8 +673,9 @@ TextCast::TextCast(Common::SeekableSubReadStreamEndian &stream) {
textType = static_cast<TextType>(stream.readByte());
textAlign = static_cast<TextAlignType>(stream.readUint16());
stream.skip(6); //palinfo
- //for now, just supposition
- fontId = stream.readUint32();
+
+ int t = stream.readUint32();
+ assert(t == 0); // So far we saw only 0 here
initialRect = Score::readRect(stream);
textShadow = static_cast<SizeType>(stream.readByte());
@@ -676,8 +686,11 @@ TextCast::TextCast(Common::SeekableSubReadStreamEndian &stream) {
textFlags.push_back(kTextFlagAutoTab);
if (flags & 0x4)
textFlags.push_back(kTextFlagDoNotWrap);
- //again supposition
- fontSize = stream.readUint16();
+
+ //TODO: FIXME: guesswork
+ fontId = stream.readByte();
+ fontSize = stream.readByte();
+
modified = 0;
}
@@ -724,11 +737,9 @@ void Score::startLoop() {
_frames[_currentFrame]->prepareFrame(this);
while (!_stopPlay && _currentFrame < _frames.size() - 2) {
+ debugC(1, kDebugImages, "Current frame: %d", _currentFrame);
update();
processEvents();
-
- g_system->updateScreen();
- g_system->delayMillis(10);
}
}
@@ -740,8 +751,8 @@ void Score::update() {
_surface->copyFrom(*_trailSurface);
//Enter and exit from previous frame (Director 4)
- _lingo->processEvent(kEventEnterFrame, _currentFrame);
- _lingo->processEvent(kEventExitFrame, _currentFrame);
+ _lingo->processEvent(kEventEnterFrame, _frames[_currentFrame]->_actionId);
+ _lingo->processEvent(kEventExitFrame, _frames[_currentFrame]->_actionId);
//TODO Director 6 - another order
@@ -785,13 +796,11 @@ void Score::update() {
//Wait for sound channel 1
while (_soundManager->isChannelActive(1)) {
processEvents();
- g_system->delayMillis(10);
}
} else if (tempo == 134) {
//Wait for sound channel 2
while (_soundManager->isChannelActive(2)) {
processEvents();
- g_system->delayMillis(10);
}
}
}
@@ -804,22 +813,29 @@ void Score::processEvents() {
Common::Event event;
- while (g_system->getEventManager()->pollEvent(event)) {
- if (event.type == Common::EVENT_QUIT)
- _stopPlay = true;
+ int endTime = g_system->getMillis() + 200;
- if (event.type == Common::EVENT_LBUTTONDOWN) {
- Common::Point pos = g_system->getEventManager()->getMousePos();
+ while (g_system->getMillis() < endTime) {
+ while (g_system->getEventManager()->pollEvent(event)) {
+ if (event.type == Common::EVENT_QUIT)
+ _stopPlay = true;
- //TODO there is dont send frame id
- _lingo->processEvent(kEventMouseDown, _frames[_currentFrame]->getSpriteIDFromPos(pos));
- }
+ if (event.type == Common::EVENT_LBUTTONDOWN) {
+ Common::Point pos = g_system->getEventManager()->getMousePos();
- if (event.type == Common::EVENT_LBUTTONUP) {
- Common::Point pos = g_system->getEventManager()->getMousePos();
+ //TODO there is dont send frame id
+ _lingo->processEvent(kEventMouseDown, _frames[_currentFrame]->getSpriteIDFromPos(pos));
+ }
- _lingo->processEvent(kEventMouseUp, _frames[_currentFrame]->getSpriteIDFromPos(pos));
+ if (event.type == Common::EVENT_LBUTTONUP) {
+ Common::Point pos = g_system->getEventManager()->getMousePos();
+
+ _lingo->processEvent(kEventMouseUp, _frames[_currentFrame]->getSpriteIDFromPos(pos));
+ }
}
+
+ g_system->updateScreen();
+ g_system->delayMillis(10);
}
}
diff --git a/engines/director/score.h b/engines/director/score.h
index dc6a62b971..a9ac1f97de 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -58,6 +58,7 @@ enum ScriptType {
kMovieScript = 0,
kSpriteScript = 1,
kFrameScript = 2,
+ kNoneScript = -1,
kMaxScriptType = 2
};
@@ -74,6 +75,8 @@ struct BitmapCast : Cast {
uint16 regX;
uint16 regY;
uint8 flags;
+ uint16 someFlaggyThing;
+ uint16 unk1, unk2;
};
enum ShapeType {
@@ -167,7 +170,7 @@ struct Label {
class Score {
public:
- Score(DirectorEngine *vm);
+ Score(DirectorEngine *vm, Archive *);
~Score();
static Common::Rect readRect(Common::SeekableSubReadStreamEndian &stream);
@@ -180,6 +183,7 @@ public:
void startLoop();
void processEvents();
Archive *getArchive() const { return _movieArchive; };
+ void loadConfig(Common::SeekableSubReadStreamEndian &stream);
void loadCastData(Common::SeekableSubReadStreamEndian &stream);
void setCurrentFrame(uint16 frameId) { _currentFrame = frameId; }
Common::String getMacName() const { return _macName; }
@@ -187,7 +191,6 @@ public:
private:
void update();
void readVersion(uint32 rid);
- void loadConfig(Common::SeekableSubReadStreamEndian &stream);
void loadPalette(Common::SeekableSubReadStreamEndian &stream);
void loadFrames(Common::SeekableSubReadStreamEndian &stream);
void loadLabels(Common::SeekableSubReadStreamEndian &stream);
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 7fd5b3d055..77d53ae1da 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -51,6 +51,10 @@ Sprite::Sprite() {
_volume = 0;
_stretch = 0;
_type = kInactiveSprite;
+
+ _cast = nullptr;
+ _blend = 0;
+ _lineSize = 1;
}
Sprite::Sprite(const Sprite &sprite) {
@@ -76,6 +80,13 @@ Sprite::Sprite(const Sprite &sprite) {
_volume = sprite._volume;
_stretch = sprite._stretch;
_type = sprite._type;
+
+ _cast = sprite._cast;
+ _constraint = sprite._constraint;
+ _moveable = sprite._moveable;
+ _blend = sprite._blend;
+ _startTime = sprite._startTime;
+ _lineSize = sprite._lineSize;
}
Sprite::~Sprite() {
diff --git a/engines/fullpipe/behavior.cpp b/engines/fullpipe/behavior.cpp
index faef1672ca..4f70553033 100644
--- a/engines/fullpipe/behavior.cpp
+++ b/engines/fullpipe/behavior.cpp
@@ -49,6 +49,8 @@ void BehaviorManager::clear() {
}
void BehaviorManager::initBehavior(Scene *sc, GameVar *var) {
+ debugC(2, kDebugBehavior, "BehaviorManager::initBehavior(%d, %s)", sc->_sceneId, transCyrillic((byte *)var->_varName));
+
clear();
_scene = sc;
@@ -58,7 +60,10 @@ void BehaviorManager::initBehavior(Scene *sc, GameVar *var) {
if (!behvar)
return;
+ debugC(3, kDebugBehavior, "BehaviorManager::initBehavior. have Variable");
+
for (GameVar *subvar = behvar->_subVars; subvar; subvar = subvar->_nextVarObj) {
+ debugC(3, kDebugBehavior, "BehaviorManager::initBehavior. subVar %s", transCyrillic((byte *)subvar->_varName));
if (!strcmp(subvar->_varName, "AMBIENT")) {
behinfo = new BehaviorInfo;
behinfo->initAmbientBehavior(subvar, sc);
@@ -66,8 +71,8 @@ void BehaviorManager::initBehavior(Scene *sc, GameVar *var) {
_behaviors.push_back(behinfo);
} else {
StaticANIObject *ani = sc->getStaticANIObject1ByName(subvar->_varName, -1);
- if (ani)
- for (uint i = 0; i < sc->_staticANIObjectList1.size(); i++)
+ if (ani) {
+ for (uint i = 0; i < sc->_staticANIObjectList1.size(); i++) {
if (((StaticANIObject *)sc->_staticANIObjectList1[i])->_id == ani->_id) {
behinfo = new BehaviorInfo;
behinfo->initObjectBehavior(subvar, sc, ani);
@@ -75,6 +80,8 @@ void BehaviorManager::initBehavior(Scene *sc, GameVar *var) {
_behaviors.push_back(behinfo);
}
+ }
+ }
}
}
}
@@ -83,7 +90,7 @@ void BehaviorManager::updateBehaviors() {
if (!_isActive)
return;
- debugC(4, kDebugBehavior, "BehaviorManager::updateBehaviors()");
+ debugC(6, kDebugBehavior, "BehaviorManager::updateBehaviors()");
for (uint i = 0; i < _behaviors.size(); i++) {
BehaviorInfo *beh = _behaviors[i];
@@ -122,7 +129,7 @@ void BehaviorManager::updateBehaviors() {
}
void BehaviorManager::updateBehavior(BehaviorInfo *behaviorInfo, BehaviorAnim *entry) {
- debugC(4, kDebugBehavior, "BehaviorManager::updateBehavior() %d", entry->_movesCount);
+ debugC(7, kDebugBehavior, "BehaviorManager::updateBehavior() moves: %d", entry->_movesCount);
for (int i = 0; i < entry->_movesCount; i++) {
BehaviorMove *bhi = entry->_behaviorMoves[i];
if (!(bhi->_flags & 1)) {
@@ -144,7 +151,7 @@ void BehaviorManager::updateBehavior(BehaviorInfo *behaviorInfo, BehaviorAnim *e
}
void BehaviorManager::updateStaticAniBehavior(StaticANIObject *ani, int delay, BehaviorAnim *bhe) {
- debugC(4, kDebugBehavior, "BehaviorManager::updateStaticAniBehavior(%s)", transCyrillic((byte *)ani->_objectName));
+ debugC(6, kDebugBehavior, "BehaviorManager::updateStaticAniBehavior(%s)", transCyrillic((byte *)ani->_objectName));
MessageQueue *mq = 0;
@@ -224,7 +231,7 @@ BehaviorMove *BehaviorManager::getBehaviorMoveByMessageQueueDataId(StaticANIObje
}
void BehaviorInfo::clear() {
- _ani = 0;
+ _ani = NULL;
_staticsId = 0;
_counter = 0;
_counterMax = 0;
@@ -260,7 +267,8 @@ void BehaviorInfo::initAmbientBehavior(GameVar *var, Scene *sc) {
}
void BehaviorInfo::initObjectBehavior(GameVar *var, Scene *sc, StaticANIObject *ani) {
- debugC(4, kDebugBehavior, "BehaviorInfo::initObjectBehavior(%s)", transCyrillic((byte *)var->_varName));
+ Common::String s((char *)transCyrillic((byte *)var->_varName));
+ debugC(4, kDebugBehavior, "BehaviorInfo::initObjectBehavior(%s, %d, %s)", s.c_str(), sc->_sceneId, transCyrillic((byte *)ani->_objectName));
clear();
diff --git a/engines/fullpipe/fullpipe.cpp b/engines/fullpipe/fullpipe.cpp
index 22f2050d16..54a77938c9 100644
--- a/engines/fullpipe/fullpipe.cpp
+++ b/engines/fullpipe/fullpipe.cpp
@@ -55,6 +55,8 @@ FullpipeEngine::FullpipeEngine(OSystem *syst, const ADGameDescription *gameDesc)
DebugMan.addDebugChannel(kDebugBehavior, "behavior", "Behavior");
DebugMan.addDebugChannel(kDebugMemory, "memory", "Memory management");
DebugMan.addDebugChannel(kDebugEvents, "events", "Event handling");
+ DebugMan.addDebugChannel(kDebugInventory, "inventory", "Inventory");
+ DebugMan.addDebugChannel(kDebugSceneLogic, "scenelogic", "Scene Logic");
// Setup mixer
if (!_mixer->isReady()) {
@@ -404,6 +406,7 @@ void FullpipeEngine::updateEvents() {
_lastInputTicks = _updateTicks;
ex->handle();
}
+ _mouseScreenPos = event.mouse;
break;
case Common::EVENT_LBUTTONDOWN:
if (!_inputArFlag && (_updateTicks - _lastInputTicks) >= 2) {
@@ -416,6 +419,7 @@ void FullpipeEngine::updateEvents() {
_lastInputTicks = _updateTicks;
ex->handle();
}
+ _mouseScreenPos = event.mouse;
break;
case Common::EVENT_LBUTTONUP:
if (!_inputArFlag && (_updateTicks - _lastButtonUpTicks) >= 2) {
@@ -424,6 +428,7 @@ void FullpipeEngine::updateEvents() {
_lastButtonUpTicks = _updateTicks;
ex->handle();
}
+ _mouseScreenPos = event.mouse;
break;
default:
break;
diff --git a/engines/fullpipe/fullpipe.h b/engines/fullpipe/fullpipe.h
index 2012d7a344..09c9559199 100644
--- a/engines/fullpipe/fullpipe.h
+++ b/engines/fullpipe/fullpipe.h
@@ -55,7 +55,9 @@ enum {
kDebugAnimation = 1 << 3,
kDebugMemory = 1 << 4,
kDebugEvents = 1 << 5,
- kDebugBehavior = 1 << 6
+ kDebugBehavior = 1 << 6,
+ kDebugInventory = 1 << 7,
+ kDebugSceneLogic = 1 << 8
};
class BehaviorManager;
diff --git a/engines/fullpipe/gfx.cpp b/engines/fullpipe/gfx.cpp
index 174f66a3c8..eba5d442d5 100644
--- a/engines/fullpipe/gfx.cpp
+++ b/engines/fullpipe/gfx.cpp
@@ -290,8 +290,8 @@ bool GameObject::load(MfcArchive &file) {
_id = file.readUint16LE();
_objectName = file.readPascalString();
- _ox = file.readUint32LE();
- _oy = file.readUint32LE();
+ _ox = file.readSint32LE();
+ _oy = file.readSint32LE();
_priority = file.readUint16LE();
if (g_fp->_gameProjectVersion >= 11) {
@@ -353,7 +353,6 @@ bool GameObject::getPicAniInfo(PicAniInfo *info) {
info->ox = _ox;
info->oy = _oy;
info->priority = _priority;
- warning("Yep %d", _id);
return true;
}
@@ -495,8 +494,8 @@ bool Picture::load(MfcArchive &file) {
debugC(5, kDebugLoading, "Picture::load()");
MemoryObject::load(file);
- _x = file.readUint32LE();
- _y = file.readUint32LE();
+ _x = file.readSint32LE();
+ _y = file.readSint32LE();
_field_44 = file.readUint16LE();
assert(g_fp->_gameProjectVersion >= 2);
@@ -786,8 +785,8 @@ Bitmap::~Bitmap() {
void Bitmap::load(Common::ReadStream *s) {
debugC(5, kDebugLoading, "Bitmap::load()");
- _x = s->readUint32LE();
- _y = s->readUint32LE();
+ _x = s->readSint32LE();
+ _y = s->readSint32LE();
_width = s->readUint32LE();
_height = s->readUint32LE();
s->readUint32LE(); // pixels
@@ -806,7 +805,7 @@ bool Bitmap::isPixelHitAtPos(int x, int y) {
if (!_surface)
return false;
- return ((*((int32 *)_surface->getBasePtr(x - _x, y - _y)) & 0xff000000) != 0);
+ return ((*((int32 *)_surface->getBasePtr(x - _x, y - _y)) & 0xff) != 0);
}
void Bitmap::decode(int32 *palette) {
@@ -1139,13 +1138,14 @@ Bitmap *Bitmap::flipVertical() {
}
void Bitmap::drawShaded(int type, int x, int y, byte *palette, int alpha) {
- warning("STUB: Bitmap::drawShaded(%d, %d, %d)", type, x, y);
+ if (alpha != 255)
+ warning("STUB: Bitmap::drawShaded(%d, %d, %d, %d)", type, x, y, alpha);
putDib(x, y, (int32 *)palette, alpha);
}
void Bitmap::drawRotated(int x, int y, int angle, byte *palette, int alpha) {
- warning("STUB: Bitmap::drawShaded(%d, %d, %d)", x, y, angle);
+ warning("STUB: Bitmap::drawRotated(%d, %d, %d, %d)", x, y, angle, alpha);
putDib(x, y, (int32 *)palette, alpha);
}
diff --git a/engines/fullpipe/interaction.cpp b/engines/fullpipe/interaction.cpp
index f0abd0d02c..dc40750fe6 100644
--- a/engines/fullpipe/interaction.cpp
+++ b/engines/fullpipe/interaction.cpp
@@ -450,8 +450,8 @@ bool Interaction::load(MfcArchive &file) {
_objectId3 = file.readUint16LE();
_objectState2 = file.readUint32LE();
_objectState1 = file.readUint32LE();
- _xOffs = file.readUint32LE();
- _yOffs = file.readUint32LE();
+ _xOffs = file.readSint32LE();
+ _yOffs = file.readSint32LE();
_sceneId = file.readUint32LE();
_flags = file.readUint32LE();
_actionName = file.readPascalString();
diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp
index aa229d55d7..f1dafeba7d 100644
--- a/engines/fullpipe/inventory.cpp
+++ b/engines/fullpipe/inventory.cpp
@@ -35,7 +35,7 @@ Inventory::~Inventory() {
}
bool Inventory::load(MfcArchive &file) {
- debugC(5, kDebugLoading, "Inventory::load()");
+ debugC(5, kDebugLoading | kDebugInventory, "Inventory::load()");
_sceneId = file.readUint16LE();
int numInvs = file.readUint32LE();
@@ -119,12 +119,36 @@ void Inventory2::addItem2(StaticANIObject *obj) {
}
void Inventory2::removeItem(int itemId, int count) {
- warning("STUB: Inventory2::removeItem(%d, %d)", itemId, count);
+ debugC(2, kDebugInventory, "Inventory2::removeItem(%d, %d)", itemId, count);
+
+ while (count) {
+ int i;
+ for (i = _inventoryItems.size() - 1; i >= 0; i--) {
+ if (_inventoryItems[i]->itemId == itemId) {
+ if (_selectedId == itemId)
+ unselectItem(false);
+
+ if (_inventoryItems[i]->count > count) {
+ _inventoryItems[i]->count -= count;
+ } else {
+ count -= _inventoryItems[i]->count;
+ _inventoryItems.remove_at(i);
+ }
+
+ if (getCountItemsWithId(itemId) < 0)
+ getInventoryPoolItemFieldCById(itemId);
+
+ break;
+ }
+ }
+ }
}
void Inventory2::removeItem2(Scene *sceneObj, int itemId, int x, int y, int priority) {
int idx = getInventoryItemIndexById(itemId);
+ debugC(2, kDebugInventory, "removeItem2(*, %d, %d, %d, %d)", itemId, x, y, priority);
+
if (idx >= 0) {
if (_inventoryItems[idx]->count) {
removeItem(itemId, 1);
@@ -187,11 +211,15 @@ int Inventory2::getItemFlags(int itemId) {
}
void Inventory2::rebuildItemRects() {
+ debugC(2, kDebugInventory, "rebuildItemRects()");
+
_scene = g_fp->accessScene(_sceneId);
if (!_scene)
return;
+ _inventoryIcons.clear();
+
_picture = _scene->getBigPicture(0, 0);
_picture->setAlpha(50);
diff --git a/engines/fullpipe/lift.cpp b/engines/fullpipe/lift.cpp
index d066c89d4a..93bfbaaa24 100644
--- a/engines/fullpipe/lift.cpp
+++ b/engines/fullpipe/lift.cpp
@@ -392,7 +392,8 @@ void FullpipeEngine::lift_clickButton() {
lift_walkAndGo();
}
-void FullpipeEngine::lift_goAnimation() { if (_lastLiftButton) {
+void FullpipeEngine::lift_goAnimation() {
+ if (_lastLiftButton) {
int parentId = _currentScene->_sceneId;
int buttonId = lift_getButtonIdN(_lastLiftButton->_statics->_staticsId);
@@ -428,6 +429,8 @@ void FullpipeEngine::lift_goAnimation() { if (_lastLiftButton) {
delete mq;
_aniMan->_flags |= 1;
+
+ return;
}
}
}
diff --git a/engines/fullpipe/messages.cpp b/engines/fullpipe/messages.cpp
index 9085e92832..981797cea2 100644
--- a/engines/fullpipe/messages.cpp
+++ b/engines/fullpipe/messages.cpp
@@ -61,8 +61,8 @@ bool ExCommand::load(MfcArchive &file) {
_parentId = file.readUint16LE();
_messageKind = file.readUint32LE();
- _x = file.readUint32LE();
- _y = file.readUint32LE();
+ _x = file.readSint32LE();
+ _y = file.readSint32LE();
_field_14 = file.readUint32LE();
_sceneClickX = file.readUint32LE();
_sceneClickY = file.readUint32LE();
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index 096323781f..382cdfd688 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -309,7 +309,7 @@ bool ModalMap::init(int counterdiff) {
_rect2.right = _rect2.left + 800;
_rect2.bottom = _rect2.top + 600;
- g_fp->_sceneRect =_rect2;
+ g_fp->_sceneRect = _rect2;
_mapScene->updateScrolling2();
@@ -346,17 +346,17 @@ bool ModalMap::handleMessage(ExCommand *cmd) {
_mouseX = g_fp->_mouseScreenPos.x;
_mouseY = g_fp->_mouseScreenPos.x;
- _field_3C = _rect2.top;
_field_38 = _rect2.left;
+ _field_3C = _rect2.top;
- break;
+ return false;
case 30:
_flag = 0;
- break;
+ return false;
case 36:
- if (cmd->_keyCode != 9 && cmd->_keyCode != 27 )
+ if (cmd->_keyCode != 9 && cmd->_keyCode != 27)
return false;
break;
@@ -431,20 +431,20 @@ PictureObject *ModalMap::getScenePicture() {
switch (g_fp->_currentScene->_sceneId) {
case SC_1:
- picId = PIC_MAP_S01;
- break;
+ picId = PIC_MAP_S01;
+ break;
case SC_2:
- picId = PIC_MAP_S02;
- break;
+ picId = PIC_MAP_S02;
+ break;
case SC_3:
- picId = PIC_MAP_S03;
- break;
+ picId = PIC_MAP_S03;
+ break;
case SC_4:
- picId = PIC_MAP_S04;
- break;
+ picId = PIC_MAP_S04;
+ break;
case SC_5:
- picId = PIC_MAP_S05;
- break;
+ picId = PIC_MAP_S05;
+ break;
case SC_6:
picId = PIC_MAP_S06;
break;
@@ -489,7 +489,7 @@ PictureObject *ModalMap::getScenePicture() {
picId = PIC_MAP_S20;
break;
case SC_21:
- picId = PIC_MAP_S21;
+ picId = PIC_MAP_S21;
break;
case SC_22:
picId = PIC_MAP_S22;
diff --git a/engines/fullpipe/motion.cpp b/engines/fullpipe/motion.cpp
index d3b29b324a..81d92ccac8 100644
--- a/engines/fullpipe/motion.cpp
+++ b/engines/fullpipe/motion.cpp
@@ -372,16 +372,16 @@ bool MctlLadder::initMovement(StaticANIObject *ani, MctlLadderMovement *movement
if (!v)
return false;
- v = v->getSubVarByName("Test_Ladder");
+ GameVar *l = v->getSubVarByName("Test_Ladder");
- if (!v)
+ if (!l)
return false;
movement->staticIdsSize = 6;
movement->movVars = new MctlLadderMovementVars;
movement->staticIds = new int[movement->staticIdsSize];
- v = v->getSubVarByName("Up");
+ v = l->getSubVarByName("Up");
if (!v)
return false;
@@ -393,7 +393,7 @@ bool MctlLadder::initMovement(StaticANIObject *ani, MctlLadderMovement *movement
movement->staticIds[0] = ani->getMovementById(movement->movVars->varUpStart)->_staticsObj1->_staticsId;
movement->staticIds[2] = ani->getMovementById(movement->movVars->varUpGo)->_staticsObj1->_staticsId;
- v = v->getSubVarByName("Down");
+ v = l->getSubVarByName("Down");
if (!v)
return false;
@@ -1332,9 +1332,9 @@ double MovGraph::putToLink(Common::Point *point, MovGraphLink *link, int fuzzyMa
int n2x = link->_graphDst->_x;
int n2y = link->_graphDst->_y;
double dist1x = (double)(point->x - n1x);
- double dist1y = (double)(point->y - n1y);
+ double dist1y = (double)(n1y - point->y);
double dist2x = (double)(n2x - n1x);
- double dist2y = (double)(n2y - n1y);
+ double dist2y = (double)(n1y - n2y);
double dist1 = sqrt(dist1x * dist1x + dist1y * dist1y);
double dist2 = (dist2y * dist1y + dist2x * dist1x) / link->_length / dist1;
double distm = dist2 * dist1;
@@ -1355,8 +1355,8 @@ double MovGraph::putToLink(Common::Point *point, MovGraphLink *link, int fuzzyMa
return -1.0;
}
} else {
- point->x = (int)(n1x + (dist2x * distm / link->_length));
- point->y = (int)(n1y + (dist2y * distm / link->_length));
+ point->x = n1x + (int)((double)(n2x - n1x) * distm / link->_length);
+ point->y = n1y + (int)((double)(n2y - n1y) * distm / link->_length);
}
return res;
@@ -2476,7 +2476,7 @@ int MctlGraph::getLinkDir(Common::Array<MovGraphLink *> *linkList, int idx, Comm
}
if (abs(node3->_x - node2->_x) <= abs(node3->_y - node2->_y))
- return (node3->_y < node2->_x) + 2;
+ return (node3->_y < node2->_y) + 2;
else
return node3->_x >= node2->_x;
}
@@ -2918,9 +2918,9 @@ bool MovGraphNode::load(MfcArchive &file) {
debugC(5, kDebugLoading, "MovGraphNode::load()");
_field_14 = file.readUint32LE();
- _x = file.readUint32LE();
- _y = file.readUint32LE();
- _z = file.readUint32LE();
+ _x = file.readSint32LE();
+ _y = file.readSint32LE();
+ _z = file.readSint32LE();
return true;
}
@@ -2937,12 +2937,12 @@ ReactParallel::ReactParallel() {
bool ReactParallel::load(MfcArchive &file) {
debugC(5, kDebugLoading, "ReactParallel::load()");
- _x1 = file.readUint32LE();
- _y1 = file.readUint32LE();
- _x2 = file.readUint32LE();
- _y2 = file.readUint32LE();
- _dx = file.readUint32LE();
- _dy = file.readUint32LE();
+ _x1 = file.readSint32LE();
+ _y1 = file.readSint32LE();
+ _x2 = file.readSint32LE();
+ _y2 = file.readSint32LE();
+ _dx = file.readSint32LE();
+ _dy = file.readSint32LE();
createRegion();
@@ -2995,8 +2995,8 @@ ReactPolygonal::~ReactPolygonal() {
bool ReactPolygonal::load(MfcArchive &file) {
debugC(5, kDebugLoading, "ReactPolygonal::load()");
- _centerX = file.readUint32LE();
- _centerY = file.readUint32LE();
+ _centerX = file.readSint32LE();
+ _centerY = file.readSint32LE();
_pointCount = file.readUint32LE();
if (_pointCount > 0) {
diff --git a/engines/fullpipe/objects.h b/engines/fullpipe/objects.h
index 1849bcb96e..f9a641d562 100644
--- a/engines/fullpipe/objects.h
+++ b/engines/fullpipe/objects.h
@@ -61,6 +61,8 @@ struct PicAniInfo {
int32 someDynamicPhaseIndex;
bool load(MfcArchive &file);
+
+ PicAniInfo() { memset(this, 0, sizeof(PicAniInfo)); }
};
union VarValue {
diff --git a/engines/fullpipe/scene.cpp b/engines/fullpipe/scene.cpp
index b47988d768..70f5f1aa81 100644
--- a/engines/fullpipe/scene.cpp
+++ b/engines/fullpipe/scene.cpp
@@ -601,7 +601,7 @@ StaticANIObject *Scene::getStaticANIObjectAtPos(int x, int y) {
if ((p->_field_8 & 0x100) && (p->_flags & 4) &&
p->getPixelAtPos(x, y, &pixel) &&
- (!res || res->_priority >= p->_priority))
+ (!res || res->_priority > p->_priority))
res = p;
}
diff --git a/engines/fullpipe/scenes/scene03.cpp b/engines/fullpipe/scenes/scene03.cpp
index e6c9fa3bbd..e374c87971 100644
--- a/engines/fullpipe/scenes/scene03.cpp
+++ b/engines/fullpipe/scenes/scene03.cpp
@@ -48,6 +48,8 @@ void FullpipeEngine::setSwallowedEggsState() {
}
void scene03_initScene(Scene *sc) {
+ debugC(1, kDebugSceneLogic, "scene03_initScene()");
+
g_vars->scene03_eggeater = sc->getStaticANIObject1ById(ANI_EGGEATER, -1);
g_vars->scene03_domino = sc->getStaticANIObject1ById(ANI_DOMINO_3, -1);
@@ -60,6 +62,9 @@ void scene03_initScene(Scene *sc) {
g_fp->lift_setButton(sO_Level2, ST_LBN_2N);
g_fp->lift_init(sc, QU_SC3_ENTERLIFT, QU_SC3_EXITLIFT);
+
+ debugC(2, kDebugSceneLogic, "scene03: egg1: %d egg2: %d egg3: %d", g_vars->swallowedEgg1->_value.intValue,
+ g_vars->swallowedEgg2->_value.intValue, g_vars->swallowedEgg3->_value.intValue);
}
void scene03_setEaterState() {
@@ -90,10 +95,13 @@ void sceneHandler03_eaterFat() {
void sceneHandler03_swallowEgg(int item) {
if (!g_vars->swallowedEgg1->_value.intValue) {
g_vars->swallowedEgg1->_value.intValue = item;
+ debugC(2, kDebugSceneLogic, "scene03: setting egg1: %d", g_vars->swallowedEgg1->_value.intValue);
} else if (!g_vars->swallowedEgg2->_value.intValue) {
g_vars->swallowedEgg2->_value.intValue = item;
+ debugC(2, kDebugSceneLogic, "scene03: setting egg2: %d", g_vars->swallowedEgg2->_value.intValue);
} else if (!g_vars->swallowedEgg3->_value.intValue) {
g_vars->swallowedEgg3->_value.intValue = item;
+ debugC(2, kDebugSceneLogic, "scene03: setting egg3: %d", g_vars->swallowedEgg3->_value.intValue);
g_fp->setObjectState(sO_EggGulperGaveCoin, g_fp->getObjectEnumState(sO_EggGulperGaveCoin, sO_Yes));
diff --git a/engines/fullpipe/scenes/scene04.cpp b/engines/fullpipe/scenes/scene04.cpp
index d901d74289..b6239c219f 100644
--- a/engines/fullpipe/scenes/scene04.cpp
+++ b/engines/fullpipe/scenes/scene04.cpp
@@ -60,6 +60,10 @@ void scene04_speakerCallback(int *phase) {
}
}
+void scene04_springCallback(int *phase) {
+ // do nothing
+}
+
void scene04_initScene(Scene *sc) {
g_vars->scene04_dudeOnLadder = false;
g_vars->scene04_bottle = sc->getPictureObjectById(PIC_SC4_BOTTLE, 0);
@@ -127,7 +131,7 @@ void scene04_initScene(Scene *sc) {
StaticANIObject *spring = sc->getStaticANIObject1ById(ANI_SPRING, -1);
if (spring)
- spring->_callback2 = 0;
+ spring->_callback2 = scene04_springCallback;
g_vars->scene04_bottleObjList.clear();
g_vars->scene04_bottleObjList.push_back(sc->getPictureObjectById(PIC_SC4_BOTTLE, 0));
@@ -949,7 +953,8 @@ void sceneHandler04_springWobble() {
if (g_vars->scene04_bottleWeight < newdelta)
g_vars->scene04_springOffset--;
- if ((oldDynIndex <= g_vars->scene04_bottleWeight && newdelta > g_vars->scene04_bottleWeight) || newdelta <= g_vars->scene04_bottleWeight) {
+ if ((oldDynIndex <= g_vars->scene04_bottleWeight && newdelta > g_vars->scene04_bottleWeight)
+ || (oldDynIndex > g_vars->scene04_bottleWeight && newdelta <= g_vars->scene04_bottleWeight)) {
g_vars->scene04_springDelay++;
if (g_vars->scene04_springOffset && g_vars->scene04_springDelay > 1) {
diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
index c95f6c67f3..02053aa94e 100644
--- a/engines/fullpipe/stateloader.cpp
+++ b/engines/fullpipe/stateloader.cpp
@@ -350,8 +350,8 @@ bool PicAniInfo::load(MfcArchive &file) {
field_8 = file.readUint32LE();
sceneId = file.readUint16LE();
field_E = file.readUint16LE();
- ox = file.readUint32LE();
- oy = file.readUint32LE();
+ ox = file.readSint32LE();
+ oy = file.readSint32LE();
priority = file.readUint32LE();
staticsId = file.readUint16LE();
movementId = file.readUint16LE();
diff --git a/engines/fullpipe/statics.cpp b/engines/fullpipe/statics.cpp
index 22be04b393..1f25bfb46e 100644
--- a/engines/fullpipe/statics.cpp
+++ b/engines/fullpipe/statics.cpp
@@ -108,20 +108,22 @@ bool StepArray::gotoNextPoint() {
void StepArray::insertPoints(Common::Point **points, int pointsCount) {
if (_currPointIndex + pointsCount >= _pointsCount) {
- _points = (Common::Point **)realloc(_points, sizeof(Common::Point *) * (_currPointIndex + pointsCount));
+ _points = (Common::Point **)realloc(_points, sizeof(Common::Point *) * (_pointsCount + pointsCount));
if (!_points) {
error("Out of memory at StepArray::insertPoints()");
}
+
+ for(int i = 0; i < pointsCount; i++)
+ _points[_pointsCount + i] = new Common::Point;
+
+ _pointsCount += pointsCount;
}
_maxPointIndex = _currPointIndex + pointsCount;
- for (int i = 0; i < pointsCount; i++) {
- _points[_currPointIndex + i] = new Common::Point;
-
+ for (int i = 0; i < pointsCount; i++)
*_points[_currPointIndex + i] = *points[i];
- }
}
StaticANIObject::StaticANIObject() {
@@ -831,7 +833,7 @@ void StaticANIObject::update(int counterdiff) {
}
}
- if (dyn->_initialCountdown != dyn->_countdown || dyn->_field_68 == 0) {
+ if (dyn->_initialCountdown == dyn->_countdown && dyn->_field_68 != 0) {
newex = new ExCommand(_id, 17, dyn->_field_68, 0, 0, 0, 1, 0, 0, 0);
newex->_excFlags = 2;
newex->_keyCode = _okeyCode;
@@ -952,7 +954,7 @@ Common::Point *StaticANIObject::calcNextStep(Common::Point *pRes) {
}
void StaticANIObject::stopAnim_maybe() {
- debugC(6, kDebugAnimation, "StaticANIObject::stopAnim_maybe()");
+ debugC(2, kDebugAnimation, "StaticANIObject::stopAnim_maybe()");
if (!(_flags & 1))
return;
@@ -967,7 +969,10 @@ void StaticANIObject::stopAnim_maybe() {
setOXY(_movement->_ox, _movement->_oy);
if (_flags & 0x40) {
- if (!_movement->_currMovement && !_movement->_currDynamicPhaseIndex) {
+ if (!_movement->_currMovement) {
+ if (_movement->_currDynamicPhaseIndex)
+ goto L11;
+L8:
_statics = _movement->_staticsObj1;
_movement->getCurrDynamicPhaseXY(point);
_ox -= point.x;
@@ -985,13 +990,14 @@ void StaticANIObject::stopAnim_maybe() {
_ox += point.x;
_oy += point.y;
}
- } else {
- _statics = _movement->_staticsObj2;
+ goto L12;
}
- } else {
- _statics = _movement->_staticsObj2;
+ if (!_movement->_currDynamicPhaseIndex)
+ goto L8;
}
-
+L11:
+ _statics = _movement->_staticsObj2;
+L12:
_statics->getSomeXY(point);
_statics->_x = _ox - point.x;
@@ -1697,8 +1703,8 @@ bool Movement::load(MfcArchive &file, StaticANIObject *ani) {
_staticsObj1 = ani->addReverseStatics(s);
}
- _mx = file.readUint32LE();
- _my = file.readUint32LE();
+ _mx = file.readSint32LE();
+ _my = file.readSint32LE();
staticsid = file.readUint16LE();
@@ -1709,8 +1715,8 @@ bool Movement::load(MfcArchive &file, StaticANIObject *ani) {
_staticsObj2 = ani->addReverseStatics(s);
}
- _m2x = file.readUint32LE();
- _m2y = file.readUint32LE();
+ _m2x = file.readSint32LE();
+ _m2y = file.readSint32LE();
if (_staticsObj2) {
_dynamicPhases.push_back(_staticsObj2);
@@ -2148,11 +2154,17 @@ void Movement::gotoFirstFrame() {
void Movement::gotoLastFrame() {
if (_currMovement) {
- while ((uint)_currDynamicPhaseIndex != _currMovement->_dynamicPhases.size() - 1)
- gotoNextFrame(0, 0);
+ if ((uint)_currDynamicPhaseIndex != _currMovement->_dynamicPhases.size() - 1) {
+ do {
+ gotoNextFrame(0, 0);
+ } while ((uint)_currDynamicPhaseIndex != _currMovement->_dynamicPhases.size() - 1);
+ }
} else {
- while ((uint)_currDynamicPhaseIndex != _dynamicPhases.size() - 1)
- gotoNextFrame(0, 0);
+ if ((uint)_currDynamicPhaseIndex != _dynamicPhases.size() - 1) {
+ do {
+ gotoNextFrame(0, 0);
+ } while ((uint)_currDynamicPhaseIndex != _dynamicPhases.size() - 1);
+ }
}
}
@@ -2261,17 +2273,17 @@ bool DynamicPhase::load(MfcArchive &file) {
_field_7C = file.readUint16LE();
_rect = new Common::Rect();
- _rect->left = file.readUint32LE();
- _rect->top = file.readUint32LE();
- _rect->right = file.readUint32LE();
- _rect->bottom = file.readUint32LE();
+ _rect->left = file.readSint32LE();
+ _rect->top = file.readSint32LE();
+ _rect->right = file.readSint32LE();
+ _rect->bottom = file.readSint32LE();
- assert (g_fp->_gameProjectVersion >= 1);
+ assert(g_fp->_gameProjectVersion >= 1);
- _someX = file.readUint32LE();
- _someY = file.readUint32LE();
+ _someX = file.readSint32LE();
+ _someY = file.readSint32LE();
- assert (g_fp->_gameProjectVersion >= 12);
+ assert(g_fp->_gameProjectVersion >= 12);
_dynFlags = file.readUint32LE();
diff --git a/engines/fullpipe/utils.cpp b/engines/fullpipe/utils.cpp
index a8e00468b5..148f779d1e 100644
--- a/engines/fullpipe/utils.cpp
+++ b/engines/fullpipe/utils.cpp
@@ -84,7 +84,7 @@ bool DWordArray::load(MfcArchive &file) {
resize(count);
for (int i = 0; i < count; i++) {
- int32 t = file.readUint32LE();
+ int32 t = file.readSint32LE();
push_back(t);
}
diff --git a/engines/kyra/animator_tim.cpp b/engines/kyra/animator_tim.cpp
index 1d65ba7b1a..b1cfc6a6a8 100644
--- a/engines/kyra/animator_tim.cpp
+++ b/engines/kyra/animator_tim.cpp
@@ -202,6 +202,9 @@ void TimAnimator::playPart(int animIndex, int firstFrame, int lastFrame, int del
return;
Animation *anim = &_animations[animIndex];
+ // WORKAROUND for some bugged scripts that will try to play invalid animations
+ if (!anim->wsa)
+ return;
int step = (lastFrame >= firstFrame) ? 1 : -1;
for (int i = firstFrame; i != (lastFrame + step); i += step) {
diff --git a/engines/sci/engine/file.cpp b/engines/sci/engine/file.cpp
index 156f6f51f7..8cecd8c82c 100644
--- a/engines/sci/engine/file.cpp
+++ b/engines/sci/engine/file.cpp
@@ -200,7 +200,7 @@ reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool u
#ifdef ENABLE_SCI32
if (mode != _K_FILE_MODE_OPEN_OR_FAIL && (
- (g_sci->getGameId() == GID_PHANTASMAGORIA && filename == "phantsg.dir") ||
+ (g_sci->getGameId() == GID_PHANTASMAGORIA && (filename == "phantsg.dir" || filename == "chase.dat")) ||
(g_sci->getGameId() == GID_PQSWAT && filename == "swat.dat"))) {
debugC(kDebugLevelFile, " -> file_open opening %s for rewriting", wrappedName.c_str());
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index b6c35dca73..6e141e7f3b 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -183,8 +183,8 @@ static const SciKernelMapSubEntry kDoSound_subops[] = {
};
#ifdef ENABLE_SCI32
-// NOTE: In SSCI, some 'unused' kDoAudio subops are actually
-// called indirectly by kDoSound:
+// NOTE: In SSCI, some 'unused' kDoAudio subops are actually called indirectly
+// by kDoSound:
//
// kDoSoundGetAudioCapability -> kDoAudioGetCapability
// kDoSoundPlay -> kDoAudioPlay, kDoAudioStop
@@ -194,23 +194,26 @@ static const SciKernelMapSubEntry kDoSound_subops[] = {
// kDoSoundSetLoop -> kDoAudioSetLoop
// kDoSoundUpdateCues -> kDoAudioPosition
//
-// In ScummVM, logic inside these kernel functions has been
-// moved to methods of Audio32, and direct calls to Audio32
-// are made from kDoSound instead.
+// In ScummVM, logic inside these kernel functions has been moved to methods of
+// Audio32, and direct calls to Audio32 are made from kDoSound instead.
//
-// Some kDoAudio methods are esoteric and appear to be used
-// only by one or two games:
+// Some kDoAudio methods are esoteric and appear to be used only by one or two
+// games:
//
-// kDoAudioMixing: Phantasmagoria (other games call this
-// function, but only to disable the feature)
-// kDoAudioHasSignal: SQ6 TalkRandCycle
-// kDoAudioPan: Rama RegionSFX::pan method
+// - kDoAudioMixing: Phantasmagoria (other games call this function, but only
+// to disable the feature)
+// - kDoAudioHasSignal: SQ6 TalkRandCycle
+// - kDoAudioPan: Rama RegionSFX::pan method
+// - kDoAudioCritical: Phantasmagoria, chapter 3, nursery (room 14200), during
+// the "ghost lullaby" event. It is used to make the
+// lullaby sound exclusive, but it really doesn't make any
+// major difference. Returning 0 means "non-critical", i.e.
+// normal audio behavior.
//
-// Finally, there is a split in SCI2.1mid audio code.
-// QFG4CD & SQ6 do not have opcodes 18 and 19, but they
-// exist in GK2, KQ7 2.00b, Phantasmagoria 1, PQ:SWAT, and
-// Torin. (It is unknown if they exist in MUMG Deluxe or
-// Shivers 1; they are not used in either of these games.)
+// Finally, there is a split in SCI2.1mid audio code. QFG4CD & SQ6 do not have
+// opcodes 18 and 19, but they exist in GK2, KQ7 2.00b, Phantasmagoria 1,
+// PQ:SWAT, and Torin. It is unknown if they exist in MUMG Deluxe or Shivers 1;
+// they are not used in either of these games.
// version, subId, function-mapping, signature, workarounds
static const SciKernelMapSubEntry kDoAudio_subops[] = {
@@ -235,7 +238,7 @@ static const SciKernelMapSubEntry kDoAudio_subops[] = {
{ SIG_SINCE_SCI21MID, 15, MAP_CALL(DoAudioFade), "(iiii)(i)(i)", NULL },
{ SIG_SINCE_SCI21MID, 16, MAP_DUMMY(DoAudioFade36), "iiiii(iii)(i)", NULL },
{ SIG_SINCE_SCI21MID, 17, MAP_CALL(DoAudioHasSignal), "", NULL },
- { SIG_SINCE_SCI21MID, 18, MAP_EMPTY(DoAudioCritical), "", NULL },
+ { SIG_SINCE_SCI21MID, 18, MAP_EMPTY(DoAudioCritical), "(i)", NULL },
{ SIG_SINCE_SCI21MID, 19, MAP_CALL(DoAudioSetLoop), "iii(o)", NULL },
{ SIG_SCI3, 20, MAP_DUMMY(DoAudioPan), "", NULL },
{ SIG_SCI3, 21, MAP_DUMMY(DoAudioPanOff), "", NULL },
@@ -377,7 +380,7 @@ static const SciKernelMapSubEntry kText_subops[] = {
// version, subId, function-mapping, signature, workarounds
static const SciKernelMapSubEntry kBitmap_subops[] = {
{ SIG_SINCE_SCI21, 0, MAP_CALL(BitmapCreate), "iiii(i)(i)(i)", NULL },
- { SIG_SINCE_SCI21, 1, MAP_CALL(BitmapDestroy), "r", NULL },
+ { SIG_SINCE_SCI21, 1, MAP_CALL(BitmapDestroy), "[r!]", NULL },
{ SIG_SINCE_SCI21, 2, MAP_CALL(BitmapDrawLine), "riiiii(i)(i)", NULL },
{ SIG_SINCE_SCI21, 3, MAP_CALL(BitmapDrawView), "riii(i)(i)(0)(i)(i)", NULL },
{ SIG_SINCE_SCI21, 4, MAP_CALL(BitmapDrawText), "rriiiiiiiiiii", NULL },
@@ -502,7 +505,7 @@ static const SciKernelMapSubEntry kString_subops[] = {
{ SIG_SCI32, 0, MAP_CALL(StringNew), "i(i)", NULL },
{ SIG_SCI32, 1, MAP_CALL(StringSize), "[or]", NULL },
{ SIG_SCI32, 2, MAP_CALL(StringAt), "[or]i", NULL },
- { SIG_SCI32, 3, MAP_CALL(StringPutAt), "[or]i(i*)", NULL },
+ { SIG_SCI32, 3, MAP_CALL(StringPutAt), "[or]i(i*)", kStringPutAt_workarounds },
// StringFree accepts invalid references
{ SIG_SCI32, 4, MAP_CALL(StringFree), "[or0!]", NULL },
{ SIG_SCI32, 5, MAP_CALL(StringFill), "[or]ii", NULL },
@@ -812,7 +815,7 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_CALL(CreateTextBitmap), SIG_EVERYWHERE, "i(.*)", NULL, NULL },
{ MAP_CALL(DeletePlane), SIG_EVERYWHERE, "o", NULL, NULL },
{ MAP_CALL(DeleteScreenItem), SIG_EVERYWHERE, "o", NULL, NULL },
- { "DisposeTextBitmap", kBitmapDestroy, SIG_SCI2, SIGFOR_ALL, "r", NULL, NULL },
+ { "DisposeTextBitmap", kBitmapDestroy, SIG_SCI2, SIGFOR_ALL, "[r!]", NULL, NULL },
{ MAP_CALL(FrameOut), SIG_EVERYWHERE, "(i)", NULL, NULL },
{ MAP_CALL(GetHighPlanePri), SIG_EVERYWHERE, "", NULL, NULL },
{ MAP_CALL(InPolygon), SIG_EVERYWHERE, "iio", NULL, NULL },
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index e5b0aaf47a..e8b9d0461d 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -632,6 +632,15 @@ reg_t kFileIORename(EngineState *s, int argc, reg_t *argv) {
Common::String oldName = s->_segMan->getString(argv[0]);
Common::String newName = s->_segMan->getString(argv[1]);
+ // We don't fully implement all cases that could occur here, and
+ // assume the file to be renamed is a wrapped filename.
+ // Known usage: In Phant1 and KQ7 while deleting savegames.
+ // The scripts rewrite the dir file as a temporary file, and then
+ // rename it to the actual dir file.
+
+ oldName = g_sci->wrapFilename(oldName);
+ newName = g_sci->wrapFilename(newName);
+
// SCI1.1 returns 0 on success and a DOS error code on fail. SCI32
// returns -1 on fail. We just return -1 for all versions.
if (g_sci->getSaveFileManager()->renameSavefile(oldName, newName))
diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp
index f3eec59eaf..a33fcf3167 100644
--- a/engines/sci/engine/kgraphics32.cpp
+++ b/engines/sci/engine/kgraphics32.cpp
@@ -647,7 +647,16 @@ reg_t kBitmapCreate(EngineState *s, int argc, reg_t *argv) {
}
reg_t kBitmapDestroy(EngineState *s, int argc, reg_t *argv) {
- s->_segMan->freeBitmap(argv[0]);
+ const reg_t &addr = argv[0];
+ const SegmentObj *const segment = s->_segMan->getSegmentObj(addr.getSegment());
+
+ if (segment != nullptr &&
+ segment->getType() == SEG_TYPE_BITMAP &&
+ segment->isValidOffset(addr.getOffset())) {
+
+ s->_segMan->freeBitmap(addr);
+ }
+
return s->r_acc;
}
@@ -907,7 +916,7 @@ reg_t kPaletteFindColor32(EngineState *s, int argc, reg_t *argv) {
*/
reg_t kPaletteSetGamma(EngineState *s, int argc, reg_t *argv) {
const uint8 gamma = argv[0].toUint16();
- assert(gamma >= 0 && gamma <= 6);
+ assert(gamma <= 6);
warning("TODO: kPaletteSetGamma(%d)", gamma);
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index eeddda8390..be2d7660cb 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -427,6 +427,7 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) {
if (getSciVersion() >= SCI_VERSION_2) {
g_sci->_gfxPalette32->saveLoadWithSerializer(s);
g_sci->_gfxRemap32->saveLoadWithSerializer(s);
+ g_sci->_gfxCursor32->saveLoadWithSerializer(s);
} else
#endif
g_sci->_gfxPalette16->saveLoadWithSerializer(s);
@@ -892,11 +893,15 @@ void GfxRemap32::saveLoadWithSerializer(Common::Serializer &s) {
}
void GfxCursor32::saveLoadWithSerializer(Common::Serializer &s) {
- if (s.getVersion() < 37) {
+ if (s.getVersion() < 38) {
return;
}
- s.syncAsSint32LE(_hideCount);
+ int32 hideCount;
+ if (s.isSaving()) {
+ hideCount = _hideCount;
+ }
+ s.syncAsSint32LE(hideCount);
s.syncAsSint16LE(_restrictedArea.left);
s.syncAsSint16LE(_restrictedArea.top);
s.syncAsSint16LE(_restrictedArea.right);
@@ -908,8 +913,10 @@ void GfxCursor32::saveLoadWithSerializer(Common::Serializer &s) {
if (s.isLoading()) {
hide();
setView(_cursorInfo.resourceId, _cursorInfo.loopNo, _cursorInfo.celNo);
- if (!_hideCount) {
+ if (!hideCount) {
show();
+ } else {
+ _hideCount = hideCount;
}
}
}
diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h
index 51dbbedd87..6616081a20 100644
--- a/engines/sci/engine/savegame.h
+++ b/engines/sci/engine/savegame.h
@@ -37,7 +37,8 @@ struct EngineState;
*
* Version - new/changed feature
* =============================
- * 37 - Segment entry data changed to pointers, SCI32 cursor
+ * 38 - SCI32 cursor
+ * 37 - Segment entry data changed to pointers
* 36 - SCI32 bitmap segment
* 35 - SCI32 remap
* 34 - SCI32 palettes, and store play time in ticks
@@ -62,7 +63,7 @@ struct EngineState;
*/
enum {
- CURRENT_SAVEGAME_VERSION = 37,
+ CURRENT_SAVEGAME_VERSION = 38,
MINIMUM_SAVEGAME_VERSION = 14
};
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index e6eed0b4b7..d45c689985 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -746,12 +746,115 @@ static const uint16 gk1PatchInterrogationBug[] = {
PATCH_END
};
-// script, description, signature patch
+// On day 10 nearly at the end of the game, Gabriel Knight dresses up and right after that
+// someone will be at the door. Gabriel turns around to see what's going on.
+//
+// In ScummVM Gabriel turning around plays endlessly. This is caused by the loop of Gabriel
+// being kept at 1, but view + cel were changed accordingly. The view used - which is view 859 -
+// does not have a loop 1. kNumCels is called on that, BUT kNumCels in SSCI is broken in that
+// regard. It checks for loop > count and not loop >= count and will return basically random data
+// in case loop == count.
+//
+// In SSCI this simply worked by accident. kNumCels returned 0x53 in this case, but later script code
+// fixed that up somehow, so it worked out in the end.
+//
+// The setup for this is done in SDJEnters::changeState(0). The cycler will never reach the goal
+// because the goal will be cel -1, so it loops endlessly.
+//
+// We fix this by adding a setLoop(0).
+//
+// Applies to at least: English PC-CD, German PC-CD
+// Responsible method: sDJEnters::changeState
+static const uint16 gk1SignatureDay10GabrielDressUp[] = {
+ 0x87, 0x01, // lap param[1]
+ 0x65, 0x14, // aTop state
+ 0x36, // push
+ 0x3c, // dup
+ 0x35, 0x00, // ldi 0
+ 0x1a, // eq?
+ 0x30, SIG_UINT16(0x006f), // bnt [next state 1]
+ SIG_ADDTOOFFSET(+84),
+ 0x39, 0x0e, // pushi 0Eh (view)
+ 0x78, // push1
+ SIG_MAGICDWORD,
+ 0x38, SIG_UINT16(0x035B), // pushi 035Bh (859d)
+ 0x38, SIG_UINT16(0x0141), // pushi 0141h (setCel)
+ 0x78, // push1
+ 0x76, // push0
+ 0x38, SIG_UINT16(0x00E9), // pushi 00E9h (setCycle)
+ 0x7a, // push2
+ 0x51, 0x18, // class End
+ 0x36, // push
+ 0x7c, // pushSelf
+ 0x81, 0x00, // lag global[0]
+ 0x4a, 0x14, 0x00, // send 14h
+ // GKEgo::view(859)
+ // GKEgo::setCel(0)
+ // GKEgo::setCycle(End, sDJEnters)
+ 0x32, SIG_UINT16(0x0233), // jmp [ret]
+ // next state
+ 0x3c, // dup
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ 0x31, 0x07, // bnt [next state 2]
+ 0x35, 0x02, // ldi 02
+ 0x65, 0x1a, // aTop cycles
+ 0x32, SIG_UINT16(0x0226), // jmp [ret]
+ // next state
+ 0x3c, // dup
+ 0x35, 0x02, // ldi 02
+ 0x1a, // eq?
+ 0x31, 0x2a, // bnt [next state 3]
+ 0x78, // push1
+ SIG_ADDTOOFFSET(+34),
+ // part of state 2 code, delays for 1 cycle
+ 0x35, 0x01, // ldi 1
+ 0x65, 0x1a, // aTop cycles
+ SIG_END
+};
+
+static const uint16 gk1PatchDay10GabrielDressUp[] = {
+ PATCH_ADDTOOFFSET(+9),
+ 0x30, SIG_UINT16(0x0073), // bnt [next state 1] - offset adjusted
+ SIG_ADDTOOFFSET(+84 + 11),
+ // added by us: setting loop to 0 (5 bytes needed)
+ 0x38, SIG_UINT16(0x00FB), // pushi 00FBh (setLoop)
+ 0x78, // push1
+ 0x76, // push0
+ // original code, but offset changed
+ 0x38, SIG_UINT16(0x00E9), // pushi 00E9h (setCycle)
+ 0x7a, // push2
+ 0x51, 0x18, // class End
+ 0x36, // push
+ 0x7c, // pushSelf
+ 0x81, 0x00, // lag global[0]
+ 0x4a, 0x1a, 0x00, // send 1Ah - adjusted
+ // GKEgo::view(859)
+ // GKEgo::setCel(0)
+ // GKEgo::setLoop(0) <-- new, by us
+ // GKEgo::setCycle(End, sDJEnters)
+ // end of original code
+ 0x3a, // toss
+ 0x48, // ret (saves 1 byte)
+ // state 1 code
+ 0x3c, // dup
+ 0x34, SIG_UINT16(0x0001), // ldi 0001 (waste 1 byte)
+ 0x1a, // eq?
+ 0x31, 2, // bnt [next state 2]
+ 0x33, 41, // jmp to state 2 delay code
+ SIG_ADDTOOFFSET(+41),
+ // wait 2 cycles instead of only 1
+ 0x35, 0x02, // ldi 2
+ PATCH_END
+};
+
+// script, description, signature patch
static const SciScriptPatcherEntry gk1Signatures[] = {
- { true, 51, "interrogation bug", 1, gk1SignatureInterrogationBug, gk1PatchInterrogationBug },
- { true, 212, "day 5 phone freeze", 1, gk1SignatureDay5PhoneFreeze, gk1PatchDay5PhoneFreeze },
- { true, 230, "day 6 police beignet timer issue", 1, gk1SignatureDay6PoliceBeignet, gk1PatchDay6PoliceBeignet },
- { true, 230, "day 6 police sleep timer issue", 1, gk1SignatureDay6PoliceSleep, gk1PatchDay6PoliceSleep },
+ { true, 51, "interrogation bug", 1, gk1SignatureInterrogationBug, gk1PatchInterrogationBug },
+ { true, 212, "day 5 phone freeze", 1, gk1SignatureDay5PhoneFreeze, gk1PatchDay5PhoneFreeze },
+ { true, 230, "day 6 police beignet timer issue", 1, gk1SignatureDay6PoliceBeignet, gk1PatchDay6PoliceBeignet },
+ { true, 230, "day 6 police sleep timer issue", 1, gk1SignatureDay6PoliceSleep, gk1PatchDay6PoliceSleep },
+ { true, 808, "day 10 gabriel dress up infinite turning", 1, gk1SignatureDay10GabrielDressUp, gk1PatchDay10GabrielDressUp },
SCI_SIGNATUREENTRY_TERMINATOR
};
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index 8e0a90079c..7aaea0902a 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -767,6 +767,11 @@ const SciWorkaroundEntry kUnLoad_workarounds[] = {
};
// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
+const SciWorkaroundEntry kStringPutAt_workarounds[] = {
+ { GID_PHANTASMAGORIA,902, 64918, 0, "Str", "callKernel", NULL, 0, { WORKAROUND_IGNORE, 0 } }, // When starting a new game from after chapter 1, the game tries to save ego's object in a string
+};
+
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kScrollWindowAdd_workarounds[] = {
{ GID_PHANTASMAGORIA, 45, 64907, 0, "ScrollableWindow", "addString", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // ScrollWindow interface passes the last two parameters twice
};
diff --git a/engines/sci/engine/workarounds.h b/engines/sci/engine/workarounds.h
index f2b2e55ef6..2cccd05475 100644
--- a/engines/sci/engine/workarounds.h
+++ b/engines/sci/engine/workarounds.h
@@ -100,6 +100,7 @@ extern const SciWorkaroundEntry kStrAt_workarounds[];
extern const SciWorkaroundEntry kStrCpy_workarounds[];
extern const SciWorkaroundEntry kStrLen_workarounds[];
extern const SciWorkaroundEntry kUnLoad_workarounds[];
+extern const SciWorkaroundEntry kStringPutAt_workarounds[];
extern const SciWorkaroundEntry kScrollWindowAdd_workarounds[];
extern SciWorkaroundSolution trackOriginAndFindWorkaround(int index, const SciWorkaroundEntry *workaroundList, SciTrackOriginReply *trackOrigin);
diff --git a/engines/sci/graphics/celobj32.cpp b/engines/sci/graphics/celobj32.cpp
index d053fa2eef..d67a4dc03c 100644
--- a/engines/sci/graphics/celobj32.cpp
+++ b/engines/sci/graphics/celobj32.cpp
@@ -872,7 +872,7 @@ CelObjView::CelObjView(const GuiResourceId viewId, const int16 loopNo, const int
_scaledWidth = READ_SCI11ENDIAN_UINT16(data + 14);
_scaledHeight = READ_SCI11ENDIAN_UINT16(data + 16);
- if (_scaledWidth == 0 || _scaledHeight == 0) {
+ if (_scaledWidth == 0 && _scaledHeight == 0) {
byte sizeFlag = data[5];
if (sizeFlag == 0) {
_scaledWidth = kLowResX;
@@ -894,7 +894,7 @@ CelObjView::CelObjView(const GuiResourceId viewId, const int16 loopNo, const int
// NOTE: This is the actual check, in the actual location,
// from SCI engine.
if (loopNo < 0) {
- error("Loop is less than 0!");
+ error("Loop is less than 0");
}
const uint16 viewHeaderSize = READ_SCI11ENDIAN_UINT16(data);
@@ -916,8 +916,17 @@ CelObjView::CelObjView(const GuiResourceId viewId, const int16 loopNo, const int
_info.celNo = celCount - 1;
}
- if (_info.celNo < 0) {
- error("Cel is less than 0!");
+ // A celNo can be negative and still valid. At least PQ4CD uses this strange
+ // arrangement to load its high-resolution main menu resource. In PQ4CD, the
+ // low-resolution menu is at view 23, loop 9, cel 0, and the high-resolution
+ // menu is at view 2300, loop 0, cel 0. View 2300 is specially crafted to
+ // have 2 loops, with the second loop having 0 cels. When in high-resolution
+ // mode, the game scripts only change the view resource ID from 23 to 2300,
+ // leaving loop 9 and cel 0 the same. The code in CelObjView constructor
+ // auto-corrects loop 9 to loop 1, and then auto-corrects the cel number
+ // from 0 to -1, which effectively causes loop 0, cel 0 to be read.
+ if (_info.celNo < 0 && _info.loopNo == 0) {
+ error("Cel is less than 0 on loop 0");
}
_hunkPaletteOffset = READ_SCI11ENDIAN_UINT32(data + 8);
diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp
index f81d50946b..11572581ff 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -211,12 +211,12 @@ void GfxText32::drawChar(const char charIndex) {
SciBitmap &bitmap = *_segMan->lookupBitmap(_bitmap);
byte *pixels = bitmap.getPixels();
- _font->drawToBuffer(charIndex, _drawPosition.y, _drawPosition.x, _foreColor, _dimmed, pixels, _width, _height);
- _drawPosition.x += _font->getCharWidth(charIndex);
+ _font->drawToBuffer((unsigned char)charIndex, _drawPosition.y, _drawPosition.x, _foreColor, _dimmed, pixels, _width, _height);
+ _drawPosition.x += _font->getCharWidth((unsigned char)charIndex);
}
uint16 GfxText32::getCharWidth(const char charIndex, const bool doScaling) const {
- uint16 width = _font->getCharWidth(charIndex);
+ uint16 width = _font->getCharWidth((unsigned char)charIndex);
if (doScaling) {
width = scaleUpWidth(width);
}
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index 900dabe05a..86c0cffe15 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -923,14 +923,19 @@ Common::String SciEngine::getFilePrefix() const {
}
Common::String SciEngine::wrapFilename(const Common::String &name) const {
- return getFilePrefix() + "-" + name;
+ Common::String prefix = getFilePrefix() + "-";
+ if (name.hasPrefix(prefix.c_str()))
+ return name;
+ else
+ return prefix + name;
}
Common::String SciEngine::unwrapFilename(const Common::String &name) const {
Common::String prefix = getFilePrefix() + "-";
if (name.hasPrefix(prefix.c_str()))
return Common::String(name.c_str() + prefix.size());
- return name;
+ else
+ return name;
}
const char *SciEngine::getGameObjectName() {
diff --git a/engines/sci/video/robot_decoder.cpp b/engines/sci/video/robot_decoder.cpp
index f3354f9e44..1757088ea4 100644
--- a/engines/sci/video/robot_decoder.cpp
+++ b/engines/sci/video/robot_decoder.cpp
@@ -533,7 +533,6 @@ void RobotDecoder::initRecordAndCuePositions() {
void RobotDecoder::open(const GuiResourceId robotId, const reg_t plane, const int16 priority, const int16 x, const int16 y, const int16 scale) {
if (_status != kRobotStatusUninitialized) {
- warning("Last robot was not closed");
close();
}
diff --git a/engines/titanic/carry/bridge_piece.cpp b/engines/titanic/carry/bridge_piece.cpp
index fc845feff0..6a22df3243 100644
--- a/engines/titanic/carry/bridge_piece.cpp
+++ b/engines/titanic/carry/bridge_piece.cpp
@@ -55,14 +55,14 @@ bool CBridgePiece::UseWithOtherMsg(CUseWithOtherMsg *msg) {
CShipSetting *shipSetting = static_cast<CShipSetting *>(msg->_other);
if (!shipSetting) {
return CCarry::UseWithOtherMsg(msg);
- } else if (shipSetting->_string4 == "NULL") {
+ } else if (shipSetting->_itemName != "NULL") {
petAddToInventory();
return true;
} else {
setVisible(false);
playSound("z#54.wav", 100, 0, 0);
setPosition(shipSetting->_pos1);
- shipSetting->_string4 = getName();
+ shipSetting->_itemName = getName();
petMoveToHiddenRoom();
CAddHeadPieceMsg headpieceMsg(shipSetting->getName() == _string6 ?
diff --git a/engines/titanic/carry/carry.h b/engines/titanic/carry/carry.h
index fb5519e290..06e446a1b5 100644
--- a/engines/titanic/carry/carry.h
+++ b/engines/titanic/carry/carry.h
@@ -44,7 +44,6 @@ class CCarry : public CGameObject {
bool EnterViewMsg(CEnterViewMsg *msg);
bool PassOnDragStartMsg(CPassOnDragStartMsg *msg);
protected:
- CString _string1;
int _fieldDC;
CString _string3;
CString _string4;
@@ -59,6 +58,7 @@ protected:
bool _enterFrameSet;
int _visibleFrame;
public:
+ CString _string1;
int _fieldE0;
Point _origPos;
CString _fullViewName;
diff --git a/engines/titanic/carry/glass.h b/engines/titanic/carry/glass.h
index 85443840a1..608d45cb66 100644
--- a/engines/titanic/carry/glass.h
+++ b/engines/titanic/carry/glass.h
@@ -35,7 +35,7 @@ class CGlass : public CCarry {
bool MouseDragEndMsg(CMouseDragEndMsg *msg);
bool TurnOn(CTurnOn *msg);
bool TurnOff(CTurnOff *msg);
-private:
+public:
CString _string6;
public:
CLASSDEF;
diff --git a/engines/titanic/carry/maitred_left_arm.cpp b/engines/titanic/carry/maitred_left_arm.cpp
index b31c2a6f6d..0962f232bd 100644
--- a/engines/titanic/carry/maitred_left_arm.cpp
+++ b/engines/titanic/carry/maitred_left_arm.cpp
@@ -21,19 +21,48 @@
*/
#include "titanic/carry/maitred_left_arm.h"
+#include "titanic/npcs/true_talk_npc.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMaitreDLeftArm, CArm)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(MouseDragStartMsg)
+END_MESSAGE_MAP()
+
void CMaitreDLeftArm::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_field174, indent);
+ file->writeNumberLine(_flag, indent);
CArm::save(file, indent);
}
void CMaitreDLeftArm::load(SimpleFile *file) {
file->readNumber();
- _field174 = file->readNumber();
+ _flag = file->readNumber();
CArm::load(file);
}
+bool CMaitreDLeftArm::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (!_flag) {
+ CTrueTalkNPC *maitreD = dynamic_cast<CTrueTalkNPC *>(findRoomObject("MaitreD"));
+ startTalking(maitreD, 126);
+ startTalking(maitreD, 127);
+ }
+
+ return true;
+}
+
+bool CMaitreDLeftArm::MouseDragStartMsg(CMouseDragStartMsg *msg) {
+ if (checkPoint(msg->_mousePos) && !_flag) {
+ CVisibleMsg visibleMsg;
+ visibleMsg.execute("MD left arm background image");
+ _flag = true;
+
+ CArmPickedUpFromTableMsg takenMsg;
+ takenMsg.execute("Restaurant Table Pan Handler", nullptr, MSGFLAG_SCAN);
+ }
+
+ return CArm::MouseDragStartMsg(msg);
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/carry/maitred_left_arm.h b/engines/titanic/carry/maitred_left_arm.h
index 8f5090b073..0e1732df46 100644
--- a/engines/titanic/carry/maitred_left_arm.h
+++ b/engines/titanic/carry/maitred_left_arm.h
@@ -28,11 +28,14 @@
namespace Titanic {
class CMaitreDLeftArm : public CArm {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool MouseDragStartMsg(CMouseDragStartMsg *msg);
private:
- int _field174;
+ bool _flag;
public:
CLASSDEF;
- CMaitreDLeftArm() : CArm(), _field174(0) {}
+ CMaitreDLeftArm() : CArm(), _flag(false) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/carry/maitred_right_arm.cpp b/engines/titanic/carry/maitred_right_arm.cpp
index 7030e83c9d..5cec6be9bd 100644
--- a/engines/titanic/carry/maitred_right_arm.cpp
+++ b/engines/titanic/carry/maitred_right_arm.cpp
@@ -24,6 +24,10 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMaitreDRightArm, CArm)
+ ON_MESSAGE(DropZoneLostObjectMsg)
+END_MESSAGE_MAP()
+
void CMaitreDRightArm::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CArm::save(file, indent);
@@ -34,4 +38,12 @@ void CMaitreDRightArm::load(SimpleFile *file) {
CArm::load(file);
}
+bool CMaitreDRightArm::DropZoneLostObjectMsg(CDropZoneLostObjectMsg *msg) {
+ CActMsg actMsg("LoseArm");
+ actMsg.execute("MaitreDBody");
+ actMsg.execute("MaitreD Arm Holder");
+ _fieldE0 = 1;
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/carry/maitred_right_arm.h b/engines/titanic/carry/maitred_right_arm.h
index ce07ed7af4..4a53d45f69 100644
--- a/engines/titanic/carry/maitred_right_arm.h
+++ b/engines/titanic/carry/maitred_right_arm.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CMaitreDRightArm : public CArm {
+ DECLARE_MESSAGE_MAP;
+ bool DropZoneLostObjectMsg(CDropZoneLostObjectMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/carry/mouth.cpp b/engines/titanic/carry/mouth.cpp
index 8c3791fa9c..e48929a391 100644
--- a/engines/titanic/carry/mouth.cpp
+++ b/engines/titanic/carry/mouth.cpp
@@ -21,9 +21,16 @@
*/
#include "titanic/carry/mouth.h"
+#include "titanic/game/head_slot.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMouth, CHeadPiece)
+ ON_MESSAGE(UseWithOtherMsg)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(PETGainedObjectMsg)
+END_MESSAGE_MAP()
+
CMouth::CMouth() : CHeadPiece() {
}
@@ -37,4 +44,37 @@ void CMouth::load(SimpleFile *file) {
CHeadPiece::load(file);
}
+bool CMouth::UseWithOtherMsg(CUseWithOtherMsg *msg) {
+ CHeadSlot *slot = dynamic_cast<CHeadSlot *>(msg->_other);
+ if (!slot)
+ return CHeadPiece::UseWithOtherMsg(msg);
+
+ _flag = true;
+ setVisible(false);
+ setPosition(Point(0, 0));
+ petMoveToHiddenRoom();
+
+ CAddHeadPieceMsg addMsg(getName());
+ if (addMsg._value != "NULL")
+ addMsg.execute("MouthSlot");
+
+ return true;
+}
+
+bool CMouth::MovieEndMsg(CMovieEndMsg *msg) {
+ return true;
+}
+
+bool CMouth::PETGainedObjectMsg(CPETGainedObjectMsg *msg) {
+ _visibleFrame = 2;
+ loadFrame(2);
+ setVisible(true);
+ if (!_field13C) {
+ stateInc38();
+ _field13C = true;
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/carry/mouth.h b/engines/titanic/carry/mouth.h
index e394330494..f5f0f53b45 100644
--- a/engines/titanic/carry/mouth.h
+++ b/engines/titanic/carry/mouth.h
@@ -28,6 +28,10 @@
namespace Titanic {
class CMouth : public CHeadPiece {
+ DECLARE_MESSAGE_MAP;
+ bool UseWithOtherMsg(CUseWithOtherMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool PETGainedObjectMsg(CPETGainedObjectMsg *msg);
public:
CLASSDEF;
CMouth();
diff --git a/engines/titanic/carry/napkin.cpp b/engines/titanic/carry/napkin.cpp
index ace5a389a0..d25e8b5975 100644
--- a/engines/titanic/carry/napkin.cpp
+++ b/engines/titanic/carry/napkin.cpp
@@ -57,5 +57,4 @@ bool CNapkin::UseWithOtherMsg(CUseWithOtherMsg *msg) {
return CCarry::UseWithOtherMsg(msg);
}
-
} // End of namespace Titanic
diff --git a/engines/titanic/carry/nose.cpp b/engines/titanic/carry/nose.cpp
index 4f3afe24ac..a08d02a88c 100644
--- a/engines/titanic/carry/nose.cpp
+++ b/engines/titanic/carry/nose.cpp
@@ -21,9 +21,15 @@
*/
#include "titanic/carry/nose.h"
+#include "titanic/game/head_slot.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CNose, CHeadPiece)
+ ON_MESSAGE(ChangeSeasonMsg)
+ ON_MESSAGE(UseWithOtherMsg)
+END_MESSAGE_MAP()
+
CNose::CNose() : CHeadPiece() {
}
@@ -37,4 +43,23 @@ void CNose::load(SimpleFile *file) {
CHeadPiece::load(file);
}
+bool CNose::ChangeSeasonMsg(CChangeSeasonMsg *msg) {
+ // WORKAROUND: Redundant code in original skipped
+ return true;
+}
+
+bool CNose::UseWithOtherMsg(CUseWithOtherMsg *msg) {
+ CHeadSlot *slot = dynamic_cast<CHeadSlot *>(msg->_other);
+ if (!slot)
+ return CCarry::UseWithOtherMsg(msg);
+
+ petMoveToHiddenRoom();
+ _flag = false;
+ CAddHeadPieceMsg addMsg(getName());
+ if (addMsg._value != "NULL")
+ addMsg.execute("NoseSlot");
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/carry/nose.h b/engines/titanic/carry/nose.h
index b688da231a..6e5be30df2 100644
--- a/engines/titanic/carry/nose.h
+++ b/engines/titanic/carry/nose.h
@@ -28,6 +28,9 @@
namespace Titanic {
class CNose : public CHeadPiece {
+ DECLARE_MESSAGE_MAP;
+ bool ChangeSeasonMsg(CChangeSeasonMsg *msg);
+ bool UseWithOtherMsg(CUseWithOtherMsg *msg);
public:
CLASSDEF;
CNose();
diff --git a/engines/titanic/carry/perch.cpp b/engines/titanic/carry/perch.cpp
index 281b3fce53..4f0e76bdb0 100644
--- a/engines/titanic/carry/perch.cpp
+++ b/engines/titanic/carry/perch.cpp
@@ -24,6 +24,10 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPerch, CCentralCore)
+ ON_MESSAGE(UseWithOtherMsg)
+END_MESSAGE_MAP()
+
void CPerch::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CCentralCore::save(file, indent);
@@ -34,4 +38,13 @@ void CPerch::load(SimpleFile *file) {
CCentralCore::load(file);
}
+bool CPerch::UseWithOtherMsg(CUseWithOtherMsg *msg) {
+ if (msg->_other->isEquals("SpeechCentre")) {
+ CShowTextMsg textMsg("This does not reach.");
+ textMsg.execute("PET");
+ }
+
+ return CCentralCore::UseWithOtherMsg(msg);
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/carry/perch.h b/engines/titanic/carry/perch.h
index d23868d909..8941c8ea4d 100644
--- a/engines/titanic/carry/perch.h
+++ b/engines/titanic/carry/perch.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CPerch : public CCentralCore {
+ DECLARE_MESSAGE_MAP;
+ bool UseWithOtherMsg(CUseWithOtherMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/carry/phonograph_cylinder.cpp b/engines/titanic/carry/phonograph_cylinder.cpp
index 0684c56611..41df050d2b 100644
--- a/engines/titanic/carry/phonograph_cylinder.cpp
+++ b/engines/titanic/carry/phonograph_cylinder.cpp
@@ -22,6 +22,7 @@
#include "titanic/carry/phonograph_cylinder.h"
#include "titanic/game/phonograph.h"
+#include "titanic/sound/music_room.h"
namespace Titanic {
@@ -162,10 +163,33 @@ bool CPhonographCylinder::RecordOntoCylinderMsg(CRecordOntoCylinderMsg *msg) {
}
bool CPhonographCylinder::SetMusicControlsMsg(CSetMusicControlsMsg *msg) {
- if (_itemName.left(7) == "STMusic") {
- //todo
- warning("TODO");
- }
+ if (!_itemName.hasPrefix("STMusic"))
+ return true;
+
+ CMusicRoom *musicRoom = getMusicRoom();
+ musicRoom->setItem5(BELLS, _bellsMuteControl);
+ musicRoom->setItem2(BELLS, _bellsPitchControl);
+ musicRoom->setItem1(BELLS, _bellsSpeedControl);
+ musicRoom->setItem4(BELLS, _bellsInversionControl);
+ musicRoom->setItem3(BELLS, _bellsDirectionControl);
+
+ musicRoom->setItem5(SNAKE, _snakeMuteControl);
+ musicRoom->setItem2(SNAKE, _snakePitchControl);
+ musicRoom->setItem1(SNAKE, _snakeSpeedControl);
+ musicRoom->setItem4(SNAKE, _snakeInversionControl);
+ musicRoom->setItem3(SNAKE, _snakeDirectionControl);
+
+ musicRoom->setItem5(PIANO, _pianoMuteControl);
+ musicRoom->setItem2(PIANO, _pianoPitchControl);
+ musicRoom->setItem1(PIANO, _pianoSpeedControl);
+ musicRoom->setItem4(PIANO, _pianoInversionControl);
+ musicRoom->setItem3(PIANO, _pianoDirectionControl);
+
+ musicRoom->setItem5(BASS, _bassMuteControl);
+ musicRoom->setItem2(BASS, _bassPitchControl);
+ musicRoom->setItem1(BASS, _bassSpeedControl);
+ musicRoom->setItem4(BASS, _bassInversionControl);
+ musicRoom->setItem3(BASS, _bassDirectionControl);
return true;
}
diff --git a/engines/titanic/carry/photograph.cpp b/engines/titanic/carry/photograph.cpp
index 7f32a0623d..039efd0252 100644
--- a/engines/titanic/carry/photograph.cpp
+++ b/engines/titanic/carry/photograph.cpp
@@ -21,6 +21,7 @@
*/
#include "titanic/carry/photograph.h"
+#include "titanic/core/dont_save_file_item.h"
#include "titanic/core/room_item.h"
namespace Titanic {
@@ -59,8 +60,12 @@ bool CPhotograph::MouseDragEndMsg(CMouseDragEndMsg *msg) {
_v1 = 0;
CGameObject *target = msg->_dropTarget;
- if (target && target->getName() != "NavigationComputer") {
- warning("TODO: CPhotograph::MouseDragEndMsg");
+ if (target && target->isEquals("NavigationComputer")) {
+ moveUnder(getDontSave());
+ makeDirty();
+ playSound("a#46.wav");
+ starFn1(14);
+ showMouse();
return true;
} else {
return CCarry::MouseDragEndMsg(msg);
@@ -78,7 +83,7 @@ bool CPhotograph::MouseDragStartMsg(CMouseDragStartMsg *msg) {
}
bool CPhotograph::PETGainedObjectMsg(CPETGainedObjectMsg *msg) {
- if (getRoom()->getName() == "Home") {
+ if (getRoom()->isEquals("Home")) {
CActMsg actMsg("PlayerPutsPhotoInPET");
actMsg.execute("Doorbot");
}
diff --git a/engines/titanic/carry/plug_in.cpp b/engines/titanic/carry/plug_in.cpp
index c82a4cc422..883458c9b1 100644
--- a/engines/titanic/carry/plug_in.cpp
+++ b/engines/titanic/carry/plug_in.cpp
@@ -47,19 +47,13 @@ bool CPlugIn::UseWithOtherMsg(CUseWithOtherMsg *msg) {
if (otherName == "PET") {
return CCarry::UseWithOtherMsg(msg);
- } else if (otherName == "DatasideTransporter") {
- CString name = getName();
- if (name == "DatasideTransporter") {
- // TODO
- if (name != "SendYourself") {
- // TODO
- }
- } else {
- // TODO
- }
- } else {
+ } else if (isEquals("DatasideTransporter")) {
CShowTextMsg textMsg("This item is incorrectly calibrated.");
textMsg.execute("PET");
+ } else if (isEquals("DatasideTransporter")) {
+ error("TODO: Set msg->_other->fieldC4 = 2");
+ } else if (isEquals("SendYourself")) {
+ error("TODO: Set msg->_other->fieldC8 = 1");
}
return true;
diff --git a/engines/titanic/carry/speech_centre.cpp b/engines/titanic/carry/speech_centre.cpp
index b8076aee76..29ced484a5 100644
--- a/engines/titanic/carry/speech_centre.cpp
+++ b/engines/titanic/carry/speech_centre.cpp
@@ -24,10 +24,17 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CSpeechCentre, CBrain)
+ ON_MESSAGE(PuzzleSolvedMsg)
+ ON_MESSAGE(ChangeSeasonMsg)
+ ON_MESSAGE(SpeechFallsFromTreeMsg)
+ ON_MESSAGE(FrameMsg)
+END_MESSAGE_MAP()
+
void CSpeechCentre::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_field13C, indent);
- file->writeQuotedLine(_string1, indent);
+ file->writeQuotedLine(_season, indent);
file->writeNumberLine(_field14C, indent);
CBrain::save(file, indent);
@@ -36,10 +43,41 @@ void CSpeechCentre::save(SimpleFile *file, int indent) {
void CSpeechCentre::load(SimpleFile *file) {
file->readNumber();
_field13C = file->readNumber();
- _string1 = file->readString();
+ _season = file->readString();
_field14C = file->readNumber();
CBrain::load(file);
}
+bool CSpeechCentre::PuzzleSolvedMsg(CPuzzleSolvedMsg *msg) {
+ if (_field13C == 1 && _season == "Autumn")
+ _fieldE0 = true;
+ return true;
+}
+
+bool CSpeechCentre::ChangeSeasonMsg(CChangeSeasonMsg *msg) {
+ _season = msg->_season;
+ return true;
+}
+
+bool CSpeechCentre::SpeechFallsFromTreeMsg(CSpeechFallsFromTreeMsg *msg) {
+ setVisible(true);
+ dragMove(msg->_pos);
+ _field14C = true;
+ return true;
+}
+
+bool CSpeechCentre::FrameMsg(CFrameMsg *msg) {
+ if (_field14C) {
+ if (_bounds.top > 200)
+ _field14C = false;
+
+ makeDirty();
+ _bounds.top += 3;
+ makeDirty();
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/carry/speech_centre.h b/engines/titanic/carry/speech_centre.h
index 50f47e9c8a..806e22247b 100644
--- a/engines/titanic/carry/speech_centre.h
+++ b/engines/titanic/carry/speech_centre.h
@@ -28,13 +28,18 @@
namespace Titanic {
class CSpeechCentre : public CBrain {
+ DECLARE_MESSAGE_MAP;
+ bool PuzzleSolvedMsg(CPuzzleSolvedMsg *msg);
+ bool ChangeSeasonMsg(CChangeSeasonMsg *msg);
+ bool SpeechFallsFromTreeMsg(CSpeechFallsFromTreeMsg *msg);
+ bool FrameMsg(CFrameMsg *msg);
private:
int _field13C;
- CString _string1;
+ CString _season;
int _field14C;
public:
CLASSDEF;
- CSpeechCentre() : CBrain(), _string1("Summer"),
+ CSpeechCentre() : CBrain(), _season("Summer"),
_field13C(1), _field14C(0) {}
/**
diff --git a/engines/titanic/carry/vision_centre.cpp b/engines/titanic/carry/vision_centre.cpp
index 8c8bab15f8..fd30089fc5 100644
--- a/engines/titanic/carry/vision_centre.cpp
+++ b/engines/titanic/carry/vision_centre.cpp
@@ -24,6 +24,12 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CVisionCentre, CBrain)
+ ON_MESSAGE(PuzzleSolvedMsg)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(MouseDragStartMsg)
+END_MESSAGE_MAP()
+
void CVisionCentre::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CBrain::save(file, indent);
@@ -34,4 +40,27 @@ void CVisionCentre::load(SimpleFile *file) {
CBrain::load(file);
}
+bool CVisionCentre::PuzzleSolvedMsg(CPuzzleSolvedMsg *msg) {
+ _fieldE0 = true;
+ return true;
+}
+
+bool CVisionCentre::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (_fieldE0) {
+ return CBrain::MouseButtonDownMsg(msg);
+ } else {
+ petDisplayMessage(1, "It would be nice if you could take that but you can't.");
+ return true;
+ }
+}
+
+bool CVisionCentre::MouseDragStartMsg(CMouseDragStartMsg *msg) {
+ if (_fieldE0) {
+ return CBrain::MouseDragStartMsg(msg);
+ } else {
+ petDisplayMessage(1, "It would be nice if you could take that but you can't.");
+ return true;
+ }
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/carry/vision_centre.h b/engines/titanic/carry/vision_centre.h
index 6cf8e2c653..14055a5f5f 100644
--- a/engines/titanic/carry/vision_centre.h
+++ b/engines/titanic/carry/vision_centre.h
@@ -28,6 +28,10 @@
namespace Titanic {
class CVisionCentre : public CBrain {
+ DECLARE_MESSAGE_MAP;
+ bool PuzzleSolvedMsg(CPuzzleSolvedMsg *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool MouseDragStartMsg(CMouseDragStartMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/core/drop_target.h b/engines/titanic/core/drop_target.h
index 8c497b6bc2..e07b640c9f 100644
--- a/engines/titanic/core/drop_target.h
+++ b/engines/titanic/core/drop_target.h
@@ -34,7 +34,7 @@ class CDropTarget : public CGameObject {
bool EnterViewMsg(CEnterViewMsg *msg);
bool VisibleMsg(CVisibleMsg *msg);
bool DropZoneLostObjectMsg(CDropZoneLostObjectMsg *msg);
-private:
+protected:
Point _pos1;
int _itemFrame;
CString _itemMatchName;
diff --git a/engines/titanic/core/game_object.cpp b/engines/titanic/core/game_object.cpp
index 3126aac228..2c7b7db998 100644
--- a/engines/titanic/core/game_object.cpp
+++ b/engines/titanic/core/game_object.cpp
@@ -1025,12 +1025,12 @@ void CGameObject::moveToView(const CString &name) {
addUnder(view);
}
-void CGameObject::stateInc14() {
- getGameManager()->_gameState.inc14();
+void CGameObject::stateChangeSeason() {
+ getGameManager()->_gameState.changeSeason();
}
-int CGameObject::stateGet14() const {
- return getGameManager()->_gameState._field14;
+Season CGameObject::stateGetSeason() const {
+ return getGameManager()->_gameState._seasonNum;
}
void CGameObject::stateSet24() {
@@ -1066,7 +1066,7 @@ void CGameObject::setMovieFrameRate(double rate) {
_surface->setMovieFrameRate(rate);
}
-void CGameObject::setTextBorder(const CString &str, int border, int borderRight) {
+void CGameObject::setText(const CString &str, int border, int borderRight) {
if (!_text)
_text = new CPetText();
_textBorder = border;
@@ -1160,8 +1160,8 @@ void CGameObject::mouseUnlockE4() {
CScreenManager::_screenManagerPtr->_mouseCursor->unlockE4();
}
-void CGameObject::mouseSaveState(int v1, int v2, int v3) {
- CScreenManager::_screenManagerPtr->_mouseCursor->saveState(v1, v2, v3);
+void CGameObject::mouseSetPosition(const Point &pt, double rate) {
+ CScreenManager::_screenManagerPtr->_mouseCursor->setPosition(pt, rate);
}
void CGameObject::lockInputHandler() {
diff --git a/engines/titanic/core/game_object.h b/engines/titanic/core/game_object.h
index cafd96e38e..182d165e89 100644
--- a/engines/titanic/core/game_object.h
+++ b/engines/titanic/core/game_object.h
@@ -33,6 +33,7 @@
#include "titanic/core/named_item.h"
#include "titanic/pet_control/pet_section.h"
#include "titanic/pet_control/pet_text.h"
+#include "titanic/game_state.h"
namespace Titanic {
@@ -165,7 +166,10 @@ protected:
void mouseLockE4();
void mouseUnlockE4();
- void mouseSaveState(int v1, int v2, int v3);
+ /**
+ * Sets the mouse to a new position
+ */
+ void mouseSetPosition(const Point &pt, double rate);
/**
* Lock the input handler
@@ -349,7 +353,7 @@ protected:
/**
* Play an arbitrary clip
*/
- void playClip(const CString &name, uint flags);
+ void playClip(const CString &name, uint flags = 0);
/**
* Play a clip
@@ -364,7 +368,7 @@ protected:
/**
* Play a clip randomly from a passed list of names
*/
- void playRandomClip(const char *const *names, uint flags);
+ void playRandomClip(const char *const *names, uint flags = 0);
/**
* Return the current view/node/room as a single string
@@ -491,9 +495,9 @@ protected:
void setMovieFrameRate(double rate);
/**
- * Set up the text borders for the object
+ * Set up the text and borders for the object
*/
- void setTextBorder(const CString &str, int border = 0, int borderRight = 0);
+ void setText(const CString &str, int border = 0, int borderRight = 0);
/**
* Sets whether the text will use borders
@@ -941,8 +945,17 @@ public:
/*--- CGameState Methods ---*/
void setState1C(bool flag);
- void stateInc14();
- int stateGet14() const;
+
+ /**
+ * Change to the next season
+ */
+ void stateChangeSeason();
+
+ /**
+ * Returns the currently active season
+ */
+ Season stateGetSeason() const;
+
void stateSet24();
int stateGet24() const;
void stateInc38();
diff --git a/engines/titanic/core/multi_drop_target.cpp b/engines/titanic/core/multi_drop_target.cpp
index f2998199b1..b95696577f 100644
--- a/engines/titanic/core/multi_drop_target.cpp
+++ b/engines/titanic/core/multi_drop_target.cpp
@@ -21,9 +21,14 @@
*/
#include "titanic/core/multi_drop_target.h"
+#include "titanic/support/string_parser.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMultiDropTarget, CDropTarget)
+ ON_MESSAGE(DropObjectMsg)
+END_MESSAGE_MAP()
+
void CMultiDropTarget::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeQuotedLine(_string5, indent);
@@ -40,4 +45,20 @@ void CMultiDropTarget::load(SimpleFile *file) {
CDropTarget::load(file);
}
+bool CMultiDropTarget::DropObjectMsg(CDropObjectMsg *msg) {
+ CStringParser parser1(_string5);
+ CStringParser parser2(_string6);
+ CString seperatorChars = ",";
+
+ while (parser2.parse(_itemMatchName, seperatorChars)) {
+ _dropFrame = parser1.readInt();
+ CDropTarget::DropObjectMsg(msg);
+
+ parser1.skipSeperators(seperatorChars);
+ parser2.skipSeperators(seperatorChars);
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/core/multi_drop_target.h b/engines/titanic/core/multi_drop_target.h
index c004b9bece..ab552f96e1 100644
--- a/engines/titanic/core/multi_drop_target.h
+++ b/engines/titanic/core/multi_drop_target.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CMultiDropTarget : public CDropTarget {
+ DECLARE_MESSAGE_MAP;
+ bool DropObjectMsg(CDropObjectMsg *msg);
public:
CString _string5;
CString _string6;
diff --git a/engines/titanic/core/saveable_object.cpp b/engines/titanic/core/saveable_object.cpp
index 5fc2d7e738..db3249c107 100644
--- a/engines/titanic/core/saveable_object.cpp
+++ b/engines/titanic/core/saveable_object.cpp
@@ -165,6 +165,8 @@
#include "titanic/game/music_room_stop_phonograph_button.h"
#include "titanic/game/music_system_lock.h"
#include "titanic/game/nav_helmet.h"
+#include "titanic/game/nav_helmet_on.h"
+#include "titanic/game/nav_helmet_off.h"
#include "titanic/game/navigation_computer.h"
#include "titanic/game/no_nut_bowl.h"
#include "titanic/game/nose_holder.h"
@@ -250,7 +252,7 @@
#include "titanic/game/pickup/pick_up_vis_centre.h"
#include "titanic/game/placeholder/bar_shelf_vis_centre.h"
#include "titanic/game/placeholder/lemon_on_bar.h"
-#include "titanic/game/placeholder/place_holder_item.h"
+#include "titanic/game/placeholder/place_holder.h"
#include "titanic/game/placeholder/tv_on_bar.h"
#include "titanic/game/sgt/armchair.h"
#include "titanic/game/sgt/basin.h"
@@ -284,7 +286,6 @@
#include "titanic/gfx/chev_right_off.h"
#include "titanic/gfx/chev_right_on.h"
#include "titanic/gfx/chev_send_rec_switch.h"
-#include "titanic/gfx/chev_switch.h"
#include "titanic/gfx/edit_control.h"
#include "titanic/gfx/elevator_button.h"
#include "titanic/gfx/get_from_succ.h"
@@ -575,6 +576,8 @@ DEFFN(CMusicRoomPhonograph);
DEFFN(CMusicRoomStopPhonographButton);
DEFFN(CMusicSystemLock);
DEFFN(CNavHelmet);
+DEFFN(CNavHelmetOn);
+DEFFN(CNavHelmetOff);
DEFFN(CNavigationComputer);
DEFFN(CNoNutBowl);
DEFFN(CNoseHolder);
@@ -665,7 +668,7 @@ DEFFN(CPickUpSpeechCentre);
DEFFN(CPickUpVisCentre);
DEFFN(CBarShelfVisCentre);
DEFFN(CLemonOnBar);
-DEFFN(CPlaceHolderItem);
+DEFFN(CPlaceHolder);
DEFFN(CTVOnBar);
DEFFN(CArmchair);
DEFFN(CBasin);
@@ -701,7 +704,6 @@ DEFFN(CChevLeftOn);
DEFFN(CChevRightOff);
DEFFN(CChevRightOn);
DEFFN(CChevSendRecSwitch);
-DEFFN(CChevSwitch);
DEFFN(CEditControl);
DEFFN(CElevatorButton);
DEFFN(CGetFromSucc);
@@ -1162,6 +1164,8 @@ void CSaveableObject::initClassList() {
ADDFN(CMusicRoomStopPhonographButton, CEjectPhonographButton);
ADDFN(CMusicSystemLock, CDropTarget);
ADDFN(CNavHelmet, CGameObject);
+ ADDFN(CNavHelmetOn, CGameObject);
+ ADDFN(CNavHelmetOff, CGameObject);
ADDFN(CNavigationComputer, CGameObject);
ADDFN(CNoNutBowl, CBackground);
ADDFN(CNoseHolder, CDropTarget);
@@ -1245,10 +1249,10 @@ void CSaveableObject::initClassList() {
ADDFN(CPickUpLemon, CPickUp);
ADDFN(CPickUpSpeechCentre, CPickUp);
ADDFN(CPickUpVisCentre, CPickUp);
- ADDFN(CBarShelfVisCentre, CPlaceHolderItem);
- ADDFN(CLemonOnBar, CPlaceHolderItem);
- ADDFN(CPlaceHolderItem, CGameObject);
- ADDFN(CTVOnBar, CPlaceHolderItem);
+ ADDFN(CBarShelfVisCentre, CPlaceHolder);
+ ADDFN(CLemonOnBar, CPlaceHolder);
+ ADDFN(CPlaceHolder, CGameObject);
+ ADDFN(CTVOnBar, CPlaceHolder);
ADDFN(CArmchair, CSGTStateRoom);
ADDFN(CBasin, CSGTStateRoom);
ADDFN(CBedfoot, CSGTStateRoom);
@@ -1283,7 +1287,6 @@ void CSaveableObject::initClassList() {
ADDFN(CChevRightOff, CToggleSwitch);
ADDFN(CChevRightOn, CToggleSwitch);
ADDFN(CChevSendRecSwitch, CToggleSwitch);
- ADDFN(CChevSwitch, CToggleSwitch);
ADDFN(CEditControl, CGameObject);
ADDFN(CElevatorButton, CSTButton);
ADDFN(CGetFromSucc, CToggleSwitch);
diff --git a/engines/titanic/core/tree_item.cpp b/engines/titanic/core/tree_item.cpp
index 870ee38016..86c34cab8b 100644
--- a/engines/titanic/core/tree_item.cpp
+++ b/engines/titanic/core/tree_item.cpp
@@ -34,7 +34,7 @@
#include "titanic/core/room_item.h"
#include "titanic/pet_control/pet_control.h"
#include "titanic/game_manager.h"
-#include "titanic/game/placeholder/place_holder_item.h"
+#include "titanic/game/placeholder/place_holder.h"
namespace Titanic {
@@ -96,7 +96,7 @@ bool CTreeItem::isLinkItem() const {
}
bool CTreeItem::isPlaceHolderItem() const {
- return isInstanceOf(CPlaceHolderItem::_type);
+ return isInstanceOf(CPlaceHolder::_type);
}
bool CTreeItem::isNamedItem() const {
diff --git a/engines/titanic/core/turn_on_play_sound.cpp b/engines/titanic/core/turn_on_play_sound.cpp
index 2f9dba24a6..ab50b33134 100644
--- a/engines/titanic/core/turn_on_play_sound.cpp
+++ b/engines/titanic/core/turn_on_play_sound.cpp
@@ -24,26 +24,37 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CTurnOnPlaySound, CTurnOnObject)
+ ON_MESSAGE(MouseButtonUpMsg)
+END_MESSAGE_MAP()
+
CTurnOnPlaySound::CTurnOnPlaySound() : CTurnOnObject(),
- _string3("NULL"), _fieldF8(80), _fieldFC(0) {
+ _soundName("NULL"), _soundVolume(80), _soundVal3(0) {
}
void CTurnOnPlaySound::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeQuotedLine(_string3, indent);
- file->writeNumberLine(_fieldF8, indent);
- file->writeNumberLine(_fieldFC, indent);
+ file->writeQuotedLine(_soundName, indent);
+ file->writeNumberLine(_soundVolume, indent);
+ file->writeNumberLine(_soundVal3, indent);
CTurnOnObject::save(file, indent);
}
void CTurnOnPlaySound::load(SimpleFile *file) {
file->readNumber();
- _string3 = file->readString();
- _fieldF8 = file->readNumber();
- _fieldFC = file->readNumber();
+ _soundName = file->readString();
+ _soundVolume = file->readNumber();
+ _soundVal3 = file->readNumber();
CTurnOnObject::load(file);
}
+bool CTurnOnPlaySound::MouseButtonUpMsg(CMouseButtonUpMsg *msg) {
+ if (_soundName != "NULL")
+ playSound(_soundName, _soundVolume, _soundVal3);
+
+ return CTurnOnObject::MouseButtonUpMsg(msg);
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/core/turn_on_play_sound.h b/engines/titanic/core/turn_on_play_sound.h
index 1164135071..29a25a5665 100644
--- a/engines/titanic/core/turn_on_play_sound.h
+++ b/engines/titanic/core/turn_on_play_sound.h
@@ -28,10 +28,12 @@
namespace Titanic {
class CTurnOnPlaySound : public CTurnOnObject {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonUpMsg(CMouseButtonUpMsg *msg);
private:
- CString _string3;
- int _fieldF8;
- int _fieldFC;
+ CString _soundName;
+ int _soundVolume;
+ int _soundVal3;
public:
CLASSDEF;
CTurnOnPlaySound();
diff --git a/engines/titanic/core/turn_on_turn_off.cpp b/engines/titanic/core/turn_on_turn_off.cpp
index d43ddf7038..6498c226a0 100644
--- a/engines/titanic/core/turn_on_turn_off.cpp
+++ b/engines/titanic/core/turn_on_turn_off.cpp
@@ -24,16 +24,21 @@
namespace Titanic {
-CTurnOnTurnOff::CTurnOnTurnOff() : CBackground(), _fieldE0(0),
- _fieldE4(0), _fieldE8(0), _fieldEC(0), _fieldF0(0) {
+BEGIN_MESSAGE_MAP(CTurnOnTurnOff, CBackground)
+ ON_MESSAGE(TurnOn)
+ ON_MESSAGE(TurnOff)
+END_MESSAGE_MAP()
+
+CTurnOnTurnOff::CTurnOnTurnOff() : CBackground(), _startFrameOn(0),
+ _endFrameOn(0), _startFrameOff(0), _endFrameOff(0), _fieldF0(false) {
}
void CTurnOnTurnOff::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldE0, indent);
- file->writeNumberLine(_fieldE4, indent);
- file->writeNumberLine(_fieldE8, indent);
- file->writeNumberLine(_fieldEC, indent);
+ file->writeNumberLine(_startFrameOn, indent);
+ file->writeNumberLine(_endFrameOn, indent);
+ file->writeNumberLine(_startFrameOff, indent);
+ file->writeNumberLine(_endFrameOff, indent);
file->writeNumberLine(_fieldF0, indent);
CBackground::save(file, indent);
@@ -41,13 +46,37 @@ void CTurnOnTurnOff::save(SimpleFile *file, int indent) {
void CTurnOnTurnOff::load(SimpleFile *file) {
file->readNumber();
- _fieldE0 = file->readNumber();
- _fieldE4 = file->readNumber();
- _fieldE8 = file->readNumber();
- _fieldEC = file->readNumber();
+ _startFrameOn = file->readNumber();
+ _endFrameOn = file->readNumber();
+ _startFrameOff = file->readNumber();
+ _endFrameOff = file->readNumber();
_fieldF0 = file->readNumber();
CBackground::load(file);
}
+bool CTurnOnTurnOff::TurnOn(CTurnOn *msg) {
+ if (!_fieldF0) {
+ if (_fieldDC)
+ playMovie(_startFrameOn, _endFrameOn, MOVIE_GAMESTATE);
+ else
+ playMovie(_startFrameOn, _endFrameOn, MOVIE_NOTIFY_OBJECT);
+ _fieldF0 = true;
+ }
+
+ return true;
+}
+
+bool CTurnOnTurnOff::TurnOff(CTurnOff *msg) {
+ if (!_fieldF0) {
+ if (_fieldDC)
+ playMovie(_startFrameOff, _endFrameOff, MOVIE_GAMESTATE);
+ else
+ playMovie(_startFrameOff, _endFrameOff, MOVIE_NOTIFY_OBJECT);
+ _fieldF0 = true;
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/core/turn_on_turn_off.h b/engines/titanic/core/turn_on_turn_off.h
index adca6876ff..c09f0e0d7d 100644
--- a/engines/titanic/core/turn_on_turn_off.h
+++ b/engines/titanic/core/turn_on_turn_off.h
@@ -28,12 +28,15 @@
namespace Titanic {
class CTurnOnTurnOff : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool TurnOn(CTurnOn *msg);
+ bool TurnOff(CTurnOff *msg);
private:
- int _fieldE0;
- int _fieldE4;
- int _fieldE8;
- int _fieldEC;
- int _fieldF0;
+ int _startFrameOn;
+ int _endFrameOn;
+ int _startFrameOff;
+ int _endFrameOff;
+ bool _fieldF0;
public:
CLASSDEF;
CTurnOnTurnOff();
diff --git a/engines/titanic/game/arboretum_gate.cpp b/engines/titanic/game/arboretum_gate.cpp
index 4c3ca03b7a..1435e3e204 100644
--- a/engines/titanic/game/arboretum_gate.cpp
+++ b/engines/titanic/game/arboretum_gate.cpp
@@ -21,7 +21,6 @@
*/
#include "titanic/game/arboretum_gate.h"
-#include "titanic/game/seasonal_adjustment.h"
namespace Titanic {
@@ -45,30 +44,30 @@ CArboretumGate::CArboretumGate() : CBackground() {
_viewName2 = "NULL";
_seasonNum = 0;
_fieldF0 = 0;
- _winterOffStartFrame = 244;
- _winterOffEndFrame = 304;
- _springOffStartFrame = 122;
- _springOffEndFrame = 182;
- _summerOffStartFrame1 = 183;
- _summerOffEndFrame1 = 243;
- _summerOffStartFrame2 = 665;
- _summerOffEndFrame2 = 724;
- _autumnOffStartFrame1 = 61;
- _autumnOffEndFrame1 = 121;
- _autumnOffStartFrame2 = 0;
- _autumnOffEndFrame2 = 60;
- _winterOnStartFrame = 485;
- _winterOnEndFrame = 544;
- _springOnStartFrame = 425;
- _springOnEndFrame = 484;
- _summerOnStartFrame1 = 545;
- _summerOnEndFrame1 = 604;
- _summerOnStartFrame2 = 605;
- _summerOnEndFrame2 = 664;
- _autumnOnStartFrame1 = 305;
- _autumnOnEndFrame1 = 364;
- _autumnOnStartFrame2 = 365;
- _autumnOnEndFrame2 = 424;
+ _startFrameSpringOff = 244;
+ _endFrameSpringOff = 304;
+ _startFrameSummerOff = 122;
+ _endFrameSummerOff = 182;
+ _startFrameAutumnOff1 = 183;
+ _endFrameAutumnOff1 = 243;
+ _startFrameAutumnOff2 = 665;
+ _endFrameAutumnOff2 = 724;
+ _startFrameWinterOff1 = 61;
+ _endFrameWinterOff1 = 121;
+ _startFrameWinterOff2 = 0;
+ _endFrameWinterOff2 = 60;
+ _startFrameSpringOn = 485;
+ _endFrameSpringOn = 544;
+ _startFrameSummerOn = 425;
+ _endFrameSummerOn = 484;
+ _startFrameAutumnOn1 = 545;
+ _endFrameAutumnOn1 = 604;
+ _startFrameAutumnOn2 = 605;
+ _endFrameAutumnOn2 = 664;
+ _startFrameWinterOn1 = 305;
+ _endFrameWinterOn1 = 364;
+ _startFrameWinterOn2 = 365;
+ _endFrameWinterOn2 = 424;
}
void CArboretumGate::save(SimpleFile *file, int indent) {
@@ -79,30 +78,30 @@ void CArboretumGate::save(SimpleFile *file, int indent) {
file->writeNumberLine(_v3, indent);
file->writeQuotedLine(_viewName1, indent);
file->writeNumberLine(_fieldF0, indent);
- file->writeNumberLine(_winterOffStartFrame, indent);
- file->writeNumberLine(_winterOffEndFrame, indent);
- file->writeNumberLine(_springOffStartFrame, indent);
- file->writeNumberLine(_springOffEndFrame, indent);
- file->writeNumberLine(_summerOffStartFrame1, indent);
- file->writeNumberLine(_summerOffEndFrame1, indent);
- file->writeNumberLine(_summerOffStartFrame2, indent);
- file->writeNumberLine(_summerOffEndFrame2, indent);
- file->writeNumberLine(_autumnOffStartFrame1, indent);
- file->writeNumberLine(_autumnOffEndFrame1, indent);
- file->writeNumberLine(_autumnOffStartFrame2, indent);
- file->writeNumberLine(_autumnOffEndFrame2, indent);
- file->writeNumberLine(_winterOnStartFrame, indent);
- file->writeNumberLine(_winterOnEndFrame, indent);
- file->writeNumberLine(_springOnStartFrame, indent);
- file->writeNumberLine(_springOnEndFrame, indent);
- file->writeNumberLine(_summerOnStartFrame1, indent);
- file->writeNumberLine(_summerOnEndFrame1, indent);
- file->writeNumberLine(_summerOnStartFrame2, indent);
- file->writeNumberLine(_summerOnEndFrame2, indent);
- file->writeNumberLine(_autumnOnStartFrame1, indent);
- file->writeNumberLine(_autumnOnEndFrame1, indent);
- file->writeNumberLine(_autumnOnStartFrame2, indent);
- file->writeNumberLine(_autumnOnEndFrame2, indent);
+ file->writeNumberLine(_startFrameSpringOff, indent);
+ file->writeNumberLine(_endFrameSpringOff, indent);
+ file->writeNumberLine(_startFrameSummerOff, indent);
+ file->writeNumberLine(_endFrameSummerOff, indent);
+ file->writeNumberLine(_startFrameAutumnOff1, indent);
+ file->writeNumberLine(_endFrameAutumnOff1, indent);
+ file->writeNumberLine(_startFrameAutumnOff2, indent);
+ file->writeNumberLine(_endFrameAutumnOff2, indent);
+ file->writeNumberLine(_startFrameWinterOff1, indent);
+ file->writeNumberLine(_endFrameWinterOff1, indent);
+ file->writeNumberLine(_startFrameWinterOff2, indent);
+ file->writeNumberLine(_endFrameWinterOff2, indent);
+ file->writeNumberLine(_startFrameSpringOn, indent);
+ file->writeNumberLine(_endFrameSpringOn, indent);
+ file->writeNumberLine(_startFrameSummerOn, indent);
+ file->writeNumberLine(_endFrameSummerOn, indent);
+ file->writeNumberLine(_startFrameAutumnOn1, indent);
+ file->writeNumberLine(_endFrameAutumnOn1, indent);
+ file->writeNumberLine(_startFrameAutumnOn2, indent);
+ file->writeNumberLine(_endFrameAutumnOn2, indent);
+ file->writeNumberLine(_startFrameWinterOn1, indent);
+ file->writeNumberLine(_endFrameWinterOn1, indent);
+ file->writeNumberLine(_startFrameWinterOn2, indent);
+ file->writeNumberLine(_endFrameWinterOn2, indent);
file->writeQuotedLine(_viewName2, indent);
CBackground::save(file, indent);
@@ -116,30 +115,30 @@ void CArboretumGate::load(SimpleFile *file) {
_v3 = file->readNumber();
_viewName1 = file->readString();
_fieldF0 = file->readNumber();
- _winterOffStartFrame = file->readNumber();
- _winterOffEndFrame = file->readNumber();
- _springOffStartFrame = file->readNumber();
- _springOffEndFrame = file->readNumber();
- _summerOffStartFrame1 = file->readNumber();
- _summerOffEndFrame1 = file->readNumber();
- _summerOffStartFrame2 = file->readNumber();
- _summerOffEndFrame2 = file->readNumber();
- _autumnOffStartFrame1 = file->readNumber();
- _autumnOffEndFrame1 = file->readNumber();
- _autumnOffStartFrame2 = file->readNumber();
- _autumnOffEndFrame2 = file->readNumber();
- _winterOnStartFrame = file->readNumber();
- _winterOnEndFrame = file->readNumber();
- _springOnStartFrame = file->readNumber();
- _springOnEndFrame = file->readNumber();
- _summerOnStartFrame1 = file->readNumber();
- _summerOnEndFrame1 = file->readNumber();
- _summerOnStartFrame2 = file->readNumber();
- _summerOnEndFrame2 = file->readNumber();
- _autumnOnStartFrame1 = file->readNumber();
- _autumnOnEndFrame1 = file->readNumber();
- _autumnOnStartFrame2 = file->readNumber();
- _autumnOnEndFrame2 = file->readNumber();
+ _startFrameSpringOff = file->readNumber();
+ _endFrameSpringOff = file->readNumber();
+ _startFrameSummerOff = file->readNumber();
+ _endFrameSummerOff = file->readNumber();
+ _startFrameAutumnOff1 = file->readNumber();
+ _endFrameAutumnOff1 = file->readNumber();
+ _startFrameAutumnOff2 = file->readNumber();
+ _endFrameAutumnOff2 = file->readNumber();
+ _startFrameWinterOff1 = file->readNumber();
+ _endFrameWinterOff1 = file->readNumber();
+ _startFrameWinterOff2 = file->readNumber();
+ _endFrameWinterOff2 = file->readNumber();
+ _startFrameSpringOn = file->readNumber();
+ _endFrameSpringOn = file->readNumber();
+ _startFrameSummerOn = file->readNumber();
+ _endFrameSummerOn = file->readNumber();
+ _startFrameAutumnOn1 = file->readNumber();
+ _endFrameAutumnOn1 = file->readNumber();
+ _startFrameAutumnOn2 = file->readNumber();
+ _endFrameAutumnOn2 = file->readNumber();
+ _startFrameWinterOn1 = file->readNumber();
+ _endFrameWinterOn1 = file->readNumber();
+ _startFrameWinterOn2 = file->readNumber();
+ _endFrameWinterOn2 = file->readNumber();
_viewName2 = file->readString();
CBackground::load(file);
@@ -213,28 +212,28 @@ bool CArboretumGate::LeaveViewMsg(CLeaveViewMsg *msg) {
bool CArboretumGate::TurnOff(CTurnOff *msg) {
if (!_v3) {
switch (_seasonNum) {
- case SPRING:
- playMovie(_springOffStartFrame, _springOffEndFrame, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ case SEASON_SUMMER:
+ playMovie(_startFrameSummerOff, _endFrameSummerOff, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
break;
- case SUMMER:
+ case SEASON_AUTUMN:
if (_v1) {
- playMovie(_summerOffStartFrame2, _summerOffEndFrame2, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ playMovie(_startFrameAutumnOff2, _endFrameAutumnOff2, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
} else {
- playMovie(_summerOffStartFrame1, _summerOffEndFrame1, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ playMovie(_startFrameAutumnOff1, _endFrameAutumnOff1, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
}
break;
- case AUTUMN:
+ case SEASON_WINTER:
if (_v1) {
- playMovie(_autumnOffStartFrame2, _autumnOffEndFrame2, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ playMovie(_startFrameWinterOff2, _endFrameWinterOff2, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
} else {
- playMovie(_autumnOffStartFrame1, _autumnOffEndFrame1, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ playMovie(_startFrameWinterOff1, _endFrameWinterOff1, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
}
break;
- case WINTER:
- playMovie(_winterOffStartFrame, _winterOffEndFrame, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ case SEASON_SPRING:
+ playMovie(_startFrameSpringOff, _endFrameSpringOff, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
break;
default:
@@ -256,28 +255,28 @@ bool CArboretumGate::TurnOn(CTurnOn *msg) {
setVisible(true);
switch (_seasonNum) {
- case SPRING:
- playMovie(_springOnStartFrame, _springOnEndFrame, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ case SEASON_SUMMER:
+ playMovie(_startFrameSummerOn, _endFrameSummerOn, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
break;
- case SUMMER:
+ case SEASON_AUTUMN:
if (_v1) {
- playMovie(_summerOnStartFrame2, _summerOnEndFrame2, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ playMovie(_startFrameAutumnOn2, _endFrameAutumnOn2, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
} else {
- playMovie(_summerOnStartFrame1, _summerOnEndFrame1, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ playMovie(_startFrameAutumnOn1, _endFrameAutumnOn1, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
}
break;
- case AUTUMN:
+ case SEASON_WINTER:
if (_v1) {
- playMovie(_autumnOnStartFrame2, _autumnOnEndFrame2, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ playMovie(_startFrameWinterOn2, _endFrameWinterOn2, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
} else {
- playMovie(_autumnOnStartFrame1, _autumnOnEndFrame1, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ playMovie(_startFrameWinterOn1, _endFrameWinterOn1, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
}
break;
- case WINTER:
- playMovie(_winterOnStartFrame, _winterOnEndFrame, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ case SEASON_SPRING:
+ playMovie(_startFrameSpringOn, _endFrameSpringOn, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
break;
default:
@@ -302,20 +301,20 @@ bool CArboretumGate::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
bool CArboretumGate::EnterViewMsg(CEnterViewMsg *msg) {
if (!_v3) {
switch (_seasonNum) {
- case SPRING:
- _initialFrame = _springOffStartFrame;
+ case SEASON_SUMMER:
+ _initialFrame = _startFrameSummerOff;
break;
- case SUMMER:
- _initialFrame = _v1 ? _summerOffStartFrame2 : _summerOffStartFrame1;
+ case SEASON_AUTUMN:
+ _initialFrame = _v1 ? _startFrameAutumnOff2 : _startFrameAutumnOff1;
break;
- case AUTUMN:
- _initialFrame = _v1 ? _autumnOffStartFrame1 : _autumnOffStartFrame2;
+ case SEASON_WINTER:
+ _initialFrame = _v1 ? _startFrameWinterOff1 : _startFrameWinterOff2;
break;
- case WINTER:
- _initialFrame = _winterOffStartFrame;
+ case SEASON_SPRING:
+ _initialFrame = _startFrameSpringOff;
break;
default:
diff --git a/engines/titanic/game/arboretum_gate.h b/engines/titanic/game/arboretum_gate.h
index 62c9200a64..b1c06cf773 100644
--- a/engines/titanic/game/arboretum_gate.h
+++ b/engines/titanic/game/arboretum_gate.h
@@ -47,30 +47,30 @@ private:
int _seasonNum;
CString _viewName1;
int _fieldF0;
- int _winterOffStartFrame;
- int _winterOffEndFrame;
- int _springOffStartFrame;
- int _springOffEndFrame;
- int _summerOffStartFrame2;
- int _summerOffEndFrame2;
- int _summerOffStartFrame1;
- int _summerOffEndFrame1;
- int _autumnOffStartFrame2;
- int _autumnOffEndFrame2;
- int _autumnOffStartFrame1;
- int _autumnOffEndFrame1;
- int _winterOnStartFrame;
- int _winterOnEndFrame;
- int _springOnStartFrame;
- int _springOnEndFrame;
- int _summerOnStartFrame1;
- int _summerOnEndFrame1;
- int _summerOnStartFrame2;
- int _summerOnEndFrame2;
- int _autumnOnStartFrame1;
- int _autumnOnEndFrame1;
- int _autumnOnStartFrame2;
- int _autumnOnEndFrame2;
+ int _startFrameSpringOff;
+ int _endFrameSpringOff;
+ int _startFrameSummerOff;
+ int _endFrameSummerOff;
+ int _startFrameAutumnOff2;
+ int _endFrameAutumnOff2;
+ int _startFrameAutumnOff1;
+ int _endFrameAutumnOff1;
+ int _startFrameWinterOff2;
+ int _endFrameWinterOff2;
+ int _startFrameWinterOff1;
+ int _endFrameWinterOff1;
+ int _startFrameSpringOn;
+ int _endFrameSpringOn;
+ int _startFrameSummerOn;
+ int _endFrameSummerOn;
+ int _startFrameAutumnOn1;
+ int _endFrameAutumnOn1;
+ int _startFrameAutumnOn2;
+ int _endFrameAutumnOn2;
+ int _startFrameWinterOn1;
+ int _endFrameWinterOn1;
+ int _startFrameWinterOn2;
+ int _endFrameWinterOn2;
CString _viewName2;
public:
CLASSDEF;
diff --git a/engines/titanic/game/code_wheel.cpp b/engines/titanic/game/code_wheel.cpp
index d8ce48e390..94ee25435a 100644
--- a/engines/titanic/game/code_wheel.cpp
+++ b/engines/titanic/game/code_wheel.cpp
@@ -24,13 +24,20 @@
namespace Titanic {
-CodeWheel::CodeWheel() : CBomb(), _field108(0), _field10C(4), _field110(0) {
+BEGIN_MESSAGE_MAP(CodeWheel, CBomb)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(MouseButtonUpMsg)
+ ON_MESSAGE(MovieEndMsg)
+END_MESSAGE_MAP()
+
+CodeWheel::CodeWheel() : CBomb(), _field108(0), _state(4), _field110(0) {
}
void CodeWheel::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_field108, indent);
- file->writeNumberLine(_field10C, indent);
+ file->writeNumberLine(_state, indent);
file->writeNumberLine(_field110, indent);
CBomb::save(file, indent);
@@ -39,10 +46,63 @@ void CodeWheel::save(SimpleFile *file, int indent) {
void CodeWheel::load(SimpleFile *file) {
file->readNumber();
_field108 = file->readNumber();
- _field10C = file->readNumber();
+ _state = file->readNumber();
_field110 = file->readNumber();
CBomb::load(file);
}
+bool CodeWheel::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ static const int START_FRAMES[15] = {
+ 0, 5, 10, 15, 19, 24, 28, 33, 38, 42, 47, 52, 57, 61, 66
+ };
+ static const int END_FRAMES[15] = {
+ 5, 10, 15, 19, 24, 28, 33, 38, 42, 47, 52, 57, 61, 66, 70
+ };
+
+ int yp = _bounds.top + _bounds.height() / 2;
+ if (msg->_mousePos.y > yp) {
+ if (_state == _field108)
+ _field110 = true;
+
+ _state = (_state + 1) % 15;
+ playMovie(START_FRAMES[_state], END_FRAMES[_state],
+ MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
+ } else {
+ if (_state == _field108)
+ _field110 = true;
+
+ playMovie(START_FRAMES[14 - _state] + 68, END_FRAMES[14 - _state] + 68,
+ MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
+
+ _state = (_state <= 0) ? 14 : _state - 1;
+ }
+
+ playSound("z#59.wav");
+ return true;
+}
+
+bool CodeWheel::EnterViewMsg(CEnterViewMsg *msg) {
+ loadFrame(24);
+ _state = 4;
+ return true;
+}
+
+bool CodeWheel::MouseButtonUpMsg(CMouseButtonUpMsg *msg) {
+ return true;
+}
+
+bool CodeWheel::MovieEndMsg(CMovieEndMsg *msg) {
+ sleep(200);
+ CStatusChangeMsg changeMsg;
+ changeMsg._newStatus = 0;
+ if (_field110)
+ changeMsg._newStatus = -1;
+ if (_field108 == _state)
+ changeMsg._newStatus = 1;
+ changeMsg.execute("Bomb");
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/code_wheel.h b/engines/titanic/game/code_wheel.h
index 63af97c6fb..e38a45b631 100644
--- a/engines/titanic/game/code_wheel.h
+++ b/engines/titanic/game/code_wheel.h
@@ -28,9 +28,14 @@
namespace Titanic {
class CodeWheel : public CBomb {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool MouseButtonUpMsg(CMouseButtonUpMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
private:
int _field108;
- int _field10C;
+ int _state;
int _field110;
public:
CLASSDEF;
diff --git a/engines/titanic/game/head_smash_lever.cpp b/engines/titanic/game/head_smash_lever.cpp
index d5c2eaf8c4..dabed26478 100644
--- a/engines/titanic/game/head_smash_lever.cpp
+++ b/engines/titanic/game/head_smash_lever.cpp
@@ -32,13 +32,13 @@ BEGIN_MESSAGE_MAP(CHeadSmashLever, CBackground)
END_MESSAGE_MAP()
CHeadSmashLever::CHeadSmashLever() : CBackground(),
- _enabled(false), _fieldE4(false), _ticksCount(0) {}
+ _enabled(false), _fieldE4(false), _ticks(0) {}
void CHeadSmashLever::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_enabled, indent);
file->writeNumberLine(_fieldE4, indent);
- file->writeNumberLine(_ticksCount, indent);
+ file->writeNumberLine(_ticks, indent);
CBackground::save(file, indent);
}
@@ -47,7 +47,7 @@ void CHeadSmashLever::load(SimpleFile *file) {
file->readNumber();
_enabled = file->readNumber();
_fieldE4 = file->readNumber();
- _ticksCount = file->readNumber();
+ _ticks = file->readNumber();
CBackground::load(file);
}
@@ -58,7 +58,7 @@ bool CHeadSmashLever::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
playSound("z#54.wav");
int soundHandle = playSound("z#45.wav");
queueSound("z#49.wav", soundHandle);
- _ticksCount = getTicksCount();
+ _ticks = getTicksCount();
_fieldE4 = true;
} else {
playMovie(0);
@@ -78,7 +78,7 @@ bool CHeadSmashLever::ActMsg(CActMsg *msg) {
}
bool CHeadSmashLever::FrameMsg(CFrameMsg *msg) {
- if (_fieldE4 && msg->_ticks > (_ticksCount + 750)) {
+ if (_fieldE4 && msg->_ticks > (_ticks + 750)) {
CActMsg actMsg1("CreatorsChamber.Node 1.S");
actMsg1.execute("MoveToCreators");
CActMsg actMsg2("PlayToEnd");
@@ -93,7 +93,7 @@ bool CHeadSmashLever::FrameMsg(CFrameMsg *msg) {
bool CHeadSmashLever::LoadSuccessMsg(CLoadSuccessMsg *msg) {
if (_fieldE4)
- _ticksCount = getTicksCount();
+ _ticks = getTicksCount();
return true;
}
diff --git a/engines/titanic/game/head_smash_lever.h b/engines/titanic/game/head_smash_lever.h
index e2426b68da..19de07922a 100644
--- a/engines/titanic/game/head_smash_lever.h
+++ b/engines/titanic/game/head_smash_lever.h
@@ -36,7 +36,7 @@ class CHeadSmashLever : public CBackground {
public:
bool _enabled;
bool _fieldE4;
- int _ticksCount;
+ uint _ticks;
public:
CLASSDEF;
CHeadSmashLever();
diff --git a/engines/titanic/game/long_stick_dispenser.cpp b/engines/titanic/game/long_stick_dispenser.cpp
index cb562ec3ca..08a29f2e4b 100644
--- a/engines/titanic/game/long_stick_dispenser.cpp
+++ b/engines/titanic/game/long_stick_dispenser.cpp
@@ -21,9 +21,21 @@
*/
#include "titanic/game/long_stick_dispenser.h"
+#include "titanic/core/project_item.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CLongStickDispenser, CGameObject)
+ ON_MESSAGE(PuzzleSolvedMsg)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(VisibleMsg)
+ ON_MESSAGE(EnterRoomMsg)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(LeaveViewMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(MouseDragStartMsg)
+END_MESSAGE_MAP()
+
void CLongStickDispenser::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_fieldBC, indent);
@@ -42,10 +54,97 @@ void CLongStickDispenser::load(SimpleFile *file) {
CGameObject::load(file);
}
+bool CLongStickDispenser::PuzzleSolvedMsg(CPuzzleSolvedMsg *msg) {
+ if (!_fieldBC && !_fieldC4 && !_fieldC0) {
+ CStatusChangeMsg statusMsg;
+ statusMsg.execute("ShatterGlass");
+ _fieldC0 = 1;
+ loadFrame(19);
+ } else if (_fieldC0) {
+ playSound("z#63.wav");
+ petDisplayMessage(1, "'This glass is totally and utterly unbreakable.");
+ }
+
+ return true;
+}
+
+bool CLongStickDispenser::MovieEndMsg(CMovieEndMsg *msg) {
+ CPuzzleSolvedMsg puzzleMsg;
+ puzzleMsg.execute("LongStick");
+ _fieldC0 = 1;
+ return true;
+}
+
+bool CLongStickDispenser::VisibleMsg(CVisibleMsg *msg) {
+ setVisible(msg->_visible);
+ return true;
+}
+
bool CLongStickDispenser::EnterRoomMsg(CEnterRoomMsg *msg) {
_fieldC0 = 0;
_fieldC4 = 1;
return true;
}
+bool CLongStickDispenser::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (!_fieldC0) {
+ playSound("z#62.wav");
+
+ switch (_fieldBC) {
+ case 0:
+ petDisplayMessage(1, "For emergency long stick, smash glass.");
+ break;
+ case 1:
+ petDisplayMessage(1, "This dispenser has suddenly been fitted with unbreakable glass "
+ "to prevent unseemly hoarding of sticks.");
+ break;
+ default:
+ break;
+ }
+ }
+
+ return true;
+}
+
+bool CLongStickDispenser::LeaveViewMsg(CLeaveViewMsg *msg) {
+ if (_fieldC0 == 1) {
+ if (_fieldC4) {
+ playMovie(19, 38, MOVIE_GAMESTATE);
+ } else {
+ playMovie(0, 18, MOVIE_GAMESTATE);
+ _fieldBC = 1;
+ }
+
+ _fieldC4 = 1;
+ _fieldC0 = 0;
+ }
+
+ return true;
+}
+
+bool CLongStickDispenser::EnterViewMsg(CEnterViewMsg *msg) {
+ setVisible(true);
+ loadFrame(38);
+ _cursorId = CURSOR_HAND;
+ return true;
+}
+
+bool CLongStickDispenser::MouseDragStartMsg(CMouseDragStartMsg *msg) {
+ if (!checkStartDragging(msg)) {
+ return false;
+ } else if (_fieldC0 == 1 && _fieldC4 == 1) {
+ CVisibleMsg visibleMsg(true);
+ visibleMsg.execute("LongStick");
+ CPassOnDragStartMsg dragMsg(msg->_mousePos, 1);
+ dragMsg.execute("LongStick");
+
+ msg->_dragItem = getRoot()->findByName("LongStick");
+ loadFrame(0);
+ _fieldC4 = 0;
+ _cursorId = CURSOR_ARROW;
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/long_stick_dispenser.h b/engines/titanic/game/long_stick_dispenser.h
index 2a1b86fb84..be05ef9c65 100644
--- a/engines/titanic/game/long_stick_dispenser.h
+++ b/engines/titanic/game/long_stick_dispenser.h
@@ -29,7 +29,15 @@
namespace Titanic {
class CLongStickDispenser : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool PuzzleSolvedMsg(CPuzzleSolvedMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool VisibleMsg(CVisibleMsg *msg);
bool EnterRoomMsg(CEnterRoomMsg *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool MouseDragStartMsg(CMouseDragStartMsg *msg);
private:
int _fieldBC;
int _fieldC0;
diff --git a/engines/titanic/game/maitred/maitred_arm_holder.cpp b/engines/titanic/game/maitred/maitred_arm_holder.cpp
index 4d35277a33..75d95640d2 100644
--- a/engines/titanic/game/maitred/maitred_arm_holder.cpp
+++ b/engines/titanic/game/maitred/maitred_arm_holder.cpp
@@ -24,6 +24,11 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMaitreDArmHolder, CDropTarget)
+ ON_MESSAGE(MaitreDArmHolder)
+ ON_MESSAGE(ActMsg)
+END_MESSAGE_MAP()
+
void CMaitreDArmHolder::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CDropTarget::save(file, indent);
@@ -34,4 +39,18 @@ void CMaitreDArmHolder::load(SimpleFile *file) {
CDropTarget::load(file);
}
+bool CMaitreDArmHolder::MaitreDArmHolder(CMaitreDArmHolder *msg) {
+ _fieldF4 = 0;
+ return true;
+}
+
+bool CMaitreDArmHolder::ActMsg(CActMsg *msg) {
+ if (msg->_action == "LoseArm") {
+ _bounds = Rect();
+ setVisible(false);
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/maitred/maitred_arm_holder.h b/engines/titanic/game/maitred/maitred_arm_holder.h
index 3392d60e43..22f961f236 100644
--- a/engines/titanic/game/maitred/maitred_arm_holder.h
+++ b/engines/titanic/game/maitred/maitred_arm_holder.h
@@ -28,6 +28,9 @@
namespace Titanic {
class CMaitreDArmHolder : public CDropTarget {
+ DECLARE_MESSAGE_MAP;
+ bool MaitreDArmHolder(CMaitreDArmHolder *msg);
+ bool ActMsg(CActMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/maitred/maitred_body.cpp b/engines/titanic/game/maitred/maitred_body.cpp
index 6b495e5a1c..4cb12aac8f 100644
--- a/engines/titanic/game/maitred/maitred_body.cpp
+++ b/engines/titanic/game/maitred/maitred_body.cpp
@@ -20,20 +20,56 @@
*
*/
-#include "titanic/game/maitred/maitred_legs.h"
+#include "titanic/game/maitred/maitred_body.h"
namespace Titanic {
-void CMaitreDLegs::save(SimpleFile *file, int indent) {
+BEGIN_MESSAGE_MAP(CMaitreDBody, CMaitreDProdReceptor)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(AnimateMaitreDMsg)
+ ON_MESSAGE(ActMsg)
+END_MESSAGE_MAP()
+
+void CMaitreDBody::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldC8, indent);
+ file->writeNumberLine(_armed, indent);
CMaitreDProdReceptor::save(file, indent);
}
-void CMaitreDLegs::load(SimpleFile *file) {
+void CMaitreDBody::load(SimpleFile *file) {
file->readNumber();
- _fieldC8 = file->readNumber();
+ _armed = file->readNumber();
CMaitreDProdReceptor::load(file);
}
+bool CMaitreDBody::EnterViewMsg(CEnterViewMsg *msg) {
+ return true;
+}
+
+bool CMaitreDBody::AnimateMaitreDMsg(CAnimateMaitreDMsg *msg) {
+ static const char *const ARMED_CLIPS[5] = {
+ "Talking 1", "Talking 2", "Talking 3", "Talking 4", nullptr
+ };
+ static const char *const UNARMED_CLIPS[5] = {
+ "Armless Talking 1", "Armless Talking 2", "Armless Talking 3",
+ "Armless Talking 4", nullptr
+ };
+
+ if (!hasActiveMovie()) {
+ playRandomClip(_armed ? ARMED_CLIPS : UNARMED_CLIPS);
+ }
+
+ return true;
+}
+
+bool CMaitreDBody::ActMsg(CActMsg *msg) {
+ if (msg->_action == "LoseArm") {
+ _armed = false;
+ loadFrame(262);
+ playSound("c#75.wav");
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/maitred/maitred_body.h b/engines/titanic/game/maitred/maitred_body.h
index 7016c15c71..1798958e84 100644
--- a/engines/titanic/game/maitred/maitred_body.h
+++ b/engines/titanic/game/maitred/maitred_body.h
@@ -28,11 +28,15 @@
namespace Titanic {
class CMaitreDBody : public CMaitreDProdReceptor {
+ DECLARE_MESSAGE_MAP;
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool AnimateMaitreDMsg(CAnimateMaitreDMsg *msg);
+ bool ActMsg(CActMsg *msg);
private:
- int _fieldC8;
+ bool _armed;
public:
CLASSDEF;
- CMaitreDBody() : CMaitreDProdReceptor(), _fieldC8(1) {}
+ CMaitreDBody() : CMaitreDProdReceptor(), _armed(true) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/maitred/maitred_legs.cpp b/engines/titanic/game/maitred/maitred_legs.cpp
index 5071805101..8c0b0db5ea 100644
--- a/engines/titanic/game/maitred/maitred_legs.cpp
+++ b/engines/titanic/game/maitred/maitred_legs.cpp
@@ -20,20 +20,76 @@
*
*/
-#include "titanic/game/maitred/maitred_body.h"
+#include "titanic/game/maitred/maitred_legs.h"
namespace Titanic {
-void CMaitreDBody::save(SimpleFile *file, int indent) {
+BEGIN_MESSAGE_MAP(CMaitreDLegs, CMaitreDProdReceptor)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(AnimateMaitreDMsg)
+END_MESSAGE_MAP()
+
+void CMaitreDLegs::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldC8, indent);
+ file->writeNumberLine(_flag, indent);
CMaitreDProdReceptor::save(file, indent);
}
-void CMaitreDBody::load(SimpleFile *file) {
+void CMaitreDLegs::load(SimpleFile *file) {
file->readNumber();
- _fieldC8 = file->readNumber();
+ _flag = file->readNumber();
CMaitreDProdReceptor::load(file);
}
+bool CMaitreDLegs::EnterViewMsg(CEnterViewMsg *msg) {
+ _flag = true;
+ loadFrame(0);
+ return true;
+}
+
+bool CMaitreDLegs::AnimateMaitreDMsg(CAnimateMaitreDMsg *msg) {
+ static const char *const WIGGLE_CLIPS[4] = {
+ "Hip Wiggle", "Knee Bend", "Wire Wiggle", nullptr
+ };
+ static const char *const FIGHTING_CLIPS[4] = {
+ "Fighting 1", "Fighting 2", "Leg Fidget", nullptr
+ };
+ static const char *const ARCING_SOUNDS[9] = {
+ "MaitreD Arcing 1.wav", "MaitreD Arcing 2.wav",
+ "MaitreD Arcing 3.wav", "MaitreD Arcing 4.wav",
+ "MaitreD Arcing 5.wav", "MaitreD Arcing 6.wav",
+ "MaitreD Arcing 7.wav", "MaitreD Arcing 8.wav",
+ "MaitreD Arcing 9.wav"
+ };
+
+ switch (msg->_value) {
+ case 0:
+ if (_flag) {
+ playRandomClip(FIGHTING_CLIPS);
+
+ if (getRandomNumber(2) != 0)
+ playSound(ARCING_SOUNDS[getRandomNumber(9)],
+ 40 + getRandomNumber(30));
+ } else {
+ playClip("Walk Right");
+ _flag = true;
+ }
+ break;
+
+ case 1:
+ if (_flag) {
+ playClip("Walk Left");
+ _flag = false;
+ } else {
+ playRandomClip(WIGGLE_CLIPS);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/maitred/maitred_legs.h b/engines/titanic/game/maitred/maitred_legs.h
index 24ba01e712..b8a32eef4c 100644
--- a/engines/titanic/game/maitred/maitred_legs.h
+++ b/engines/titanic/game/maitred/maitred_legs.h
@@ -28,11 +28,14 @@
namespace Titanic {
class CMaitreDLegs : public CMaitreDProdReceptor {
+ DECLARE_MESSAGE_MAP;
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool AnimateMaitreDMsg(CAnimateMaitreDMsg *msg);
private:
- int _fieldC8;
+ bool _flag;
public:
CLASSDEF;
- CMaitreDLegs() : CMaitreDProdReceptor(), _fieldC8(1) {}
+ CMaitreDLegs() : CMaitreDProdReceptor(), _flag(true) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/maitred/maitred_prod_receptor.cpp b/engines/titanic/game/maitred/maitred_prod_receptor.cpp
index 4823f143b0..66533a542f 100644
--- a/engines/titanic/game/maitred/maitred_prod_receptor.cpp
+++ b/engines/titanic/game/maitred/maitred_prod_receptor.cpp
@@ -21,13 +21,21 @@
*/
#include "titanic/game/maitred/maitred_prod_receptor.h"
+#include "titanic/npcs/maitre_d.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMaitreDProdReceptor, CGameObject)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(MouseMoveMsg)
+ ON_MESSAGE(ProdMaitreDMsg)
+ ON_MESSAGE(DisableMaitreDProdReceptor)
+END_MESSAGE_MAP()
+
void CMaitreDProdReceptor::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_fieldBC, indent);
- file->writeNumberLine(_fieldC0, indent);
+ file->writeNumberLine(_counter, indent);
file->writeNumberLine(_fieldC4, indent);
CGameObject::save(file, indent);
@@ -36,10 +44,79 @@ void CMaitreDProdReceptor::save(SimpleFile *file, int indent) {
void CMaitreDProdReceptor::load(SimpleFile *file) {
file->readNumber();
_fieldBC = file->readNumber();
- _fieldC0 = file->readNumber();
+ _counter = file->readNumber();
_fieldC4 = file->readNumber();
CGameObject::load(file);
}
+bool CMaitreDProdReceptor::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (_fieldBC == 2 && static_cast<CGameObject *>(getParent())->hasActiveMovie()) {
+ return false;
+ } else {
+ CProdMaitreDMsg prodMsg(126);
+ prodMsg.execute(this);
+ return true;
+ }
+}
+
+bool CMaitreDProdReceptor::MouseMoveMsg(CMouseMoveMsg *msg) {
+ if (_fieldBC == 2 && static_cast<CGameObject *>(getParent())->hasActiveMovie())
+ return false;
+ else if (++_counter < 20)
+ return true;
+
+ _counter = 0;
+ CProdMaitreDMsg prodMsg(126);
+
+ if (isEquals("Stick"))
+ prodMsg._value = 121;
+ else if (isEquals("Hammer"))
+ prodMsg._value = 122;
+ else if (isEquals("Lemon"))
+ prodMsg._value = 123;
+ else if (isEquals("Chicken"))
+ prodMsg._value = 124;
+ else if (isEquals("Perch"))
+ prodMsg._value = 125;
+
+ CMaitreD *maitreD = static_cast<CMaitreD *>(findRoomObject("MaitreD"));
+ if (maitreD->_field100 <= 0)
+ prodMsg.execute(this);
+
+ return true;
+}
+
+bool CMaitreDProdReceptor::ProdMaitreDMsg(CProdMaitreDMsg *msg) {
+ if (_fieldC4) {
+ CMaitreD *maitreD = static_cast<CMaitreD *>(findRoomObject("MaitreD"));
+ if (maitreD->_field100 <= 0) {
+ CViewItem *view = findView();
+ startTalking(maitreD, msg->_value, view);
+
+ switch (_fieldBC) {
+ case 1:
+ startTalking(maitreD, 128, view);
+ break;
+ case 2:
+ startTalking(maitreD, 129, view);
+ break;
+ case 3:
+ startTalking(maitreD, 127, view);
+ break;
+ default:
+ startTalking(maitreD, 130, view);
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool CMaitreDProdReceptor::DisableMaitreDProdReceptor(CDisableMaitreDProdReceptor *msg) {
+ _fieldC4 = 0;
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/maitred/maitred_prod_receptor.h b/engines/titanic/game/maitred/maitred_prod_receptor.h
index f3a547b8ef..0b00ce0014 100644
--- a/engines/titanic/game/maitred/maitred_prod_receptor.h
+++ b/engines/titanic/game/maitred/maitred_prod_receptor.h
@@ -28,14 +28,19 @@
namespace Titanic {
class CMaitreDProdReceptor : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool MouseMoveMsg(CMouseMoveMsg *msg);
+ bool ProdMaitreDMsg(CProdMaitreDMsg *msg);
+ bool DisableMaitreDProdReceptor(CDisableMaitreDProdReceptor *msg);
protected:
int _fieldBC;
- int _fieldC0;
+ int _counter;
int _fieldC4;
public:
CLASSDEF;
CMaitreDProdReceptor() : CGameObject(),
- _fieldBC(0), _fieldC0(0), _fieldC4(1) {}
+ _fieldBC(0), _counter(0), _fieldC4(1) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/missiveomat.cpp b/engines/titanic/game/missiveomat.cpp
index 931b146801..6f47131716 100644
--- a/engines/titanic/game/missiveomat.cpp
+++ b/engines/titanic/game/missiveomat.cpp
@@ -21,35 +21,310 @@
*/
#include "titanic/game/missiveomat.h"
+#include "titanic/core/room_item.h"
+#include "titanic/titanic.h"
namespace Titanic {
-CMissiveOMat::CMissiveOMat() : CGameObject(), _fieldBC(1),
- _fieldC0(0), _fieldC4(0), _fieldE0(-1) {
+BEGIN_MESSAGE_MAP(CMissiveOMat, CGameObject)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(KeyCharMsg)
+ ON_MESSAGE(TimerMsg)
+ ON_MESSAGE(MissiveOMatActionMsg)
+ ON_MESSAGE(LeaveViewMsg)
+END_MESSAGE_MAP()
+
+CMissiveOMat::CMissiveOMat() : CGameObject(), _mode(1),
+ _totalMessages(0), _messageNum(0), _personIndex(-1) {
+ // Load data for the messages, their from and to names
+ loadArray(_welcomeMessages, "TEXT/MISSIVEOMAT/WELCOME", 3);
+ loadArray(_messages, "TEXT/MISSIVEOMAT/MESSAGES", 58);
+ loadArray(_from, "TEXT/MISSIVEOMAT/FROM", 58);
+ loadArray(_to, "TEXT/MISSIVEOMAT/TO", 58);
+}
+
+void CMissiveOMat::loadArray(CString *arr, const CString &resName, int count) {
+ Common::SeekableReadStream *s = g_vm->_filesManager->getResource(resName);
+ for (int idx = 0; idx < count; ++idx)
+ arr[idx] = readStringFromStream(s);
+ delete s;
}
void CMissiveOMat::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldBC, indent);
- file->writeNumberLine(_fieldC0, indent);
- file->writeNumberLine(_fieldC4, indent);
+ file->writeNumberLine(_mode, indent);
+ file->writeNumberLine(_totalMessages, indent);
+ file->writeNumberLine(_messageNum, indent);
file->writeQuotedLine(_string1, indent);
file->writeQuotedLine(_string2, indent);
- file->writeNumberLine(_fieldE0, indent);
+ file->writeNumberLine(_personIndex, indent);
CGameObject::save(file, indent);
}
void CMissiveOMat::load(SimpleFile *file) {
file->readNumber();
- _fieldBC = file->readNumber();
- _fieldC0 = file->readNumber();
- _fieldC4 = file->readNumber();
+ _mode = file->readNumber();
+ _totalMessages = file->readNumber();
+ _messageNum = file->readNumber();
_string1 = file->readString();
_string2 = file->readString();
- _fieldE0 = file->readNumber();
+ _personIndex = file->readNumber();
CGameObject::load(file);
}
+bool CMissiveOMat::EnterViewMsg(CEnterViewMsg *msg) {
+ CMissiveOMatActionMsg actionMsg(9);
+ actionMsg.execute(this);
+ return true;
+}
+
+bool CMissiveOMat::KeyCharMsg(CKeyCharMsg *msg) {
+ CTreeItem *loginControl = findRoom()->findByName("MissiveOMat Login Control");
+ CTreeItem *welcome = findRoom()->findByName("MissiveOMat Welcome");
+ CTreeItem *scrollUp = findRoom()->findByName("MissiveOMat ScrollUp Button");
+ CEditControlMsg editMsg;
+
+ switch (_mode) {
+ case 1: {
+ playSound("z#228.wav");
+ editMsg._mode = 6;
+ editMsg._param = msg->_key;
+ editMsg.execute(loginControl);
+
+ if (editMsg._param == 1000) {
+ editMsg._mode = 3;
+ editMsg.execute(loginControl);
+
+ _string1 = editMsg._text;
+ if (!_string1.empty()) {
+ loadFrame(2);
+ _mode = 2;
+
+ editMsg._mode = 1;
+ editMsg.execute(loginControl);
+ editMsg._mode = 10;
+ editMsg._param = 24;
+ editMsg.execute(loginControl);
+ }
+ }
+ break;
+ }
+
+ case 2: {
+ playSound("z#228.wav");
+ editMsg._mode = 6;
+ editMsg._param = msg->_key;
+ editMsg.execute(loginControl);
+
+ _string2 = editMsg._text;
+ if (_string1 == "Droot Scraliontis") {
+ _string1 = "Scraliontis";
+ } else if (_string1 == "Antar Brobostigon") {
+ _string1 = "Brobostigon";
+ } else if (_string1 == "colin") {
+ _string1 = "Leovinus";
+ }
+
+ bool flag = false;
+ if (_string1 == "Leovinus") {
+ if (_string2 == "Other") {
+ flag = true;
+ _personIndex = 0;
+ }
+ } else if (_string1 == "Scraliontis") {
+ if (_string2 == "This") {
+ flag = true;
+ _personIndex = 1;
+ }
+ } else if (_string1 == "Brobostigon") {
+ if (_string2 == "That") {
+ flag = true;
+ _personIndex = 2;
+ }
+ }
+
+ if (flag) {
+ _mode = 4;
+ loadFrame(4);
+ editMsg._mode = 1;
+ editMsg.execute(loginControl);
+
+ getTextCursor()->hide();
+ editMsg._mode = 13;
+ editMsg.execute(loginControl);
+
+ editMsg._mode = 12;
+ editMsg.execute(welcome);
+
+ editMsg._mode = 2;
+ editMsg._text = _welcomeMessages[_personIndex];
+ editMsg.execute(welcome);
+
+ editMsg._mode = 12;
+ editMsg._text = "MissiveOMat OK Button";
+ editMsg.execute(welcome);
+ editMsg.execute(scrollUp);
+ } else {
+ _mode = 3;
+ loadFrame(3);
+ addTimer(1500);
+
+ editMsg._mode = 1;
+ editMsg.execute(loginControl);
+
+ getTextCursor()->hide();
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool CMissiveOMat::TimerMsg(CTimerMsg *msg) {
+ if (_mode == 3) {
+ CTreeItem *loginControl = findRoom()->findByName("MissiveOMat Login Control");
+ CEditControlMsg editMsg;
+ editMsg._mode = 10;
+ editMsg._param = 8;
+ editMsg.execute(loginControl);
+ }
+
+ return true;
+}
+
+bool CMissiveOMat::MissiveOMatActionMsg(CMissiveOMatActionMsg *msg) {
+ CTreeItem *welcome = findByName("MissiveOMat Welcome");
+
+ switch (msg->_action) {
+ case MESSAGE_SHOW: {
+ CTreeItem *btnOk = findRoom()->findByName("MissiveOMat OK Button");
+ CTreeItem *btnNext = findRoom()->findByName("MissiveOMat Next Button");
+ CTreeItem *btnPrev = findRoom()->findByName("MissiveOMat Prev Button");
+ CTreeItem *btnLogout = findRoom()->findByName("MissiveOMat Logout Button");
+
+ _mode = MESSAGE_5;
+ CVisibleMsg visibleMsg;
+ visibleMsg._visible = false;
+ visibleMsg.execute(btnOk);
+ visibleMsg._visible = true;
+ visibleMsg.execute(btnNext);
+ visibleMsg.execute(btnPrev);
+ visibleMsg.execute(btnLogout);
+
+ _messageNum = 0;
+ _totalMessages = 0;
+ CString *strP = &_messages[_personIndex * 19];
+ for (_totalMessages = 0; !strP->empty(); ++strP, ++_totalMessages)
+ ;
+
+ CMissiveOMatActionMsg actionMsg;
+ actionMsg._action = REDRAW_MESSAGE;
+ actionMsg.execute(this);
+ break;
+ }
+
+ case NEXT_MESSAGE:
+ if (_messageNum < (_totalMessages - 1)) {
+ ++_messageNum;
+ CMissiveOMatActionMsg actionMsg;
+ actionMsg._action = REDRAW_MESSAGE;
+ actionMsg.execute(this);
+ }
+ break;
+
+ case PRIOR_MESSAGE:
+ if (_messageNum > 0) {
+ --_messageNum;
+ CMissiveOMatActionMsg actionMsg;
+ actionMsg._action = REDRAW_MESSAGE;
+ actionMsg.execute(this);
+ }
+ break;
+
+ case MESSAGE_5: {
+ CMissiveOMatActionMsg actionMsg;
+ actionMsg._action = MESSAGE_9;
+ actionMsg.execute(this);
+ break;
+ }
+
+ case MESSAGE_DOWN:
+ if (welcome)
+ scrollTextDown();
+ break;
+
+ case MESSAGE_UP:
+ if (welcome)
+ scrollTextUp();
+ break;
+
+ case REDRAW_MESSAGE:
+ if (welcome) {
+ CString str = CString::format(
+ "Missive %d of %d.\nFrom: %s\nTo: %s\n\n%s\n",
+ _messageNum + 1, _totalMessages, _from[_messageNum].c_str(),
+ _to[_messageNum].c_str(), _messages[_messageNum].c_str());
+
+ setText(str);
+ }
+ break;
+
+ case MESSAGE_9: {
+ loadFrame(1);
+ _mode = MESSAGE_NONE;
+ _personIndex = -1;
+
+ static const char *const WIDGETS[7] = {
+ "MissiveOMat Login Control", "MissiveOMat OK Button",
+ "MissiveOMat Next Button", "MissiveOMat Prev Button",
+ "MissiveOMat Logout Button", "MissiveOMat ScrollDown Button",
+ "MissiveOMat ScrollUp Button"
+ };
+ CEditControlMsg editMsg;
+
+ for (int idx = 0; idx < 7; ++idx) {
+ editMsg._mode = 0;
+ editMsg._param = 12;
+ editMsg.execute(WIDGETS[idx]);
+ editMsg._mode = 1;
+ editMsg.execute(WIDGETS[idx]);
+ editMsg._mode = 13;
+ editMsg.execute(WIDGETS[idx]);
+ }
+
+ editMsg._mode = 12;
+ editMsg.execute("MissiveOMat Login Control");
+ editMsg._mode = 10;
+ editMsg._param = 8;
+ editMsg.execute("MissiveOMat Login Control");
+ editMsg._mode = 8;
+ editMsg.execute("MissiveOMat Login Control");
+
+ _string1.clear();
+ _string2.clear();
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool CMissiveOMat::LeaveViewMsg(CLeaveViewMsg *msg) {
+ CEditControlMsg editMsg;
+ editMsg._mode = 9;
+ editMsg.execute("MissiveOMat Login Control");
+ petShowCursor();
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/missiveomat.h b/engines/titanic/game/missiveomat.h
index 7fde8cf25d..9810fcc403 100644
--- a/engines/titanic/game/missiveomat.h
+++ b/engines/titanic/game/missiveomat.h
@@ -27,14 +27,33 @@
namespace Titanic {
+enum MissiveOMatAction {
+ MESSAGE_NONE = 1, MESSAGE_SHOW = 2, NEXT_MESSAGE = 3, PRIOR_MESSAGE = 4,
+ MESSAGE_5 = 5, MESSAGE_DOWN = 6, MESSAGE_UP = 7, REDRAW_MESSAGE = 8,
+ MESSAGE_9 = 9
+};
+
class CMissiveOMat : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool KeyCharMsg(CKeyCharMsg *msg);
+ bool TimerMsg(CTimerMsg *msg);
+ bool MissiveOMatActionMsg(CMissiveOMatActionMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
+private:
+ CString _welcomeMessages[3];
+ CString _messages[58];
+ CString _from[58];
+ CString _to[58];
+private:
+ void loadArray(CString *arr, const CString &resName, int count);
public:
- int _fieldBC;
- int _fieldC0;
- int _fieldC4;
+ int _mode;
+ int _totalMessages;
+ int _messageNum;
CString _string1;
CString _string2;
- int _fieldE0;
+ int _personIndex;
public:
CLASSDEF;
CMissiveOMat();
diff --git a/engines/titanic/game/missiveomat_button.cpp b/engines/titanic/game/missiveomat_button.cpp
index d5ae75dbc2..b7ad7f8f6f 100644
--- a/engines/titanic/game/missiveomat_button.cpp
+++ b/engines/titanic/game/missiveomat_button.cpp
@@ -21,21 +21,47 @@
*/
#include "titanic/game/missiveomat_button.h"
+#include "titanic/core/room_item.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMissiveOMatButton, CEditControl)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(VisibleMsg)
+ ON_MESSAGE(MouseDoubleClickMsg)
+END_MESSAGE_MAP()
+
void CMissiveOMatButton::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldFC, indent);
+ file->writeNumberLine(_buttonId, indent);
CEditControl::save(file, indent);
}
void CMissiveOMatButton::load(SimpleFile *file) {
file->readNumber();
- _fieldFC = file->readNumber();
+ _buttonId = file->readNumber();
CEditControl::load(file);
}
+bool CMissiveOMatButton::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ CMissiveOMatActionMsg actionMsg;
+ actionMsg._action = _buttonId;
+ actionMsg.execute(findRoom()->findByName("MissiveOMat"));
+ return true;
+}
+
+bool CMissiveOMatButton::VisibleMsg(CVisibleMsg *msg) {
+ setVisible(msg->_visible);
+ return true;
+}
+
+bool CMissiveOMatButton::MouseDoubleClickMsg(CMouseDoubleClickMsg *msg) {
+ CMissiveOMatActionMsg actionMsg;
+ actionMsg._action = _buttonId;
+ actionMsg.execute(findRoom()->findByName("MissiveOMat"));
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/missiveomat_button.h b/engines/titanic/game/missiveomat_button.h
index d36f5bd958..6dbfd4cd56 100644
--- a/engines/titanic/game/missiveomat_button.h
+++ b/engines/titanic/game/missiveomat_button.h
@@ -28,11 +28,15 @@
namespace Titanic {
class CMissiveOMatButton : public CEditControl {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool VisibleMsg(CVisibleMsg *msg);
+ bool MouseDoubleClickMsg(CMouseDoubleClickMsg *msg);
public:
- int _fieldFC;
+ int _buttonId;
public:
CLASSDEF;
- CMissiveOMatButton() : CEditControl(), _fieldFC(2) {}
+ CMissiveOMatButton() : CEditControl(), _buttonId(2) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/movie_tester.cpp b/engines/titanic/game/movie_tester.cpp
index 1b266d9c7e..bbd66a9bce 100644
--- a/engines/titanic/game/movie_tester.cpp
+++ b/engines/titanic/game/movie_tester.cpp
@@ -24,18 +24,36 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMovieTester, CGameObject)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
void CMovieTester::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_value1, indent);
- file->writeNumberLine(_value2, indent);
+ file->writeNumberLine(_movieNumFrames, indent);
+ file->writeNumberLine(_movieFrameNum, indent);
CGameObject::save(file, indent);
}
void CMovieTester::load(SimpleFile *file) {
file->readNumber();
- _value1 = file->readNumber();
- _value2 = file->readNumber();
+ _movieNumFrames = file->readNumber();
+ _movieFrameNum = file->readNumber();
CGameObject::load(file);
}
+bool CMovieTester::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (msg->_buttons == MB_RIGHT) {
+ if (--_movieFrameNum < 0) {
+ _movieFrameNum = _movieNumFrames - 1;
+ }
+ } else {
+ if (++_movieFrameNum >= _movieNumFrames)
+ _movieFrameNum = 0;
+ }
+
+ loadFrame(_movieFrameNum);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/movie_tester.h b/engines/titanic/game/movie_tester.h
index de2ef2cc5e..17a7d489d8 100644
--- a/engines/titanic/game/movie_tester.h
+++ b/engines/titanic/game/movie_tester.h
@@ -28,11 +28,13 @@
namespace Titanic {
class CMovieTester : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
public:
- int _value1, _value2;
+ int _movieNumFrames, _movieFrameNum;
public:
CLASSDEF;
- CMovieTester() : CGameObject(), _value1(0), _value2(0) {}
+ CMovieTester() : CGameObject(), _movieNumFrames(0), _movieFrameNum(0) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/music_console_button.cpp b/engines/titanic/game/music_console_button.cpp
index 1bc78ffe23..9cf385e3a7 100644
--- a/engines/titanic/game/music_console_button.cpp
+++ b/engines/titanic/game/music_console_button.cpp
@@ -21,9 +21,18 @@
*/
#include "titanic/game/music_console_button.h"
+#include "titanic/core/room_item.h"
+#include "titanic/sound/music_handler.h"
+#include "titanic/titanic.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMusicConsoleButton, CMusicPlayer)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(LeaveViewMsg)
+ ON_MESSAGE(SetMusicControlsMsg)
+END_MESSAGE_MAP()
+
void CMusicConsoleButton::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CMusicPlayer::save(file, indent);
@@ -34,4 +43,91 @@ void CMusicConsoleButton::load(SimpleFile *file) {
CMusicPlayer::load(file);
}
+bool CMusicConsoleButton::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (_isActive) {
+ CStopMusicMsg stopMsg(this);
+ stopMsg.execute(this);
+ stopMovie();
+ loadFrame(0);
+ } else {
+ CStartMusicMsg startMsg(this);
+ startMsg.execute(this);
+ playMovie(MOVIE_REPEAT);
+
+ CMusicHasStartedMsg startedMsg;
+ startedMsg.execute("Music Room Phonograph");
+
+ if (CMusicRoom::_musicHandler->checkSound(1)
+ && CMusicRoom::_musicHandler->checkSound(2)
+ && CMusicRoom::_musicHandler->checkSound(3)) {
+ CCorrectMusicPlayedMsg correctMsg;
+ correctMsg.execute(findRoom());
+ }
+ }
+
+ return true;
+}
+
+bool CMusicConsoleButton::LeaveViewMsg(CLeaveViewMsg *msg) {
+ if (_isActive) {
+ CStopMusicMsg stopMsg(this);
+ stopMsg.execute(this);
+ stopMovie();
+ loadFrame(0);
+ }
+
+ return true;
+}
+
+bool CMusicConsoleButton::SetMusicControlsMsg(CSetMusicControlsMsg *msg) {
+ CMusicRoom *musicRoom = getMusicRoom();
+ CQueryMusicControlSettingMsg queryMsg;
+
+ queryMsg.execute("Bells Mute Control");
+ musicRoom->setItem5(BELLS, queryMsg._value == 1 ? 1 : 0);
+ queryMsg.execute("Bells Pitch Control");
+ musicRoom->setItem2(BELLS, queryMsg._value);
+ queryMsg.execute("Bells Speed Control");
+ musicRoom->setItem1(BELLS, queryMsg._value);
+ queryMsg.execute("Bells Inversion Control");
+ musicRoom->setItem4(BELLS, queryMsg._value == 0 ? 1 : 0);
+ queryMsg.execute("Bells Direction Control");
+ musicRoom->setItem3(BELLS, queryMsg._value == 0 ? 1 : 0);
+
+ queryMsg.execute("Snake Mute Control");
+ musicRoom->setItem5(SNAKE, queryMsg._value == 1 ? 1 : 0);
+ queryMsg.execute("Snake Pitch Control");
+ musicRoom->setItem2(SNAKE, queryMsg._value);
+ queryMsg.execute("Snake Speed Control");
+ musicRoom->setItem1(SNAKE, queryMsg._value);
+ queryMsg.execute("Snake Inversion Control");
+ musicRoom->setItem4(SNAKE, queryMsg._value == 0 ? 1 : 0);
+ queryMsg.execute("Snake Direction Control");
+ musicRoom->setItem3(SNAKE, queryMsg._value == 0 ? 1 : 0);
+
+ queryMsg.execute("Piano Mute Control");
+ musicRoom->setItem5(PIANO, queryMsg._value == 1 ? 1 : 0);
+ queryMsg.execute("Piano Pitch Control");
+ musicRoom->setItem2(PIANO, queryMsg._value);
+ queryMsg.execute("Piano Speed Control");
+ musicRoom->setItem1(PIANO, queryMsg._value);
+ queryMsg.execute("Piano Inversion Control");
+ musicRoom->setItem4(PIANO, queryMsg._value == 0 ? 1 : 0);
+ queryMsg.execute("Piano Direction Control");
+ musicRoom->setItem3(PIANO, queryMsg._value == 0 ? 1 : 0);
+
+ queryMsg.execute("Bass Mute Control");
+ musicRoom->setItem5(BASS, queryMsg._value == 1 ? 1 : 0);
+ queryMsg.execute("Bass Pitch Control");
+ musicRoom->setItem2(BASS, queryMsg._value);
+ queryMsg.execute("Bass Speed Control");
+ musicRoom->setItem1(BASS, queryMsg._value);
+ queryMsg.execute("Bass Inversion Control");
+ musicRoom->setItem4(BASS, queryMsg._value == 0 ? 1 : 0);
+ queryMsg.execute("Bass Direction Control");
+ musicRoom->setItem3(BASS, queryMsg._value == 0 ? 1 : 0);
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/music_console_button.h b/engines/titanic/game/music_console_button.h
index 8e05b698d7..80ce719c96 100644
--- a/engines/titanic/game/music_console_button.h
+++ b/engines/titanic/game/music_console_button.h
@@ -28,6 +28,10 @@
namespace Titanic {
class CMusicConsoleButton : public CMusicPlayer {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
+ bool SetMusicControlsMsg(CSetMusicControlsMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/music_room_stop_phonograph_button.cpp b/engines/titanic/game/music_room_stop_phonograph_button.cpp
index 44342fc2d6..dee2c0883e 100644
--- a/engines/titanic/game/music_room_stop_phonograph_button.cpp
+++ b/engines/titanic/game/music_room_stop_phonograph_button.cpp
@@ -24,16 +24,52 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMusicRoomStopPhonographButton, CEjectPhonographButton)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(FrameMsg)
+END_MESSAGE_MAP()
+
void CMusicRoomStopPhonographButton::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_field100, indent);
+ file->writeNumberLine(_ticks, indent);
CEjectPhonographButton::save(file, indent);
}
void CMusicRoomStopPhonographButton::load(SimpleFile *file) {
file->readNumber();
- _field100 = file->readNumber();
+ _ticks = file->readNumber();
CEjectPhonographButton::load(file);
}
+bool CMusicRoomStopPhonographButton::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (!_ejected) {
+ loadFrame(1);
+ playSound(_soundName);
+ _readyFlag = true;
+
+ CPhonographStopMsg stopMsg;
+ stopMsg.execute(getParent(), nullptr, MSGFLAG_SCAN);
+ if (stopMsg._value2) {
+ _ticks = getTicksCount();
+ } else {
+ CEjectCylinderMsg ejectMsg;
+ ejectMsg.execute(getParent(), nullptr, MSGFLAG_SCAN);
+ _ejected = true;
+ }
+ }
+
+ return true;
+}
+
+bool CMusicRoomStopPhonographButton::FrameMsg(CFrameMsg *msg) {
+ if (_readyFlag && _ticks && msg->_ticks >= (_ticks + 100)) {
+ loadFrame(0);
+ playSound(_readySoundName);
+ _ticks = 0;
+ _readyFlag = false;
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/music_room_stop_phonograph_button.h b/engines/titanic/game/music_room_stop_phonograph_button.h
index 7260e5aaab..dd9e8b4bc0 100644
--- a/engines/titanic/game/music_room_stop_phonograph_button.h
+++ b/engines/titanic/game/music_room_stop_phonograph_button.h
@@ -28,11 +28,14 @@
namespace Titanic {
class CMusicRoomStopPhonographButton : public CEjectPhonographButton {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool FrameMsg(CFrameMsg *msg);
private:
- int _field100;
+ uint _ticks;
public:
CLASSDEF;
- CMusicRoomStopPhonographButton() : CEjectPhonographButton(), _field100(0) {}
+ CMusicRoomStopPhonographButton() : CEjectPhonographButton(), _ticks(0) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/music_system_lock.cpp b/engines/titanic/game/music_system_lock.cpp
index f1e062b3ee..074864e7c3 100644
--- a/engines/titanic/game/music_system_lock.cpp
+++ b/engines/titanic/game/music_system_lock.cpp
@@ -21,9 +21,16 @@
*/
#include "titanic/game/music_system_lock.h"
+#include "titanic/core/room_item.h"
+#include "titanic/carry/carry.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMusicSystemLock, CDropTarget)
+ ON_MESSAGE(DropObjectMsg)
+ ON_MESSAGE(MovieEndMsg)
+END_MESSAGE_MAP()
+
void CMusicSystemLock::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_value, indent);
@@ -36,4 +43,25 @@ void CMusicSystemLock::load(SimpleFile *file) {
CDropTarget::load(file);
}
+bool CMusicSystemLock::DropObjectMsg(CDropObjectMsg *msg) {
+ CTreeItem *key = msg->_item->findByName("Music System Key");
+ if (key) {
+ setVisible(true);
+ playMovie(MOVIE_NOTIFY_OBJECT);
+ }
+
+ return true;
+}
+
+bool CMusicSystemLock::MovieEndMsg(CMovieEndMsg *msg) {
+ CTreeItem *phonograph = findRoom()->findByName("Restaurant Phonograph");
+ CQueryPhonographState queryMsg;
+ queryMsg.execute(phonograph);
+ CLockPhonographMsg lockMsg(queryMsg._value);
+ lockMsg.execute(phonograph, nullptr, MSGFLAG_SCAN);
+
+ setVisible(false);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/music_system_lock.h b/engines/titanic/game/music_system_lock.h
index ff826f5c77..0947915caa 100644
--- a/engines/titanic/game/music_system_lock.h
+++ b/engines/titanic/game/music_system_lock.h
@@ -28,6 +28,9 @@
namespace Titanic {
class CMusicSystemLock : public CDropTarget {
+ DECLARE_MESSAGE_MAP;
+ bool DropObjectMsg(CDropObjectMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
private:
int _value;
public:
diff --git a/engines/titanic/game/nav_helmet.cpp b/engines/titanic/game/nav_helmet.cpp
index 770eb7375e..08ff073c26 100644
--- a/engines/titanic/game/nav_helmet.cpp
+++ b/engines/titanic/game/nav_helmet.cpp
@@ -21,19 +21,114 @@
*/
#include "titanic/game/nav_helmet.h"
+#include "titanic/pet_control/pet_control.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CNavHelmet, CGameObject)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(LeaveViewMsg)
+ ON_MESSAGE(PETHelmetOnOffMsg)
+ ON_MESSAGE(PETPhotoOnOffMsg)
+ ON_MESSAGE(PETStarFieldLockMsg)
+ ON_MESSAGE(PETSetStarDestinationMsg)
+END_MESSAGE_MAP()
+
void CNavHelmet::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_value, indent);
+ file->writeNumberLine(_flag, indent);
CGameObject::save(file, indent);
}
void CNavHelmet::load(SimpleFile *file) {
file->readNumber();
- _value = file->readNumber();
+ _flag = file->readNumber();
CGameObject::load(file);
}
+bool CNavHelmet::MovieEndMsg(CMovieEndMsg *msg) {
+ if (_flag) {
+ setVisible(false);
+
+ CPetControl *pet = getPetControl();
+ if (pet) {
+ pet->setArea(PET_STARFIELD);
+ petDisplayMessage(1, "Now would be an excellent opportunity to adjust your viewing apparatus.");
+ pet->incAreaLocks();
+ }
+
+ starFn1(0);
+ starFn1(12);
+ }
+
+ return true;
+}
+
+bool CNavHelmet::EnterViewMsg(CEnterViewMsg *msg) {
+ petSetRemoteTarget();
+ return true;
+}
+
+bool CNavHelmet::LeaveViewMsg(CLeaveViewMsg *msg) {
+ petClear();
+ return true;
+}
+
+bool CNavHelmet::PETHelmetOnOffMsg(CPETHelmetOnOffMsg *msg) {
+ CPetControl *pet = getPetControl();
+
+ if (_flag) {
+ _flag = false;
+ setVisible(true);
+ starFn1(1);
+ playMovie(61, 120, MOVIE_NOTIFY_OBJECT);
+ playSound("a#47.wav");
+ playSound("a#48.wav");
+
+ if (pet) {
+ pet->decAreaLocks();
+ pet->setArea(PET_REMOTE);
+ }
+
+ dec54();
+ } else {
+ inc54();
+ _flag = true;
+ setVisible(true);
+ playMovie(0, 60, MOVIE_NOTIFY_OBJECT);
+ playSound("a#48.wav");
+ playSound("a#47.wav");
+ }
+
+ return true;
+}
+
+bool CNavHelmet::PETPhotoOnOffMsg(CPETPhotoOnOffMsg *msg) {
+ if (_flag)
+ starFn1(9);
+
+ return true;
+}
+
+bool CNavHelmet::PETStarFieldLockMsg(CPETStarFieldLockMsg *msg) {
+ if (_flag) {
+ if (msg->_value) {
+ playSound("a#6.wav");
+ starFn1(17);
+ } else {
+ playSound("a#5.wav");
+ starFn1(18);
+ }
+ }
+
+ return true;
+}
+
+bool CNavHelmet::PETSetStarDestinationMsg(CPETSetStarDestinationMsg *msg) {
+ CActMsg actMsg("SetDestin");
+ actMsg.execute("CaptainsWheel");
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/nav_helmet.h b/engines/titanic/game/nav_helmet.h
index 74caa52534..c408d05c97 100644
--- a/engines/titanic/game/nav_helmet.h
+++ b/engines/titanic/game/nav_helmet.h
@@ -24,15 +24,24 @@
#define TITANIC_NAV_HELMET_H
#include "titanic/core/game_object.h"
+#include "titanic/messages/pet_messages.h"
namespace Titanic {
class CNavHelmet : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
+ bool PETHelmetOnOffMsg(CPETHelmetOnOffMsg *msg);
+ bool PETPhotoOnOffMsg(CPETPhotoOnOffMsg *msg);
+ bool PETStarFieldLockMsg(CPETStarFieldLockMsg *msg);
+ bool PETSetStarDestinationMsg(CPETSetStarDestinationMsg *msg);
private:
- int _value;
+ bool _flag;
public:
CLASSDEF;
- CNavHelmet() : CGameObject(), _value(0) {}
+ CNavHelmet() : CGameObject(), _flag(false) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/nav_helmet_off.cpp b/engines/titanic/game/nav_helmet_off.cpp
new file mode 100644
index 0000000000..289e9e3f55
--- /dev/null
+++ b/engines/titanic/game/nav_helmet_off.cpp
@@ -0,0 +1,49 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "titanic/game/nav_helmet_off.h"
+#include "titanic/pet_control/pet_control.h"
+#include "titanic/messages/pet_messages.h"
+
+namespace Titanic {
+
+BEGIN_MESSAGE_MAP(CNavHelmetOff, CNavHelmet)
+ ON_MESSAGE(MouseButtonUpMsg)
+END_MESSAGE_MAP()
+
+void CNavHelmetOff::save(SimpleFile *file, int indent) {
+ file->writeNumberLine(1, indent);
+ file->writeQuotedLine(_target, indent);
+}
+
+void CNavHelmetOff::load(SimpleFile *file) {
+ file->readNumber();
+ _target = file->readString();
+}
+
+bool CNavHelmetOff::MouseButtonUpMsg(CMouseButtonUpMsg *msg) {
+ CDoffNavHelmet doffMsg;
+ doffMsg.execute(_target);
+ return true;
+}
+
+} // End of namespace Titanic
diff --git a/engines/titanic/gfx/chev_switch.h b/engines/titanic/game/nav_helmet_off.h
index 01da53c854..c9529fe8e9 100644
--- a/engines/titanic/gfx/chev_switch.h
+++ b/engines/titanic/game/nav_helmet_off.h
@@ -20,23 +20,22 @@
*
*/
-#ifndef TITANIC_CHEV_SWITCH_H
-#define TITANIC_CHEV_SWITCH_H
+#ifndef TITANIC_NAV_HELMET_OFF_H
+#define TITANIC_NAV_HELMET_OFF_H
-#include "titanic/gfx/toggle_switch.h"
+#include "titanic/game/nav_helmet.h"
+#include "titanic/messages/pet_messages.h"
namespace Titanic {
-class CChevSwitch : public CToggleSwitch {
+class CNavHelmetOff : public CNavHelmet {
DECLARE_MESSAGE_MAP;
bool MouseButtonUpMsg(CMouseButtonUpMsg *msg);
- bool SetChevButtonImageMsg(CSetChevButtonImageMsg *msg);
- bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
-public:
- int _value;
+private:
+ CString _target;
public:
CLASSDEF;
- CChevSwitch();
+ CNavHelmetOff() : CNavHelmet(), _target("NULL") {}
/**
* Save the data for the class to file
@@ -51,4 +50,4 @@ public:
} // End of namespace Titanic
-#endif /* TITANIC_CHEV_SWITCH_H */
+#endif /* TITANIC_NAV_HELMET_OFF_H */
diff --git a/engines/titanic/game/nav_helmet_on.cpp b/engines/titanic/game/nav_helmet_on.cpp
new file mode 100644
index 0000000000..59ceebc4ad
--- /dev/null
+++ b/engines/titanic/game/nav_helmet_on.cpp
@@ -0,0 +1,49 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "titanic/game/nav_helmet_on.h"
+#include "titanic/pet_control/pet_control.h"
+#include "titanic/messages/pet_messages.h"
+
+namespace Titanic {
+
+BEGIN_MESSAGE_MAP(CNavHelmetOn, CNavHelmet)
+ ON_MESSAGE(MouseButtonUpMsg)
+END_MESSAGE_MAP()
+
+void CNavHelmetOn::save(SimpleFile *file, int indent) {
+ file->writeNumberLine(1, indent);
+ file->writeQuotedLine(_target, indent);
+}
+
+void CNavHelmetOn::load(SimpleFile *file) {
+ file->readNumber();
+ _target = file->readString();
+}
+
+bool CNavHelmetOn::MouseButtonUpMsg(CMouseButtonUpMsg *msg) {
+ CDonNavHelmet donMsg;
+ donMsg.execute(_target);
+ return true;
+}
+
+} // End of namespace Titanic
diff --git a/engines/adl/hires0.h b/engines/titanic/game/nav_helmet_on.h
index 624f248ea8..452637c48a 100644
--- a/engines/adl/hires0.h
+++ b/engines/titanic/game/nav_helmet_on.h
@@ -1,59 +1,53 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ADL_HIRES0_H
-#define ADL_HIRES0_H
-
-#include "adl/adl_v2.h"
-
-namespace Adl {
-
-#define IDS_HR0_DISK_IMAGE "MISSION.NIB"
-
-#define IDI_HR0_NUM_ROOMS 43
-#define IDI_HR0_NUM_MESSAGES 142
-#define IDI_HR0_NUM_VARS 40
-#define IDI_HR0_NUM_ITEM_PICS 2
-#define IDI_HR0_NUM_ITEM_OFFSETS 16
-
-// Messages used outside of scripts
-#define IDI_HR0_MSG_CANT_GO_THERE 110
-#define IDI_HR0_MSG_DONT_UNDERSTAND 112
-#define IDI_HR0_MSG_ITEM_DOESNT_MOVE 114
-#define IDI_HR0_MSG_ITEM_NOT_HERE 115
-#define IDI_HR0_MSG_THANKS_FOR_PLAYING 113
-
-class HiRes0Engine : public AdlEngine_v2 {
-public:
- HiRes0Engine(OSystem *syst, const AdlGameDescription *gd) :
- AdlEngine_v2(syst, gd) { }
- ~HiRes0Engine() { }
-
-private:
- // AdlEngine
- void init();
- void initGameState();
-};
-
-} // End of namespace Adl
-
-#endif
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TITANIC_NAV_HELMET_ON_H
+#define TITANIC_NAV_HELMET_ON_H
+
+#include "titanic/game/nav_helmet.h"
+#include "titanic/messages/pet_messages.h"
+
+namespace Titanic {
+
+class CNavHelmetOn : public CNavHelmet {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonUpMsg(CMouseButtonUpMsg *msg);
+private:
+ CString _target;
+public:
+ CLASSDEF;
+ CNavHelmetOn() : CNavHelmet(), _target("NULL") {}
+
+ /**
+ * Save the data for the class to file
+ */
+ virtual void save(SimpleFile *file, int indent);
+
+ /**
+ * Load the data for the class from file
+ */
+ virtual void load(SimpleFile *file);
+};
+
+} // End of namespace Titanic
+
+#endif /* TITANIC_NAV_HELMET_ON_H */
diff --git a/engines/titanic/game/no_nut_bowl.cpp b/engines/titanic/game/no_nut_bowl.cpp
index 47f9d7901e..8c0a95ac9a 100644
--- a/engines/titanic/game/no_nut_bowl.cpp
+++ b/engines/titanic/game/no_nut_bowl.cpp
@@ -24,6 +24,12 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CNoNutBowl, CBackground)
+ ON_MESSAGE(ActMsg)
+ ON_MESSAGE(ReplaceBowlAndNutsMsg)
+ ON_MESSAGE(NutPuzzleMsg)
+END_MESSAGE_MAP()
+
void CNoNutBowl::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CBackground::save(file, indent);
@@ -34,4 +40,19 @@ void CNoNutBowl::load(SimpleFile *file) {
CBackground::load(file);
}
+bool CNoNutBowl::ActMsg(CActMsg *msg) {
+ return true;
+}
+
+bool CNoNutBowl::ReplaceBowlAndNutsMsg(CReplaceBowlAndNutsMsg *msg) {
+ setVisible(false);
+ return true;
+}
+
+bool CNoNutBowl::NutPuzzleMsg(CNutPuzzleMsg *msg) {
+ if (msg->_value == "NutsGone")
+ setVisible(true);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/no_nut_bowl.h b/engines/titanic/game/no_nut_bowl.h
index 548b324869..cd8bc65179 100644
--- a/engines/titanic/game/no_nut_bowl.h
+++ b/engines/titanic/game/no_nut_bowl.h
@@ -28,6 +28,10 @@
namespace Titanic {
class CNoNutBowl : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool ActMsg(CActMsg *msg);
+ bool ReplaceBowlAndNutsMsg(CReplaceBowlAndNutsMsg *msg);
+ bool NutPuzzleMsg(CNutPuzzleMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/nose_holder.cpp b/engines/titanic/game/nose_holder.cpp
index cd9433ee9c..ac6c10dafd 100644
--- a/engines/titanic/game/nose_holder.cpp
+++ b/engines/titanic/game/nose_holder.cpp
@@ -24,7 +24,16 @@
namespace Titanic {
-CNoseHolder::CNoseHolder() : CDropTarget(), _field118(0), _field11C(0) {
+BEGIN_MESSAGE_MAP(CNoseHolder, CDropTarget)
+ ON_MESSAGE(ActMsg)
+ ON_MESSAGE(FrameMsg)
+ ON_MESSAGE(LeaveViewMsg)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(EnterViewMsg)
+END_MESSAGE_MAP()
+
+CNoseHolder::CNoseHolder() : CDropTarget(), _dragObject(nullptr),
+ _field11C(0) {
}
void CNoseHolder::save(SimpleFile *file, int indent) {
@@ -41,4 +50,72 @@ void CNoseHolder::load(SimpleFile *file) {
CDropTarget::load(file);
}
+bool CNoseHolder::ActMsg(CActMsg *msg) {
+ if (msg->_action == "Sneeze" && !_itemName.empty() && _fieldF4) {
+ CProximity prox;
+ prox._positioningMode = POSMODE_VECTOR;
+ playSound("z#35.wav", prox);
+
+ if (getView() == findView()) {
+ setVisible(true);
+ playMovie(1, 13, MOVIE_NOTIFY_OBJECT);
+ }
+ }
+
+ return true;
+}
+
+bool CNoseHolder::FrameMsg(CFrameMsg *msg) {
+ if (!_dragObject) {
+ CGameObject *dragObj = getDraggingObject();
+ if (!dragObj)
+ return false;
+
+ if (!dragObj->isEquals("Feathers") || getView() != findView())
+ return false;
+
+ _dragObject = dragObj;
+ }
+
+ if (_dragObject) {
+ if (!checkPoint(Point(_dragObject->_bounds.left,
+ _dragObject->_bounds.top))) {
+ _field11C = false;
+ } else if (!_field11C) {
+ CActMsg actMsg("Sneeze");
+ actMsg.execute(this);
+ _field11C = true;
+ }
+ }
+
+ return true;
+}
+
+bool CNoseHolder::LeaveViewMsg(CLeaveViewMsg *msg) {
+ _field11C = false;
+ _dragObject = nullptr;
+ if (_fieldF4) {
+ loadFrame(_dropFrame);
+ setVisible(false);
+ }
+
+ return true;
+}
+
+bool CNoseHolder::MovieEndMsg(CMovieEndMsg *msg) {
+ if (_fieldF4) {
+ loadFrame(_dropFrame);
+ setVisible(false);
+ }
+
+ return true;
+}
+
+bool CNoseHolder::EnterViewMsg(CEnterViewMsg *msg) {
+ if (_fieldF4)
+ setVisible(false);
+
+ return CDropTarget::EnterViewMsg(msg);
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/nose_holder.h b/engines/titanic/game/nose_holder.h
index b8cca95869..7b3fbba625 100644
--- a/engines/titanic/game/nose_holder.h
+++ b/engines/titanic/game/nose_holder.h
@@ -28,8 +28,14 @@
namespace Titanic {
class CNoseHolder : public CDropTarget {
+ DECLARE_MESSAGE_MAP;
+ bool ActMsg(CActMsg *msg);
+ bool FrameMsg(CFrameMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
private:
- int _field118;
+ CGameObject *_dragObject;
int _field11C;
public:
CLASSDEF;
diff --git a/engines/titanic/game/nut_replacer.cpp b/engines/titanic/game/nut_replacer.cpp
index 9a73355c91..6b05d1d0e9 100644
--- a/engines/titanic/game/nut_replacer.cpp
+++ b/engines/titanic/game/nut_replacer.cpp
@@ -24,6 +24,11 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CNutReplacer, CGameObject)
+ ON_MESSAGE(ReplaceBowlAndNutsMsg)
+ ON_MESSAGE(MovieEndMsg)
+END_MESSAGE_MAP()
+
void CNutReplacer::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CGameObject::save(file, indent);
@@ -34,4 +39,15 @@ void CNutReplacer::load(SimpleFile *file) {
CGameObject::load(file);
}
+bool CNutReplacer::ReplaceBowlAndNutsMsg(CReplaceBowlAndNutsMsg *msg) {
+ setVisible(true);
+ playMovie(MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
+ return true;
+}
+
+bool CNutReplacer::MovieEndMsg(CMovieEndMsg *msg) {
+ setVisible(false);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/nut_replacer.h b/engines/titanic/game/nut_replacer.h
index ead9713801..e2eed4e247 100644
--- a/engines/titanic/game/nut_replacer.h
+++ b/engines/titanic/game/nut_replacer.h
@@ -28,6 +28,9 @@
namespace Titanic {
class CNutReplacer : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool ReplaceBowlAndNutsMsg(CReplaceBowlAndNutsMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/parrot/parrot_lobby_controller.cpp b/engines/titanic/game/parrot/parrot_lobby_controller.cpp
index f1e054a8dd..907e7519b8 100644
--- a/engines/titanic/game/parrot/parrot_lobby_controller.cpp
+++ b/engines/titanic/game/parrot/parrot_lobby_controller.cpp
@@ -21,9 +21,14 @@
*/
#include "titanic/game/parrot/parrot_lobby_controller.h"
+#include "titanic/core/room_item.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CParrotLobbyController, CParrotLobbyObject)
+ ON_MESSAGE(ActMsg)
+END_MESSAGE_MAP()
+
void CParrotLobbyController::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CParrotLobbyObject::save(file, indent);
@@ -34,4 +39,34 @@ void CParrotLobbyController::load(SimpleFile *file) {
CParrotLobbyObject::load(file);
}
+bool CParrotLobbyController::ActMsg(CActMsg *msg) {
+ if (msg->_action == "Refresh")
+ return false;
+ else if (msg->_action == "GainParrot")
+ _haveParrot = true;
+ else if (msg->_action == "LoseParrot")
+ _haveParrot = false;
+ else if (msg->_action == "GainPerch")
+ _havePerch = true;
+ else if (msg->_action == "LosePerch")
+ _havePerch = false;
+ else if (msg->_action == "GainStick")
+ _haveStick = true;
+ else if (msg->_action == "LoseStick")
+ _haveStick = false;
+
+ _flags = 0;
+ if (_haveParrot)
+ _flags = 4;
+ if (_havePerch)
+ _flags |= 2;
+ if (_haveStick)
+ _flags |= 1;
+
+ CActMsg actMsg("Refresh");
+ actMsg.execute(findRoom(), CParrotLobbyObject::_type, MSGFLAG_CLASS_DEF | MSGFLAG_SCAN);
+ actMsg.execute("ParrotLobbyUpdater_TOW");
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/parrot/parrot_lobby_controller.h b/engines/titanic/game/parrot/parrot_lobby_controller.h
index d2fa4a1801..896a4e19d2 100644
--- a/engines/titanic/game/parrot/parrot_lobby_controller.h
+++ b/engines/titanic/game/parrot/parrot_lobby_controller.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CParrotLobbyController : public CParrotLobbyObject {
+ DECLARE_MESSAGE_MAP;
+ bool ActMsg(CActMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/parrot/parrot_lobby_link_updater.cpp b/engines/titanic/game/parrot/parrot_lobby_link_updater.cpp
index 25d5ec724b..47311c31f5 100644
--- a/engines/titanic/game/parrot/parrot_lobby_link_updater.cpp
+++ b/engines/titanic/game/parrot/parrot_lobby_link_updater.cpp
@@ -21,9 +21,46 @@
*/
#include "titanic/game/parrot/parrot_lobby_link_updater.h"
+#include "titanic/titanic.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CParrotLobbyLinkUpdater, CParrotLobbyObject)
+ ON_MESSAGE(ActMsg)
+END_MESSAGE_MAP()
+
+/*------------------------------------------------------------------------*/
+
+LinkUpdatorEntry::LinkUpdatorEntry() {
+ Common::fill(&_vals[0], &_vals[8], 0);
+}
+
+void LinkUpdatorEntry::load(Common::SeekableReadStream *s) {
+ _linkStr = readStringFromStream(s);
+ for (int idx = 0; idx < 8; ++idx)
+ _vals[idx] = s->readByte();
+}
+
+/*------------------------------------------------------------------------*/
+
+void LinkUpdatorEntries::load(Common::SeekableReadStream *s, int count) {
+ resize(count);
+ for (int idx = 0; idx < count; ++idx)
+ (*this)[idx].load(s);
+}
+
+/*------------------------------------------------------------------------*/
+
+CParrotLobbyLinkUpdater::CParrotLobbyLinkUpdater() : CParrotLobbyObject(), _fieldBC(1) {
+ Common::SeekableReadStream *s = g_vm->_filesManager->getResource("DATA/PARROT_LOBBY_LINK_UPDATOR");
+ _entries[0].load(s, 7);
+ _entries[1].load(s, 5);
+ _entries[2].load(s, 6);
+ _entries[3].load(s, 9);
+ _entries[4].load(s, 1);
+ delete s;
+}
+
void CParrotLobbyLinkUpdater::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CParrotLobbyObject::save(file, indent);
@@ -34,4 +71,45 @@ void CParrotLobbyLinkUpdater::load(SimpleFile *file) {
CParrotLobbyObject::load(file);
}
+bool CParrotLobbyLinkUpdater::ActMsg(CActMsg *msg) {
+ if (msg->_action != "Refresh")
+ return false;
+
+ CNodeItem *node = findNode();
+ LinkUpdatorEntries *entriesP;
+ if (isEquals("ParrotLobbyUpdater_TOW")) {
+ entriesP = &_entries[4];
+ } else {
+ if (node->_nodeNumber > 3)
+ return true;
+ entriesP = &_entries[node->_nodeNumber];
+ }
+ int count = entriesP->size();
+
+ for (CTreeItem *item = node->getFirstChild(); item; item = item->scan(node)) {
+ CLinkItem *link = dynamic_cast<CLinkItem *>(item);
+ if (!link || count == 0)
+ continue;
+
+ CString linkName = link->getName();
+ char c = linkName.lastChar();
+ if (c >= 'a' && c <= 'd')
+ linkName.deleteLastChar();
+
+ for (uint idx = 0; idx < entriesP->size(); ++idx) {
+ const LinkUpdatorEntry &entry = (*entriesP)[idx];
+ if (entry._linkStr == linkName) {
+ int val = entry._vals[CParrotLobbyObject::_flags];
+ if (val)
+ linkName += (char)(0x60 + val);
+
+ link->_name = linkName;
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/parrot/parrot_lobby_link_updater.h b/engines/titanic/game/parrot/parrot_lobby_link_updater.h
index 0470a62dee..93db931a53 100644
--- a/engines/titanic/game/parrot/parrot_lobby_link_updater.h
+++ b/engines/titanic/game/parrot/parrot_lobby_link_updater.h
@@ -23,16 +23,34 @@
#ifndef TITANIC_PARROT_LOBBY_LINK_UPDATER_H
#define TITANIC_PARROT_LOBBY_LINK_UPDATER_H
+#include "common/stream.h"
#include "titanic/game/parrot/parrot_lobby_object.h"
namespace Titanic {
+struct LinkUpdatorEntry {
+ CString _linkStr;
+ int _vals[8];
+
+ LinkUpdatorEntry();
+ void load(Common::SeekableReadStream *s);
+};
+
+class LinkUpdatorEntries : public Common::Array<LinkUpdatorEntry> {
+public:
+ void load(Common::SeekableReadStream *s, int count);
+};
+
class CParrotLobbyLinkUpdater : public CParrotLobbyObject {
+ DECLARE_MESSAGE_MAP;
+ bool ActMsg(CActMsg *msg);
+private:
+ LinkUpdatorEntries _entries[5];
public:
int _fieldBC;
public:
CLASSDEF;
- CParrotLobbyLinkUpdater() : CParrotLobbyObject(), _fieldBC(1) {}
+ CParrotLobbyLinkUpdater();
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/parrot/parrot_lobby_object.cpp b/engines/titanic/game/parrot/parrot_lobby_object.cpp
index a78ab2b6d9..06222fd063 100644
--- a/engines/titanic/game/parrot/parrot_lobby_object.cpp
+++ b/engines/titanic/game/parrot/parrot_lobby_object.cpp
@@ -26,34 +26,34 @@ namespace Titanic {
EMPTY_MESSAGE_MAP(CParrotLobbyObject, CGameObject);
-int CParrotLobbyObject::_v1;
-int CParrotLobbyObject::_v2;
-int CParrotLobbyObject::_v3;
-int CParrotLobbyObject::_v4;
+bool CParrotLobbyObject::_haveParrot;
+bool CParrotLobbyObject::_havePerch;
+bool CParrotLobbyObject::_haveStick;
+int CParrotLobbyObject::_flags;
void CParrotLobbyObject::init() {
- _v1 = 1;
- _v2 = 1;
- _v3 = 1;
- _v4 = 7;
+ _haveParrot = true;
+ _havePerch = true;
+ _haveStick = true;
+ _flags = 7;
}
void CParrotLobbyObject::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_v1, indent);
- file->writeNumberLine(_v2, indent);
- file->writeNumberLine(_v3, indent);
- file->writeNumberLine(_v4, indent);
+ file->writeNumberLine(_haveParrot, indent);
+ file->writeNumberLine(_havePerch, indent);
+ file->writeNumberLine(_haveStick, indent);
+ file->writeNumberLine(_flags, indent);
CGameObject::save(file, indent);
}
void CParrotLobbyObject::load(SimpleFile *file) {
file->readNumber();
- _v1 = file->readNumber();
- _v2 = file->readNumber();
- _v3 = file->readNumber();
- _v4 = file->readNumber();
+ _haveParrot = file->readNumber();
+ _havePerch = file->readNumber();
+ _haveStick = file->readNumber();
+ _flags = file->readNumber();
CGameObject::load(file);
}
diff --git a/engines/titanic/game/parrot/parrot_lobby_object.h b/engines/titanic/game/parrot/parrot_lobby_object.h
index 5272303888..a210331399 100644
--- a/engines/titanic/game/parrot/parrot_lobby_object.h
+++ b/engines/titanic/game/parrot/parrot_lobby_object.h
@@ -30,10 +30,10 @@ namespace Titanic {
class CParrotLobbyObject : public CGameObject {
DECLARE_MESSAGE_MAP;
public:
- static int _v1;
- static int _v2;
- static int _v3;
- static int _v4;
+ static bool _haveParrot;
+ static bool _havePerch;
+ static bool _haveStick;
+ static int _flags;
static void init();
public:
diff --git a/engines/titanic/game/parrot/parrot_lobby_view_object.cpp b/engines/titanic/game/parrot/parrot_lobby_view_object.cpp
index ae398036a8..1151325676 100644
--- a/engines/titanic/game/parrot/parrot_lobby_view_object.cpp
+++ b/engines/titanic/game/parrot/parrot_lobby_view_object.cpp
@@ -24,16 +24,28 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CParrotLobbyViewObject, CParrotLobbyObject)
+ ON_MESSAGE(ActMsg)
+END_MESSAGE_MAP()
+
void CParrotLobbyViewObject::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldBC, indent);
+ file->writeNumberLine(_flag, indent);
CParrotLobbyObject::save(file, indent);
}
void CParrotLobbyViewObject::load(SimpleFile *file) {
file->readNumber();
- _fieldBC = file->readNumber();
+ _flag = file->readNumber();
CParrotLobbyObject::load(file);
}
+bool CParrotLobbyViewObject::ActMsg(CActMsg *msg) {
+ if (msg->_action != "Refresh")
+ return false;
+
+ setVisible(_flag ? _haveParrot : _haveStick);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/parrot/parrot_lobby_view_object.h b/engines/titanic/game/parrot/parrot_lobby_view_object.h
index 3179bb962d..484d70908e 100644
--- a/engines/titanic/game/parrot/parrot_lobby_view_object.h
+++ b/engines/titanic/game/parrot/parrot_lobby_view_object.h
@@ -28,11 +28,13 @@
namespace Titanic {
class CParrotLobbyViewObject : public CParrotLobbyObject {
+ DECLARE_MESSAGE_MAP;
+ bool ActMsg(CActMsg *msg);
public:
- int _fieldBC;
+ bool _flag;
public:
CLASSDEF;
- CParrotLobbyViewObject() : CParrotLobbyObject(), _fieldBC(1) {}
+ CParrotLobbyViewObject() : CParrotLobbyObject(), _flag(true) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/parrot/parrot_loser.cpp b/engines/titanic/game/parrot/parrot_loser.cpp
index 6e23ef8314..dc854ee9bd 100644
--- a/engines/titanic/game/parrot/parrot_loser.cpp
+++ b/engines/titanic/game/parrot/parrot_loser.cpp
@@ -24,6 +24,10 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CParrotLoser, CGameObject)
+ ON_MESSAGE(LeaveRoomMsg)
+END_MESSAGE_MAP()
+
void CParrotLoser::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CGameObject::save(file, indent);
@@ -34,4 +38,10 @@ void CParrotLoser::load(SimpleFile *file) {
CGameObject::load(file);
}
+bool CParrotLoser::LeaveRoomMsg(CLeaveRoomMsg *msg) {
+ CActMsg actMsg("FreeParrot");
+ actMsg.execute("CarryParrot");
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/parrot/parrot_loser.h b/engines/titanic/game/parrot/parrot_loser.h
index 819fd6614c..e03bfb0727 100644
--- a/engines/titanic/game/parrot/parrot_loser.h
+++ b/engines/titanic/game/parrot/parrot_loser.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CParrotLoser : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool LeaveRoomMsg(CLeaveRoomMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/parrot/parrot_nut_bowl_actor.cpp b/engines/titanic/game/parrot/parrot_nut_bowl_actor.cpp
index c83d66cbdf..9dfc866c0e 100644
--- a/engines/titanic/game/parrot/parrot_nut_bowl_actor.cpp
+++ b/engines/titanic/game/parrot/parrot_nut_bowl_actor.cpp
@@ -21,27 +21,95 @@
*/
#include "titanic/game/parrot/parrot_nut_bowl_actor.h"
+#include "titanic/core/room_item.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CParrotNutBowlActor, CGameObject)
+ ON_MESSAGE(MouseButtonUpMsg)
+ ON_MESSAGE(BowlStateChangeMsg)
+ ON_MESSAGE(IsEarBowlPuzzleDone)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(ReplaceBowlAndNutsMsg)
+ ON_MESSAGE(LeaveViewMsg)
+ ON_MESSAGE(NutPuzzleMsg)
+END_MESSAGE_MAP()
+
CParrotNutBowlActor::CParrotNutBowlActor() : CGameObject(),
- _value1(0), _value2(0) {
+ _puzzleDone(0), _state(0) {
}
void CParrotNutBowlActor::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_value1, indent);
- file->writeNumberLine(_value2, indent);
+ file->writeNumberLine(_puzzleDone, indent);
+ file->writeNumberLine(_state, indent);
CGameObject::save(file, indent);
}
void CParrotNutBowlActor::load(SimpleFile *file) {
file->readNumber();
- _value1 = file->readNumber();
- _value2 = file->readNumber();
+ _puzzleDone = file->readNumber();
+ _state = file->readNumber();
CGameObject::load(file);
}
+bool CParrotNutBowlActor::MouseButtonUpMsg(CMouseButtonUpMsg *msg) {
+ if (!_state) {
+ CActMsg actMsg("Jiggle");
+ actMsg.execute("BowlNutsRustler");
+ }
+
+ return true;
+}
+
+bool CParrotNutBowlActor::BowlStateChangeMsg(CBowlStateChangeMsg *msg) {
+ _state = msg->_state;
+ if (msg->_state == 3) {
+ if (!_puzzleDone) {
+ CReplaceBowlAndNutsMsg replaceMsg;
+ replaceMsg.execute(findRoom(), nullptr, MSGFLAG_SCAN);
+ playSound("z#47.wav");
+ }
+
+ _puzzleDone = true;
+ }
+
+ return true;
+}
+
+bool CParrotNutBowlActor::CParrotNutBowlActor::IsEarBowlPuzzleDone(CIsEarBowlPuzzleDone *msg) {
+ msg->_value = _puzzleDone;
+ return true;
+}
+
+bool CParrotNutBowlActor::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ return true;
+}
+
+bool CParrotNutBowlActor::ReplaceBowlAndNutsMsg(CReplaceBowlAndNutsMsg *msg) {
+ if (!_puzzleDone)
+ _state = 0;
+ return true;
+}
+
+bool CParrotNutBowlActor::LeaveViewMsg(CLeaveViewMsg *msg) {
+ if (!_puzzleDone && _state) {
+ CReplaceBowlAndNutsMsg replaceMsg;
+ replaceMsg.execute(findRoom(), nullptr, MSGFLAG_SCAN);
+ }
+
+ return true;
+}
+
+bool CParrotNutBowlActor::NutPuzzleMsg(CNutPuzzleMsg *msg) {
+ if (msg->_value == "NutsGone")
+ _state = 1;
+ else if (msg->_value == "BowlUnlocked")
+ _state = 2;
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/parrot/parrot_nut_bowl_actor.h b/engines/titanic/game/parrot/parrot_nut_bowl_actor.h
index d8395bb65a..b228c0ea9e 100644
--- a/engines/titanic/game/parrot/parrot_nut_bowl_actor.h
+++ b/engines/titanic/game/parrot/parrot_nut_bowl_actor.h
@@ -28,8 +28,17 @@
namespace Titanic {
class CParrotNutBowlActor : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonUpMsg(CMouseButtonUpMsg *msg);
+ bool BowlStateChangeMsg(CBowlStateChangeMsg *msg);
+ bool IsEarBowlPuzzleDone(CIsEarBowlPuzzleDone *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool ReplaceBowlAndNutsMsg(CReplaceBowlAndNutsMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
+ bool NutPuzzleMsg(CNutPuzzleMsg *msg);
public:
- int _value1, _value2;
+ bool _puzzleDone;
+ int _state;
public:
CLASSDEF;
CParrotNutBowlActor();
diff --git a/engines/titanic/game/parrot/parrot_nut_eater.cpp b/engines/titanic/game/parrot/parrot_nut_eater.cpp
index 309b379ab8..751da931ac 100644
--- a/engines/titanic/game/parrot/parrot_nut_eater.cpp
+++ b/engines/titanic/game/parrot/parrot_nut_eater.cpp
@@ -21,9 +21,17 @@
*/
#include "titanic/game/parrot/parrot_nut_eater.h"
+#include "titanic/core/room_item.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CParrotNutEater, CGameObject)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(ReplaceBowlAndNutsMsg)
+ ON_MESSAGE(NutPuzzleMsg)
+ ON_MESSAGE(MovieFrameMsg)
+END_MESSAGE_MAP()
+
CParrotNutEater::CParrotNutEater() : CGameObject(), _fieldBC(0),
_fieldC0(69), _fieldC4(132), _fieldC8(0), _fieldCC(68) {
}
@@ -42,4 +50,48 @@ void CParrotNutEater::load(SimpleFile *file) {
CGameObject::load(file);
}
+bool CParrotNutEater::MovieEndMsg(CMovieEndMsg *msg) {
+ setVisible(false);
+ CNutPuzzleMsg nutMsg("NutsGone");
+ nutMsg.execute(getRoom(), nullptr, MSGFLAG_SCAN);
+
+ playSound("z#47.wav");
+ return true;
+}
+
+bool CParrotNutEater::ReplaceBowlAndNutsMsg(CReplaceBowlAndNutsMsg *msg) {
+ setVisible(false);
+ return true;
+}
+
+bool CParrotNutEater::NutPuzzleMsg(CNutPuzzleMsg *msg) {
+ if (msg->_value == "Jiggle") {
+ playMovie(MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ movieEvent(68);
+ movieEvent(132);
+ playSound("z#215.wav");
+
+ CTrueTalkTriggerActionMsg triggerMsg;
+ triggerMsg._param1 = triggerMsg._param2 = 0;
+ triggerMsg.execute("PerchedParrot");
+ }
+
+ return true;
+}
+
+bool CParrotNutEater::MovieFrameMsg(CMovieFrameMsg *msg) {
+ switch (msg->_frameNumber) {
+ case 68:
+ playSound("z#214.wav");
+ break;
+ case 132:
+ playSound("z#216.wav");
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/parrot/parrot_nut_eater.h b/engines/titanic/game/parrot/parrot_nut_eater.h
index 5dcb01ca11..e09ad63947 100644
--- a/engines/titanic/game/parrot/parrot_nut_eater.h
+++ b/engines/titanic/game/parrot/parrot_nut_eater.h
@@ -28,6 +28,11 @@
namespace Titanic {
class CParrotNutEater : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool ReplaceBowlAndNutsMsg(CReplaceBowlAndNutsMsg *msg);
+ bool NutPuzzleMsg(CNutPuzzleMsg *msg);
+ bool MovieFrameMsg(CMovieFrameMsg *msg);
public:
int _fieldBC;
int _fieldC0;
diff --git a/engines/titanic/game/parrot/parrot_perch_holder.cpp b/engines/titanic/game/parrot/parrot_perch_holder.cpp
index dd8523990b..d594446219 100644
--- a/engines/titanic/game/parrot/parrot_perch_holder.cpp
+++ b/engines/titanic/game/parrot/parrot_perch_holder.cpp
@@ -21,9 +21,19 @@
*/
#include "titanic/game/parrot/parrot_perch_holder.h"
+#include "titanic/game/cage.h"
+#include "titanic/core/project_item.h"
+#include "titanic/npcs/parrot.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CParrotPerchHolder, CMultiDropTarget)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(StatusChangeMsg)
+ ON_MESSAGE(DropObjectMsg)
+ ON_MESSAGE(ActMsg)
+END_MESSAGE_MAP()
+
void CParrotPerchHolder::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CMultiDropTarget::save(file, indent);
@@ -34,4 +44,39 @@ void CParrotPerchHolder::load(SimpleFile *file) {
CMultiDropTarget::load(file);
}
+bool CParrotPerchHolder::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (CParrot::_v1) {
+ if (CCage::_open) {
+ petDisplayMessage("You cannot take this because the cage is locked shut.");
+ } else if (!CParrot::_v4) {
+ CTrueTalkTriggerActionMsg triggerMsg(280252, 0, 0);
+ triggerMsg.execute(getRoot(), CParrot::_type,
+ MSGFLAG_CLASS_DEF | MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_SCAN);
+ }
+ }
+
+ return true;
+}
+
+bool CParrotPerchHolder::StatusChangeMsg(CStatusChangeMsg *msg) {
+ _fieldF4 = msg->_newStatus;
+ return true;
+}
+
+bool CParrotPerchHolder::DropObjectMsg(CDropObjectMsg *msg) {
+ if (CCage::_open)
+ return false;
+ else
+ return CMultiDropTarget::DropObjectMsg(msg);
+}
+
+bool CParrotPerchHolder::ActMsg(CActMsg *msg) {
+ if (msg->_action == "FlashCore") {
+ playMovie(2, 2, 0);
+ playMovie(1, 1, 0);
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/parrot/parrot_perch_holder.h b/engines/titanic/game/parrot/parrot_perch_holder.h
index ff618f09dc..c1fe243476 100644
--- a/engines/titanic/game/parrot/parrot_perch_holder.h
+++ b/engines/titanic/game/parrot/parrot_perch_holder.h
@@ -28,6 +28,11 @@
namespace Titanic {
class CParrotPerchHolder : public CMultiDropTarget {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool StatusChangeMsg(CStatusChangeMsg *msg);
+ bool DropObjectMsg(CDropObjectMsg *msg);
+ bool ActMsg(CActMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/parrot/parrot_trigger.cpp b/engines/titanic/game/parrot/parrot_trigger.cpp
index 36e99ada33..b7287ebb6a 100644
--- a/engines/titanic/game/parrot/parrot_trigger.cpp
+++ b/engines/titanic/game/parrot/parrot_trigger.cpp
@@ -21,9 +21,15 @@
*/
#include "titanic/game/parrot/parrot_trigger.h"
+#include "titanic/npcs/parrot.h"
+#include "titanic/core/project_item.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CParrotTrigger, CGameObject)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
void CParrotTrigger::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_value, indent);
@@ -36,4 +42,11 @@ void CParrotTrigger::load(SimpleFile *file) {
CGameObject::load(file);
}
+bool CParrotTrigger::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ CTrueTalkTriggerActionMsg triggerMsg(_value, 0, 0);
+ triggerMsg.execute(getRoot(), CParrot::_type,
+ MSGFLAG_CLASS_DEF | MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_SCAN);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/parrot/parrot_trigger.h b/engines/titanic/game/parrot/parrot_trigger.h
index 28a1663fa8..6fba77b56d 100644
--- a/engines/titanic/game/parrot/parrot_trigger.h
+++ b/engines/titanic/game/parrot/parrot_trigger.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CParrotTrigger : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
public:
int _value;
public:
diff --git a/engines/titanic/game/parrot/player_meets_parrot.cpp b/engines/titanic/game/parrot/player_meets_parrot.cpp
index 6db9345bc0..cdb14516bf 100644
--- a/engines/titanic/game/parrot/player_meets_parrot.cpp
+++ b/engines/titanic/game/parrot/player_meets_parrot.cpp
@@ -24,6 +24,10 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPlayerMeetsParrot, CGameObject)
+ ON_MESSAGE(EnterRoomMsg)
+END_MESSAGE_MAP()
+
void CPlayerMeetsParrot::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CGameObject::save(file, indent);
@@ -35,7 +39,7 @@ void CPlayerMeetsParrot::load(SimpleFile *file) {
}
bool CPlayerMeetsParrot::EnterRoomMsg(CEnterRoomMsg *msg) {
- warning("CPlayerMeetsParrot::handleEvent");
+ stateSet24();
return true;
}
diff --git a/engines/titanic/game/parrot/player_meets_parrot.h b/engines/titanic/game/parrot/player_meets_parrot.h
index 9cee9ee322..edae18801f 100644
--- a/engines/titanic/game/parrot/player_meets_parrot.h
+++ b/engines/titanic/game/parrot/player_meets_parrot.h
@@ -29,6 +29,7 @@
namespace Titanic {
class CPlayerMeetsParrot : public CGameObject {
+ DECLARE_MESSAGE_MAP;
protected:
bool EnterRoomMsg(CEnterRoomMsg *msg);
public:
diff --git a/engines/titanic/game/pet/pet.cpp b/engines/titanic/game/pet/pet.cpp
index cd4e16d38c..99c9e01eb3 100644
--- a/engines/titanic/game/pet/pet.cpp
+++ b/engines/titanic/game/pet/pet.cpp
@@ -21,9 +21,14 @@
*/
#include "titanic/game/pet/pet.h"
+#include "titanic/pet_control/pet_control.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPET, CGameObject)
+ ON_MESSAGE(ShowTextMsg)
+END_MESSAGE_MAP()
+
CPET::CPET() : CGameObject(), _fieldBC(0), _fieldC0(3),
_fieldC4(0), _fieldC8(0), _fieldD8(0), _fieldDC(0) {
}
@@ -54,4 +59,11 @@ void CPET::load(SimpleFile *file) {
CGameObject::load(file);
}
+bool CPET::ShowTextMsg(CShowTextMsg *msg) {
+ CPetControl *pet = getPetControl();
+ if (pet)
+ pet->petDisplayMessage(1, msg->_value);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/pet/pet.h b/engines/titanic/game/pet/pet.h
index cdad649401..de31a423d0 100644
--- a/engines/titanic/game/pet/pet.h
+++ b/engines/titanic/game/pet/pet.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CPET : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool ShowTextMsg(CShowTextMsg *msg);
public:
int _fieldBC;
int _fieldC0;
diff --git a/engines/titanic/game/pet/pet_lift.cpp b/engines/titanic/game/pet/pet_lift.cpp
index 39b0d01540..afa9dd04cd 100644
--- a/engines/titanic/game/pet/pet_lift.cpp
+++ b/engines/titanic/game/pet/pet_lift.cpp
@@ -21,9 +21,14 @@
*/
#include "titanic/game/pet/pet_lift.h"
+#include "titanic/pet_control/pet_control.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPETLift, CPETTransport)
+ ON_MESSAGE(TransportMsg)
+END_MESSAGE_MAP()
+
void CPETLift::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CPETTransport::save(file, indent);
@@ -34,4 +39,36 @@ void CPETLift::load(SimpleFile *file) {
CPETTransport::load(file);
}
+bool CPETLift::TransportMsg(CTransportMsg *msg) {
+ CPetControl *pet = getPetControl();
+ if (msg->_value1 != 1)
+ return false;
+
+ int floorNum = -1;
+ if (msg->_roomName == "TopOfWell") {
+ floorNum = 1;
+ } else if (msg->_roomName == "BottomOfWell") {
+ floorNum = 39;
+ } else if (msg->_roomName == "PlayersRoom" && pet) {
+ int assignedFloor = pet->getAssignedFloorNum();
+ if (assignedFloor < 1 || assignedFloor > 39) {
+ pet->petDisplayMessage("You have not assigned a room to go to.");
+ floorNum = -1;
+ }
+ }
+
+ if (floorNum != -1) {
+ int elevatorNum = pet ? pet->getRoomsElevatorNum() : 0;
+
+ if ((elevatorNum == 2 || elevatorNum == 4) && floorNum > 27) {
+ petDisplayMessage("Sorry, this elevator does not go below floor 27.");
+ } else {
+ CTrueTalkTriggerActionMsg triggerMsg(2, floorNum, 0);
+ triggerMsg.execute("Liftbot");
+ }
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/pet/pet_lift.h b/engines/titanic/game/pet/pet_lift.h
index 88b4e1c029..ce3aace1a6 100644
--- a/engines/titanic/game/pet/pet_lift.h
+++ b/engines/titanic/game/pet/pet_lift.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CPETLift : public CPETTransport {
+ DECLARE_MESSAGE_MAP;
+ bool TransportMsg(CTransportMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/pet/pet_monitor.cpp b/engines/titanic/game/pet/pet_monitor.cpp
index 6a0d207a55..2716a81fa8 100644
--- a/engines/titanic/game/pet/pet_monitor.cpp
+++ b/engines/titanic/game/pet/pet_monitor.cpp
@@ -21,6 +21,8 @@
*/
#include "titanic/game/pet/pet_monitor.h"
+#include "titanic/core/room_item.h"
+#include "titanic/pet_control/pet_control.h"
namespace Titanic {
@@ -39,7 +41,23 @@ void CPETMonitor::load(SimpleFile *file) {
}
bool CPETMonitor::EnterRoomMsg(CEnterRoomMsg *msg) {
- warning("CPETMonitor::handleEvent");
+ bool flag = true;
+ if (msg->_newRoom && msg->_oldRoom) {
+ CString oldRoomName = msg->_oldRoom->getName();
+ CString newRoomName = msg->_newRoom->getName();
+
+ if (newRoomName == "SgtLobby" && oldRoomName == "SGTState")
+ flag = false;
+ }
+
+ if (flag) {
+ CPetControl *pet = getPetControl();
+ if (pet) {
+ pet->setRoomsRoomNum(0);
+ pet->resetRoomsHighlight();
+ }
+ }
+
return true;
}
diff --git a/engines/titanic/game/pet/pet_pellerator.cpp b/engines/titanic/game/pet/pet_pellerator.cpp
index a29942ca59..59516ebcde 100644
--- a/engines/titanic/game/pet/pet_pellerator.cpp
+++ b/engines/titanic/game/pet/pet_pellerator.cpp
@@ -24,6 +24,10 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPETPellerator, CPETTransport)
+ ON_MESSAGE(PETActivateMsg)
+END_MESSAGE_MAP()
+
void CPETPellerator::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CPETTransport::save(file, indent);
@@ -34,4 +38,24 @@ void CPETPellerator::load(SimpleFile *file) {
CPETTransport::load(file);
}
+bool CPETPellerator::PETActivateMsg(CPETActivateMsg *msg) {
+ CStatusChangeMsg statusMsg;
+
+ if (msg->_name == "PromenadeDeck")
+ statusMsg._newStatus = 0;
+ else if (msg->_name == "MusicRoom")
+ statusMsg._newStatus = 1;
+ else if (msg->_name == "Bar")
+ statusMsg._newStatus = 2;
+ else if (msg->_name == "TopOfWell")
+ statusMsg._newStatus = 4;
+ else if (msg->_name == "1stClassRestaurant")
+ statusMsg._newStatus = 5;
+ else if (msg->_name == "Arboretum")
+ statusMsg._newStatus = 6;
+
+ statusMsg.execute("PelleratorObject");
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/pet/pet_pellerator.h b/engines/titanic/game/pet/pet_pellerator.h
index 9b90c9af28..51af6f1bcd 100644
--- a/engines/titanic/game/pet/pet_pellerator.h
+++ b/engines/titanic/game/pet/pet_pellerator.h
@@ -24,10 +24,13 @@
#define TITANIC_PET_PELLERATOR_H
#include "titanic/game/pet/pet_transport.h"
+#include "titanic/messages/pet_messages.h"
namespace Titanic {
class CPETPellerator : public CPETTransport {
+ DECLARE_MESSAGE_MAP;
+ bool PETActivateMsg(CPETActivateMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/pet/pet_sentinal.cpp b/engines/titanic/game/pet/pet_sentinal.cpp
index 1b647d7c62..ac4cbc8418 100644
--- a/engines/titanic/game/pet/pet_sentinal.cpp
+++ b/engines/titanic/game/pet/pet_sentinal.cpp
@@ -21,17 +21,46 @@
*/
#include "titanic/game/pet/pet_sentinal.h"
+#include "titanic/pet_control/pet_control.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPETSentinal, CGameObject)
+ ON_MESSAGE(EnterViewMsg)
+END_MESSAGE_MAP()
+
+CPETSentinal::CPETSentinal() : CGameObject(), _elevatorNum(0),
+ _wellEntry(0), _resetHighlight(0) {
+}
+
void CPETSentinal::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
+ file->writeNumberLine(_elevatorNum, indent);
+ file->writeNumberLine(_wellEntry, indent);
+ file->writeNumberLine(_resetHighlight, indent);
CGameObject::save(file, indent);
}
void CPETSentinal::load(SimpleFile *file) {
file->readNumber();
+ _elevatorNum = file->readNumber();
+ _wellEntry = file->readNumber();
+ _resetHighlight = file->readNumber();
CGameObject::load(file);
}
+bool CPETSentinal::EnterViewMsg(CEnterViewMsg *msg) {
+ CPetControl *pet = getPetControl();
+ if (pet) {
+ if (_elevatorNum != -1)
+ pet->setRoomsElevatorNum(_elevatorNum);
+ if (_wellEntry)
+ pet->setRoomsWellEntry(_wellEntry);
+ if (_resetHighlight)
+ pet->resetRoomsHighlight();
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/pet/pet_sentinal.h b/engines/titanic/game/pet/pet_sentinal.h
index f7f9fef0ba..150fe4a87e 100644
--- a/engines/titanic/game/pet/pet_sentinal.h
+++ b/engines/titanic/game/pet/pet_sentinal.h
@@ -28,8 +28,15 @@
namespace Titanic {
class CPETSentinal : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool EnterViewMsg(CEnterViewMsg *msg);
+private:
+ int _elevatorNum;
+ int _wellEntry;
+ bool _resetHighlight;
public:
CLASSDEF;
+ CPETSentinal();
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/pet/pet_sounds.cpp b/engines/titanic/game/pet/pet_sounds.cpp
index d612c745bb..c7f3cd3bf8 100644
--- a/engines/titanic/game/pet/pet_sounds.cpp
+++ b/engines/titanic/game/pet/pet_sounds.cpp
@@ -24,16 +24,40 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPETSounds, CGameObject)
+ ON_MESSAGE(PETPlaySoundMsg)
+ ON_MESSAGE(LoadSuccessMsg)
+END_MESSAGE_MAP()
+
void CPETSounds::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_value, indent);
+ file->writeNumberLine(_ticks, indent);
CGameObject::save(file, indent);
}
void CPETSounds::load(SimpleFile *file) {
file->readNumber();
- _value = file->readNumber();
+ _ticks = file->readNumber();
CGameObject::load(file);
}
+bool CPETSounds::PETPlaySoundMsg(CPETPlaySoundMsg *msg) {
+ if (msg->_soundNum == 1) {
+ playSound("z#65.wav");
+ } else if (msg->_soundNum == 2 && stateGet24()) {
+ uint ticks = getTicksCount();
+ if (!_ticks || ticks > (_ticks + 12000)) {
+ playSound("z#36.wav");
+ _ticks = ticks;
+ }
+ }
+
+ return true;
+}
+
+bool CPETSounds::LoadSuccessMsg(CLoadSuccessMsg *msg) {
+ _ticks = 0;
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/pet/pet_sounds.h b/engines/titanic/game/pet/pet_sounds.h
index 1d3acdb5f3..2262fde916 100644
--- a/engines/titanic/game/pet/pet_sounds.h
+++ b/engines/titanic/game/pet/pet_sounds.h
@@ -24,15 +24,19 @@
#define TITANIC_PET_SOUNDS_H
#include "titanic/core/game_object.h"
+#include "titanic/messages/pet_messages.h"
namespace Titanic {
class CPETSounds : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool PETPlaySoundMsg(CPETPlaySoundMsg *msg);
+ bool LoadSuccessMsg(CLoadSuccessMsg *msg);
public:
- int _value;
+ uint _ticks;
public:
CLASSDEF;
- CPETSounds() : CGameObject(), _value(0) {}
+ CPETSounds() : CGameObject(), _ticks(0) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/pet/pet_transition.cpp b/engines/titanic/game/pet/pet_transition.cpp
index 33cc36ca11..ec10569236 100644
--- a/engines/titanic/game/pet/pet_transition.cpp
+++ b/engines/titanic/game/pet/pet_transition.cpp
@@ -21,9 +21,15 @@
*/
#include "titanic/game/pet/pet_transition.h"
+#include "titanic/pet_control/pet_control.h"
+#include "titanic/core/view_item.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPETTransition, CGameObject)
+ ON_MESSAGE(EnterViewMsg)
+END_MESSAGE_MAP()
+
void CPETTransition::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CGameObject::save(file, indent);
@@ -34,4 +40,21 @@ void CPETTransition::load(SimpleFile *file) {
CGameObject::load(file);
}
+bool CPETTransition::EnterViewMsg(CEnterViewMsg *msg) {
+ CPetControl *pet = getPetControl();
+
+ if (compareRoomNameTo("1stClassLobby") && pet) {
+ int elevatorNum = pet->getRoomsElevatorNum();
+ CString nodeView = msg->_newView->getNodeViewName();
+
+ if (nodeView == "Node 1.E") {
+ pet->setRoomsElevatorNum((elevatorNum == 1 || elevatorNum == 2) ? 1 : 3);
+ } else if (nodeView == "Node 1.W") {
+ pet->setRoomsElevatorNum((elevatorNum == 1 || elevatorNum == 2) ? 2 : 4);
+ }
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/pet/pet_transition.h b/engines/titanic/game/pet/pet_transition.h
index 4abf16d509..d0fa20ccc5 100644
--- a/engines/titanic/game/pet/pet_transition.h
+++ b/engines/titanic/game/pet/pet_transition.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CPETTransition : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool EnterViewMsg(CEnterViewMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/pet/pet_transport.cpp b/engines/titanic/game/pet/pet_transport.cpp
index 9661cace2c..a48e70ed01 100644
--- a/engines/titanic/game/pet/pet_transport.cpp
+++ b/engines/titanic/game/pet/pet_transport.cpp
@@ -39,7 +39,7 @@ void CPETTransport::load(SimpleFile *file) {
}
bool CPETTransport::EnterRoomMsg(CEnterRoomMsg *msg) {
- warning("CPETTransport::handleEvent");
+ petClear();
return true;
}
diff --git a/engines/titanic/game/pet_disabler.cpp b/engines/titanic/game/pet_disabler.cpp
index 2275156503..c4946fe39f 100644
--- a/engines/titanic/game/pet_disabler.cpp
+++ b/engines/titanic/game/pet_disabler.cpp
@@ -24,6 +24,11 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPetDisabler, CGameObject)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(LeaveViewMsg)
+END_MESSAGE_MAP()
+
void CPetDisabler::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeQuotedLine(_value, indent);
@@ -36,4 +41,14 @@ void CPetDisabler::load(SimpleFile *file) {
CGameObject::load(file);
}
+bool CPetDisabler::EnterViewMsg(CEnterViewMsg *msg) {
+ petLockInput();
+ return true;
+}
+
+bool CPetDisabler::LeaveViewMsg(CLeaveViewMsg *msg) {
+ petUnlockInput();
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/pet_disabler.h b/engines/titanic/game/pet_disabler.h
index 92b4dff0a8..06e99be49e 100644
--- a/engines/titanic/game/pet_disabler.h
+++ b/engines/titanic/game/pet_disabler.h
@@ -28,6 +28,9 @@
namespace Titanic {
class CPetDisabler : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
public:
CString _value;
public:
diff --git a/engines/titanic/game/phonograph.cpp b/engines/titanic/game/phonograph.cpp
index 9740e29273..408cfa3413 100644
--- a/engines/titanic/game/phonograph.cpp
+++ b/engines/titanic/game/phonograph.cpp
@@ -24,9 +24,18 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPhonograph, CMusicPlayer)
+ ON_MESSAGE(PhonographPlayMsg)
+ ON_MESSAGE(PhonographStopMsg)
+ ON_MESSAGE(PhonographRecordMsg)
+ ON_MESSAGE(EnterRoomMsg)
+ ON_MESSAGE(LeaveRoomMsg)
+ ON_MESSAGE(MusicHasStartedMsg)
+END_MESSAGE_MAP()
+
CPhonograph::CPhonograph() : CMusicPlayer(),
- _fieldE0(0), _fieldE4(0), _fieldE8(0), _fieldEC(0),
- _fieldF0(0), _fieldF4(0) {
+ _fieldE0(false), _fieldE4(0), _fieldE8(0), _fieldEC(0),
+ _fieldF0(0), _fieldF4(0) {
}
void CPhonograph::save(SimpleFile *file, int indent) {
@@ -55,8 +64,113 @@ void CPhonograph::load(SimpleFile *file) {
CMusicPlayer::load(file);
}
+bool CPhonograph::PhonographPlayMsg(CPhonographPlayMsg *msg) {
+ CQueryCylinderHolderMsg holderMsg;
+ holderMsg.execute(this);
+ if (!holderMsg._value2) {
+ _fieldE0 = false;
+ return true;
+ }
+
+ CQueryCylinderMsg cylinderMsg;
+ cylinderMsg.execute(holderMsg._target);
+
+ if (cylinderMsg._name.empty()) {
+ _fieldE0 = false;
+ } else if (cylinderMsg._name.hasPrefix("STMusic")) {
+ CStartMusicMsg startMsg(this);
+ startMsg.execute(this);
+ _fieldE0 = true;
+ msg->_value = 1;
+ } else {
+ stopGlobalSound(0, -1);
+ playGlobalSound(cylinderMsg._name, -2, true, true, 0);
+ _fieldE0 = true;
+ msg->_value = 1;
+ }
+
+ return true;
+}
+
+bool CPhonograph::PhonographStopMsg(CPhonographStopMsg *msg) {
+ CQueryCylinderHolderMsg holderMsg;
+ holderMsg.execute(this);
+ if (!holderMsg._value2)
+ return true;
+
+ _fieldE0 = false;
+ CQueryCylinderMsg cylinderMsg;
+ cylinderMsg.execute(holderMsg._target);
+
+ if (_fieldE0) {
+ if (!cylinderMsg._name.empty()) {
+ if (cylinderMsg._name.hasPrefix("STMusic")) {
+ CStopMusicMsg stopMsg;
+ stopMsg.execute(this);
+ } else {
+ stopGlobalSound(msg->_value1, -1);
+ }
+ msg->_value2 = 1;
+ }
+
+ if (!msg->_value3)
+ _fieldE0 = false;
+ } else if (_fieldE4) {
+ _fieldE4 = false;
+ msg->_value2 = 1;
+ }
+
+ return true;
+}
+
+bool CPhonograph::PhonographRecordMsg(CPhonographRecordMsg *msg) {
+ if (!_fieldE0 && !_fieldE4 && !_fieldE8) {
+ CQueryCylinderHolderMsg holderMsg;
+ holderMsg.execute(this);
+
+ if (holderMsg._value2) {
+ _fieldE4 = true;
+ CErasePhonographCylinderMsg eraseMsg;
+ eraseMsg.execute(holderMsg._target);
+ } else {
+ _fieldE4 = false;
+ }
+ }
+
+ return true;
+}
+
bool CPhonograph::EnterRoomMsg(CEnterRoomMsg *msg) {
- warning("CPhonograph::handleEvent");
+ if (_fieldE0) {
+ CPhonographPlayMsg playMsg;
+ playMsg.execute(this);
+ }
+
+ return true;
+}
+
+bool CPhonograph::LeaveRoomMsg(CLeaveRoomMsg *msg) {
+ if (_fieldE0) {
+ CPhonographStopMsg stopMsg;
+ stopMsg._value1 = 1;
+ stopMsg.execute(this);
+ }
+
+ return true;
+}
+
+bool CPhonograph::MusicHasStartedMsg(CMusicHasStartedMsg *msg) {
+ if (_fieldE4) {
+ CQueryCylinderHolderMsg holderMsg;
+ holderMsg.execute(this);
+ if (holderMsg._value2) {
+ CRecordOntoCylinderMsg recordMsg;
+ recordMsg.execute(holderMsg._target);
+ } else {
+ _fieldE4 = false;
+ }
+ }
+
return true;
}
diff --git a/engines/titanic/game/phonograph.h b/engines/titanic/game/phonograph.h
index 274d4ba367..b13a5ea910 100644
--- a/engines/titanic/game/phonograph.h
+++ b/engines/titanic/game/phonograph.h
@@ -29,10 +29,16 @@
namespace Titanic {
class CPhonograph : public CMusicPlayer {
+ DECLARE_MESSAGE_MAP;
+ bool PhonographPlayMsg(CPhonographPlayMsg *msg);
+ bool PhonographStopMsg(CPhonographStopMsg *msg);
+ bool PhonographRecordMsg(CPhonographRecordMsg *msg);
bool EnterRoomMsg(CEnterRoomMsg *msg);
+ bool LeaveRoomMsg(CLeaveRoomMsg *msg);
+ bool MusicHasStartedMsg(CMusicHasStartedMsg *msg);
protected:
CString _string2;
- int _fieldE0;
+ bool _fieldE0;
int _fieldE4;
int _fieldE8;
int _fieldEC;
diff --git a/engines/titanic/game/phonograph_lid.cpp b/engines/titanic/game/phonograph_lid.cpp
index a0518420f7..3741749fbf 100644
--- a/engines/titanic/game/phonograph_lid.cpp
+++ b/engines/titanic/game/phonograph_lid.cpp
@@ -24,16 +24,63 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPhonographLid, CGameObject)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(LockPhonographMsg)
+ ON_MESSAGE(LeaveViewMsg)
+END_MESSAGE_MAP()
+
void CPhonographLid::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_value, indent);
+ file->writeNumberLine(_open, indent);
CGameObject::save(file, indent);
}
void CPhonographLid::load(SimpleFile *file) {
file->readNumber();
- _value = file->readNumber();
+ _open = file->readNumber();
CGameObject::load(file);
}
+bool CPhonographLid::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ CQueryPhonographState stateMsg;
+ stateMsg.execute(getParent(), nullptr, MSGFLAG_SCAN);
+ if (stateMsg._value) {
+ if (_open) {
+ CGameObject *lock = dynamic_cast<CGameObject *>(findByName("Music System Lock"));
+ if (lock)
+ lock->setVisible(false);
+ playMovie(0, 27, 0);
+ } else {
+ playMovie(27, 55, 0);
+ }
+
+ _open = !_open;
+ } else {
+ petDisplayMessage(0, "This is the restaurant music system. It appears to be locked.");
+ }
+
+ return true;
+}
+
+bool CPhonographLid::MovieEndMsg(CMovieEndMsg *msg) {
+ // WORKAROUND: Redundant code in original not included
+ return true;
+}
+
+bool CPhonographLid::LockPhonographMsg(CLockPhonographMsg *msg) {
+ _cursorId = msg->_value ? CURSOR_INVALID : CURSOR_ARROW;
+ return true;
+}
+
+bool CPhonographLid::LeaveViewMsg(CLeaveViewMsg *msg) {
+ if (_open) {
+ playMovie(27, 55, MOVIE_GAMESTATE);
+ _open = false;
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/phonograph_lid.h b/engines/titanic/game/phonograph_lid.h
index ab32be268b..4e71d70ec2 100644
--- a/engines/titanic/game/phonograph_lid.h
+++ b/engines/titanic/game/phonograph_lid.h
@@ -28,11 +28,16 @@
namespace Titanic {
class CPhonographLid : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool LockPhonographMsg(CLockPhonographMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
private:
- int _value;
+ bool _open;
public:
CLASSDEF;
- CPhonographLid() : CGameObject(), _value(0) {}
+ CPhonographLid() : CGameObject(), _open(false) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/pickup/pick_up.cpp b/engines/titanic/game/pickup/pick_up.cpp
index c660a36a32..64d2d1d0d2 100644
--- a/engines/titanic/game/pickup/pick_up.cpp
+++ b/engines/titanic/game/pickup/pick_up.cpp
@@ -24,16 +24,26 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPickUp, CGameObject)
+ ON_MESSAGE(StatusChangeMsg)
+END_MESSAGE_MAP()
+
void CPickUp::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldBC, indent);
+ file->writeNumberLine(_enabled, indent);
CGameObject::save(file, indent);
}
void CPickUp::load(SimpleFile *file) {
file->readNumber();
- _fieldBC = file->readNumber();
+ _enabled = file->readNumber();
CGameObject::load(file);
}
+bool CPickUp::StatusChangeMsg(CStatusChangeMsg *msg) {
+ _enabled = msg->_newStatus == 1;
+ setVisible(_enabled);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/pickup/pick_up.h b/engines/titanic/game/pickup/pick_up.h
index f0b6794442..f5ee06fd32 100644
--- a/engines/titanic/game/pickup/pick_up.h
+++ b/engines/titanic/game/pickup/pick_up.h
@@ -28,11 +28,13 @@
namespace Titanic {
class CPickUp : public CGameObject {
-private:
- int _fieldBC;
+ DECLARE_MESSAGE_MAP;
+ bool StatusChangeMsg(CStatusChangeMsg *msg);
+protected:
+ bool _enabled;
public:
CLASSDEF;
- CPickUp() : CGameObject(), _fieldBC(0) {}
+ CPickUp() : CGameObject(), _enabled(false) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/pickup/pick_up_bar_glass.cpp b/engines/titanic/game/pickup/pick_up_bar_glass.cpp
index 85b883281e..9da17b139e 100644
--- a/engines/titanic/game/pickup/pick_up_bar_glass.cpp
+++ b/engines/titanic/game/pickup/pick_up_bar_glass.cpp
@@ -21,9 +21,16 @@
*/
#include "titanic/game/pickup/pick_up_bar_glass.h"
+#include "titanic/core/project_item.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPickUpBarGlass, CPickUp)
+ ON_MESSAGE(StatusChangeMsg)
+ ON_MESSAGE(MouseDragStartMsg)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
void CPickUpBarGlass::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CPickUp::save(file, indent);
@@ -34,4 +41,48 @@ void CPickUpBarGlass::load(SimpleFile *file) {
CPickUp::load(file);
}
+bool CPickUpBarGlass::StatusChangeMsg(CStatusChangeMsg *msg) {
+ switch (msg->_newStatus) {
+ case 0:
+ setVisible(false);
+ _enabled = false;
+ break;
+ case 1:
+ setVisible(true);
+ _enabled = true;
+ break;
+ case 2:
+ setVisible(true);
+ _enabled = false;
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool CPickUpBarGlass::MouseDragStartMsg(CMouseDragStartMsg *msg) {
+ if (checkStartDragging(msg) && _enabled) {
+ CTurnOn onMsg;
+ onMsg.execute("BeerGlass");
+ CVisibleMsg visibleMsg;
+ visibleMsg.execute("BeerGlass");
+ CPassOnDragStartMsg passMsg(msg->_mousePos, 1, 3);
+ passMsg.execute("BeerGlass");
+
+ msg->_dragItem = getRoot()->findByName("BeerGlass");
+
+ CActMsg actMsg("PlayerTakesGlass");
+ actMsg.execute("Barbot");
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool CPickUpBarGlass::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/pickup/pick_up_bar_glass.h b/engines/titanic/game/pickup/pick_up_bar_glass.h
index b5ef6f5a47..d273d96170 100644
--- a/engines/titanic/game/pickup/pick_up_bar_glass.h
+++ b/engines/titanic/game/pickup/pick_up_bar_glass.h
@@ -28,6 +28,10 @@
namespace Titanic {
class CPickUpBarGlass : public CPickUp {
+ DECLARE_MESSAGE_MAP;
+ bool StatusChangeMsg(CStatusChangeMsg *msg);
+ bool MouseDragStartMsg(CMouseDragStartMsg *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/pickup/pick_up_hose.cpp b/engines/titanic/game/pickup/pick_up_hose.cpp
index 7375ddaa63..d07088cefd 100644
--- a/engines/titanic/game/pickup/pick_up_hose.cpp
+++ b/engines/titanic/game/pickup/pick_up_hose.cpp
@@ -21,14 +21,24 @@
*/
#include "titanic/game/pickup/pick_up_hose.h"
+#include "titanic/core/project_item.h"
+#include "titanic/core/room_item.h"
+#include "titanic/core/view_item.h"
namespace Titanic {
-int CPickUpHose::_v1;
+BEGIN_MESSAGE_MAP(CPickUpHose, CPickUp)
+ ON_MESSAGE(MouseDragStartMsg)
+ ON_MESSAGE(StatusChangeMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
+bool CPickUpHose::_v1;
void CPickUpHose::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeQuotedLine(_string1, indent);
+ file->writeQuotedLine(_target, indent);
file->writeNumberLine(_v1, indent);
CPickUp::save(file, indent);
@@ -36,10 +46,61 @@ void CPickUpHose::save(SimpleFile *file, int indent) {
void CPickUpHose::load(SimpleFile *file) {
file->readNumber();
- _string1 = file->readString();
+ _target = file->readString();
_v1 = file->readNumber();
CPickUp::load(file);
}
+bool CPickUpHose::MouseDragStartMsg(CMouseDragStartMsg *msg) {
+ if (!checkStartDragging(msg))
+ return true;
+ if (_v1 || !_enabled)
+ return false;
+
+ CViewItem *view = getView();
+ if (view) {
+ _v1 = true;
+ CRoomItem *room = locateRoom("Arboretum");
+ CTreeItem *hose = room ? room->findByName("Hose") : nullptr;
+
+ if (!hose) {
+ room = locateRoom("FrozenArboretum");
+ if (room)
+ hose = room->findByName("Hose");
+ }
+
+ if (hose) {
+ CVisibleMsg visibleMsg;
+ visibleMsg.execute(this);
+ moveUnder(view);
+
+ CPassOnDragStartMsg passMsg(msg->_mousePos, 1);
+ passMsg.execute("Hose");
+
+ msg->_dragItem = getRoot()->findByName("Hose");
+ _cursorId = CURSOR_IGNORE;
+
+ CActMsg actMsg("PlayerGetsHose");
+ actMsg.execute(_target);
+ }
+ }
+
+ return true;
+}
+
+bool CPickUpHose::StatusChangeMsg(CStatusChangeMsg *msg) {
+ _cursorId = msg->_newStatus == 1 ? CURSOR_HAND : CURSOR_IGNORE;
+ return true;
+}
+
+bool CPickUpHose::EnterViewMsg(CEnterViewMsg *msg) {
+ _cursorId = CURSOR_IGNORE;
+ return true;
+}
+
+bool CPickUpHose::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ return _enabled;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/pickup/pick_up_hose.h b/engines/titanic/game/pickup/pick_up_hose.h
index 80ccedc845..2ad7c2a583 100644
--- a/engines/titanic/game/pickup/pick_up_hose.h
+++ b/engines/titanic/game/pickup/pick_up_hose.h
@@ -28,10 +28,15 @@
namespace Titanic {
class CPickUpHose : public CPickUp {
+ DECLARE_MESSAGE_MAP;
+ bool MouseDragStartMsg(CMouseDragStartMsg *msg);
+ bool StatusChangeMsg(CStatusChangeMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
private:
- static int _v1;
+ static bool _v1;
- CString _string1;
+ CString _target;
public:
CLASSDEF;
diff --git a/engines/titanic/game/pickup/pick_up_lemon.cpp b/engines/titanic/game/pickup/pick_up_lemon.cpp
index 772114f76c..5109c36304 100644
--- a/engines/titanic/game/pickup/pick_up_lemon.cpp
+++ b/engines/titanic/game/pickup/pick_up_lemon.cpp
@@ -21,9 +21,15 @@
*/
#include "titanic/game/pickup/pick_up_lemon.h"
+#include "titanic/core/project_item.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPickUpLemon, CPickUp)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(MouseDragStartMsg)
+END_MESSAGE_MAP()
+
void CPickUpLemon::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CPickUp::save(file, indent);
@@ -34,4 +40,23 @@ void CPickUpLemon::load(SimpleFile *file) {
CPickUp::load(file);
}
+bool CPickUpLemon::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ return true;
+}
+
+bool CPickUpLemon::MouseDragStartMsg(CMouseDragStartMsg *msg) {
+ if (!checkStartDragging(msg))
+ return true;
+ if (!_enabled)
+ return false;
+
+ CVisibleMsg visibleMsg;
+ visibleMsg.execute("Lemon");
+ CPassOnDragStartMsg passMsg(msg->_mousePos, 1);
+ passMsg.execute("Lemon");
+
+ msg->_dragItem = getRoot()->findByName("Lemon");
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/pickup/pick_up_lemon.h b/engines/titanic/game/pickup/pick_up_lemon.h
index 0312c71012..c196acdeaf 100644
--- a/engines/titanic/game/pickup/pick_up_lemon.h
+++ b/engines/titanic/game/pickup/pick_up_lemon.h
@@ -28,6 +28,9 @@
namespace Titanic {
class CPickUpLemon : public CPickUp {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool MouseDragStartMsg(CMouseDragStartMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/pickup/pick_up_speech_centre.cpp b/engines/titanic/game/pickup/pick_up_speech_centre.cpp
index 0b9a8d2c48..5e99c0a3b7 100644
--- a/engines/titanic/game/pickup/pick_up_speech_centre.cpp
+++ b/engines/titanic/game/pickup/pick_up_speech_centre.cpp
@@ -21,9 +21,16 @@
*/
#include "titanic/game/pickup/pick_up_speech_centre.h"
+#include "titanic/core/project_item.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPickUpSpeechCentre, CPickUp)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(StatusChangeMsg)
+ ON_MESSAGE(MouseDragStartMsg)
+END_MESSAGE_MAP()
+
void CPickUpSpeechCentre::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CPickUp::save(file, indent);
@@ -34,4 +41,33 @@ void CPickUpSpeechCentre::load(SimpleFile *file) {
CPickUp::load(file);
}
+bool CPickUpSpeechCentre::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ return true;
+}
+
+bool CPickUpSpeechCentre::StatusChangeMsg(CStatusChangeMsg *msg) {
+ _enabled = msg->_newStatus == 1;
+ return true;
+}
+
+bool CPickUpSpeechCentre::MouseDragStartMsg(CMouseDragStartMsg *msg) {
+ if (checkStartDragging(msg)) {
+ if (_enabled) {
+ CVisibleMsg visibleMsg;
+ visibleMsg.execute("SpeechCentre");
+ CPassOnDragStartMsg passMsg(msg->_mousePos, 1);
+ passMsg.execute("SpeechCentre");
+
+ msg->_dragItem = getRoot()->findByName("SpeechCentre");
+
+ CActMsg actMsg("PlayerGetsSpeechCentre");
+ actMsg.execute("SeasonalAdjust");
+ } else {
+ petDisplayMessage("You can't pick this up on account of it being stuck to the branch.");
+ }
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/pickup/pick_up_speech_centre.h b/engines/titanic/game/pickup/pick_up_speech_centre.h
index 29dce04fb3..81ee0b5d77 100644
--- a/engines/titanic/game/pickup/pick_up_speech_centre.h
+++ b/engines/titanic/game/pickup/pick_up_speech_centre.h
@@ -28,6 +28,10 @@
namespace Titanic {
class CPickUpSpeechCentre : public CPickUp {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool StatusChangeMsg(CStatusChangeMsg *msg);
+ bool MouseDragStartMsg(CMouseDragStartMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/pickup/pick_up_vis_centre.cpp b/engines/titanic/game/pickup/pick_up_vis_centre.cpp
index 796e46778c..baf1763d09 100644
--- a/engines/titanic/game/pickup/pick_up_vis_centre.cpp
+++ b/engines/titanic/game/pickup/pick_up_vis_centre.cpp
@@ -24,6 +24,11 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPickUpVisCentre, CPickUp)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(MouseDragStartMsg)
+END_MESSAGE_MAP()
+
void CPickUpVisCentre::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CPickUp::save(file, indent);
@@ -34,4 +39,22 @@ void CPickUpVisCentre::load(SimpleFile *file) {
CPickUp::load(file);
}
+
+bool CPickUpVisCentre::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ return true;
+}
+
+bool CPickUpVisCentre::MouseDragStartMsg(CMouseDragStartMsg *msg) {
+ if (!checkStartDragging(msg) || !_enabled)
+ return false;
+
+ setVisible(false);
+ CVisibleMsg visibleMsg;
+ visibleMsg.execute("VisionCentre");
+ msg->execute("VisionCentre");
+ CActMsg actMsg("PlayerTakesVisCentre");
+ actMsg.execute("Barbot");
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/pickup/pick_up_vis_centre.h b/engines/titanic/game/pickup/pick_up_vis_centre.h
index 4f808f73c5..a5f59211d3 100644
--- a/engines/titanic/game/pickup/pick_up_vis_centre.h
+++ b/engines/titanic/game/pickup/pick_up_vis_centre.h
@@ -28,6 +28,9 @@
namespace Titanic {
class CPickUpVisCentre : public CPickUp {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool MouseDragStartMsg(CMouseDragStartMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/placeholder/bar_shelf_vis_centre.cpp b/engines/titanic/game/placeholder/bar_shelf_vis_centre.cpp
index fc5d680f0c..6e5037f237 100644
--- a/engines/titanic/game/placeholder/bar_shelf_vis_centre.cpp
+++ b/engines/titanic/game/placeholder/bar_shelf_vis_centre.cpp
@@ -24,7 +24,7 @@
namespace Titanic {
-BEGIN_MESSAGE_MAP(CBarShelfVisCentre, CPlaceHolderItem)
+BEGIN_MESSAGE_MAP(CBarShelfVisCentre, CPlaceHolder)
ON_MESSAGE(MouseButtonDownMsg)
ON_MESSAGE(TimerMsg)
ON_MESSAGE(EnterViewMsg)
@@ -33,13 +33,13 @@ END_MESSAGE_MAP()
void CBarShelfVisCentre::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_flag, indent);
- CPlaceHolderItem::save(file, indent);
+ CPlaceHolder::save(file, indent);
}
void CBarShelfVisCentre::load(SimpleFile *file) {
file->readNumber();
_flag = file->readNumber();
- CPlaceHolderItem::load(file);
+ CPlaceHolder::load(file);
}
bool CBarShelfVisCentre::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
diff --git a/engines/titanic/game/placeholder/bar_shelf_vis_centre.h b/engines/titanic/game/placeholder/bar_shelf_vis_centre.h
index 672655d368..8ad3dcb8d1 100644
--- a/engines/titanic/game/placeholder/bar_shelf_vis_centre.h
+++ b/engines/titanic/game/placeholder/bar_shelf_vis_centre.h
@@ -23,11 +23,11 @@
#ifndef TITANIC_BAR_SHELF_VIS_CENTRE_H
#define TITANIC_BAR_SHELF_VIS_CENTRE_H
-#include "titanic/game/placeholder/place_holder_item.h"
+#include "titanic/game/placeholder/place_holder.h"
namespace Titanic {
-class CBarShelfVisCentre : public CPlaceHolderItem {
+class CBarShelfVisCentre : public CPlaceHolder {
DECLARE_MESSAGE_MAP;
bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
bool TimerMsg(CTimerMsg *msg);
@@ -36,7 +36,7 @@ private:
bool _flag;
public:
CLASSDEF;
- CBarShelfVisCentre() : CPlaceHolderItem(), _flag(false) {}
+ CBarShelfVisCentre() : CPlaceHolder(), _flag(false) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/placeholder/lemon_on_bar.cpp b/engines/titanic/game/placeholder/lemon_on_bar.cpp
index 917c751e67..e9cf6a309a 100644
--- a/engines/titanic/game/placeholder/lemon_on_bar.cpp
+++ b/engines/titanic/game/placeholder/lemon_on_bar.cpp
@@ -24,20 +24,20 @@
namespace Titanic {
-BEGIN_MESSAGE_MAP(CLemonOnBar, CPlaceHolderItem)
+BEGIN_MESSAGE_MAP(CLemonOnBar, CPlaceHolder)
ON_MESSAGE(VisibleMsg)
END_MESSAGE_MAP()
void CLemonOnBar::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writePoint(_lemonPos, indent);
- CPlaceHolderItem::save(file, indent);
+ CPlaceHolder::save(file, indent);
}
void CLemonOnBar::load(SimpleFile *file) {
file->readNumber();
_lemonPos = file->readPoint();
- CPlaceHolderItem::load(file);
+ CPlaceHolder::load(file);
}
bool CLemonOnBar::VisibleMsg(CVisibleMsg *msg) {
diff --git a/engines/titanic/game/placeholder/lemon_on_bar.h b/engines/titanic/game/placeholder/lemon_on_bar.h
index af5d5e67c8..c6512ced67 100644
--- a/engines/titanic/game/placeholder/lemon_on_bar.h
+++ b/engines/titanic/game/placeholder/lemon_on_bar.h
@@ -23,11 +23,11 @@
#ifndef TITANIC_LEMON_ON_BAR_H
#define TITANIC_LEMON_ON_BAR_H
-#include "titanic/game/placeholder/place_holder_item.h"
+#include "titanic/game/placeholder/place_holder.h"
namespace Titanic {
-class CLemonOnBar : public CPlaceHolderItem {
+class CLemonOnBar : public CPlaceHolder {
DECLARE_MESSAGE_MAP;
bool VisibleMsg(CVisibleMsg *msg);
private:
diff --git a/engines/titanic/game/placeholder/place_holder_item.cpp b/engines/titanic/game/placeholder/place_holder.cpp
index 365e8cbe50..ae42cabc29 100644
--- a/engines/titanic/game/placeholder/place_holder_item.cpp
+++ b/engines/titanic/game/placeholder/place_holder.cpp
@@ -20,18 +20,27 @@
*
*/
-#include "titanic/game/placeholder/place_holder_item.h"
+#include "titanic/game/placeholder/place_holder.h"
namespace Titanic {
-void CPlaceHolderItem::save(SimpleFile *file, int indent) {
+BEGIN_MESSAGE_MAP(CPlaceHolder, CGameObject)
+ ON_MESSAGE(VisibleMsg)
+END_MESSAGE_MAP()
+
+void CPlaceHolder::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CGameObject::save(file, indent);
}
-void CPlaceHolderItem::load(SimpleFile *file) {
+void CPlaceHolder::load(SimpleFile *file) {
file->readNumber();
CGameObject::load(file);
}
+bool CPlaceHolder::VisibleMsg(CVisibleMsg *msg) {
+ setVisible(msg->_visible);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/placeholder/place_holder_item.h b/engines/titanic/game/placeholder/place_holder.h
index de04a64bf7..b1aa041710 100644
--- a/engines/titanic/game/placeholder/place_holder_item.h
+++ b/engines/titanic/game/placeholder/place_holder.h
@@ -27,7 +27,9 @@
namespace Titanic {
-class CPlaceHolderItem : public CGameObject {
+class CPlaceHolder : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool VisibleMsg(CVisibleMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/placeholder/tv_on_bar.cpp b/engines/titanic/game/placeholder/tv_on_bar.cpp
index efbbe50461..710b5a346e 100644
--- a/engines/titanic/game/placeholder/tv_on_bar.cpp
+++ b/engines/titanic/game/placeholder/tv_on_bar.cpp
@@ -24,16 +24,30 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CTVOnBar, CPlaceHolder)
+ ON_MESSAGE(VisibleMsg)
+END_MESSAGE_MAP()
+
void CTVOnBar::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writePoint(_pos1, indent);
- CPlaceHolderItem::save(file, indent);
+ file->writePoint(_tvPos, indent);
+ CPlaceHolder::save(file, indent);
}
void CTVOnBar::load(SimpleFile *file) {
file->readNumber();
- _pos1 = file->readPoint();
- CPlaceHolderItem::load(file);
+ _tvPos = file->readPoint();
+ CPlaceHolder::load(file);
+}
+
+bool CTVOnBar::VisibleMsg(CVisibleMsg *msg) {
+ setVisible(msg->_visible);
+ if (msg->_visible)
+ setPosition(_tvPos);
+ else
+ setPosition(Point(0, 0));
+
+ return true;
}
} // End of namespace Titanic
diff --git a/engines/titanic/game/placeholder/tv_on_bar.h b/engines/titanic/game/placeholder/tv_on_bar.h
index d41d972e73..0157bc8764 100644
--- a/engines/titanic/game/placeholder/tv_on_bar.h
+++ b/engines/titanic/game/placeholder/tv_on_bar.h
@@ -23,13 +23,15 @@
#ifndef TITANIC_TV_ON_BAR_H
#define TITANIC_TV_ON_BAR_H
-#include "titanic/game/placeholder/place_holder_item.h"
+#include "titanic/game/placeholder/place_holder.h"
namespace Titanic {
-class CTVOnBar : public CPlaceHolderItem {
+class CTVOnBar : public CPlaceHolder {
+ DECLARE_MESSAGE_MAP;
+ bool VisibleMsg(CVisibleMsg *msg);
private:
- Point _pos1;
+ Point _tvPos;
public:
CLASSDEF;
diff --git a/engines/titanic/game/play_music_button.cpp b/engines/titanic/game/play_music_button.cpp
index 8066739f10..93416911b8 100644
--- a/engines/titanic/game/play_music_button.cpp
+++ b/engines/titanic/game/play_music_button.cpp
@@ -21,23 +21,58 @@
*/
#include "titanic/game/play_music_button.h"
+#include "titanic/sound/music_room.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPlayMusicButton, CBackground)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(FrameMsg)
+END_MESSAGE_MAP()
+
void CPlayMusicButton::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldE0, indent);
- file->writeNumberLine(_fieldE4, indent);
+ file->writeNumberLine(_flag, indent);
+ file->writeNumberLine(_ticks, indent);
CBackground::save(file, indent);
}
void CPlayMusicButton::load(SimpleFile *file) {
file->readNumber();
- _fieldE0 = file->readNumber();
- _fieldE4 = file->readNumber();
+ _flag = file->readNumber();
+ _ticks = file->readNumber();
CBackground::load(file);
}
+bool CPlayMusicButton::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ CMusicRoom *musicRoom = getMusicRoom();
+ if (_flag) {
+ musicRoom->stopMusic();
+ stopMovie();
+ loadFrame(0);
+ _flag = false;
+ } else {
+ musicRoom->startMusic(100);
+ playMovie(MOVIE_REPEAT);
+ _ticks = getTicksCount();
+ _flag = true;
+ }
+
+ return true;
+}
+
+bool CPlayMusicButton::FrameMsg(CFrameMsg *msg) {
+ if (_flag && !CMusicRoom::_musicHandler->isBusy()) {
+ CMusicRoom *musicRoom = getMusicRoom();
+ musicRoom->stopMusic();
+ stopMovie();
+ loadFrame(0);
+ _flag = false;
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/play_music_button.h b/engines/titanic/game/play_music_button.h
index 4e3474181c..824b372bf9 100644
--- a/engines/titanic/game/play_music_button.h
+++ b/engines/titanic/game/play_music_button.h
@@ -28,12 +28,15 @@
namespace Titanic {
class CPlayMusicButton : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool FrameMsg(CFrameMsg *msg);
public:
- int _fieldE0;
- int _fieldE4;
+ bool _flag;
+ uint _ticks;
public:
CLASSDEF;
- CPlayMusicButton() : CBackground(), _fieldE0(0), _fieldE4(0) {}
+ CPlayMusicButton() : CBackground(), _flag(false), _ticks(0) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/play_on_act.cpp b/engines/titanic/game/play_on_act.cpp
index e1ef1201c6..9c368c335d 100644
--- a/engines/titanic/game/play_on_act.cpp
+++ b/engines/titanic/game/play_on_act.cpp
@@ -24,6 +24,11 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CPlayOnAct, CBackground)
+ ON_MESSAGE(ActMsg)
+ ON_MESSAGE(LeaveViewMsg)
+END_MESSAGE_MAP()
+
void CPlayOnAct::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CBackground::save(file, indent);
@@ -34,4 +39,20 @@ void CPlayOnAct::load(SimpleFile *file) {
CBackground::load(file);
}
+bool CPlayOnAct::ActMsg(CActMsg *msg) {
+ if (msg->_action == "PlayMovie") {
+ setVisible(true);
+ playMovie(0);
+ } else if (msg->_action == "PlayToEnd") {
+ setVisible(true);
+ playMovie(MOVIE_GAMESTATE);
+ }
+
+ return true;
+}
+
+bool CPlayOnAct::LeaveViewMsg(CLeaveViewMsg *msg) {
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/play_on_act.h b/engines/titanic/game/play_on_act.h
index 197e647943..72615f2fc4 100644
--- a/engines/titanic/game/play_on_act.h
+++ b/engines/titanic/game/play_on_act.h
@@ -28,6 +28,9 @@
namespace Titanic {
class CPlayOnAct : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool ActMsg(CActMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/port_hole.cpp b/engines/titanic/game/port_hole.cpp
index f3c447f443..25807b1b1d 100644
--- a/engines/titanic/game/port_hole.cpp
+++ b/engines/titanic/game/port_hole.cpp
@@ -24,26 +24,72 @@
namespace Titanic {
-CPortHole::CPortHole() : CGameObject(), _fieldBC(0),
- _string1("b#47.wav"), _string2("b#46.wav") {
+BEGIN_MESSAGE_MAP(CPortHole, CGameObject)
+ ON_MESSAGE(ActMsg)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(LeaveViewMsg)
+ ON_MESSAGE(EnterViewMsg)
+END_MESSAGE_MAP()
+
+CPortHole::CPortHole() : CGameObject(), _open(false),
+ _closeSoundName("b#47.wav"), _openSoundName("b#46.wav") {
}
void CPortHole::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldBC, indent);
- file->writeQuotedLine(_string1, indent);
- file->writeQuotedLine(_string2, indent);
+ file->writeNumberLine(_open, indent);
+ file->writeQuotedLine(_closeSoundName, indent);
+ file->writeQuotedLine(_openSoundName, indent);
CGameObject::save(file, indent);
}
void CPortHole::load(SimpleFile *file) {
file->readNumber();
- _fieldBC = file->readNumber();
- _string1 = file->readString();
- _string2 = file->readString();
+ _open = file->readNumber();
+ _closeSoundName = file->readString();
+ _openSoundName = file->readString();
CGameObject::load(file);
}
+bool CPortHole::ActMsg(CActMsg *msg) {
+ if (msg->_action == "TogglePortHole") {
+ if (_open) {
+ playMovie(14, 26, MOVIE_NOTIFY_OBJECT);
+ playSound(_closeSoundName);
+ _open = false;
+ } else {
+ setVisible(true);
+ playMovie(1, 13, 0);
+ playSound(_openSoundName);
+ _open = true;
+ }
+ }
+
+ return true;
+}
+
+bool CPortHole::MovieEndMsg(CMovieEndMsg *msg) {
+ _open = false;
+ setVisible(false);
+ return true;
+}
+
+bool CPortHole::LeaveViewMsg(CLeaveViewMsg *msg) {
+ if (_open) {
+ playSound(_closeSoundName);
+ playMovie(14, 26, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ _open = false;
+ }
+
+ return true;
+}
+
+bool CPortHole::EnterViewMsg(CEnterViewMsg *msg) {
+ setVisible(false);
+ _open = false;
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/port_hole.h b/engines/titanic/game/port_hole.h
index 7bba18d12a..9f1997a517 100644
--- a/engines/titanic/game/port_hole.h
+++ b/engines/titanic/game/port_hole.h
@@ -28,9 +28,14 @@
namespace Titanic {
class CPortHole : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool ActMsg(CActMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
private:
- int _fieldBC;
- CString _string1, _string2;
+ bool _open;
+ CString _closeSoundName, _openSoundName;
public:
CLASSDEF;
CPortHole();
diff --git a/engines/titanic/game/record_phonograph_button.cpp b/engines/titanic/game/record_phonograph_button.cpp
index f022957dbb..1ffaec4228 100644
--- a/engines/titanic/game/record_phonograph_button.cpp
+++ b/engines/titanic/game/record_phonograph_button.cpp
@@ -24,16 +24,44 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CRecordPhonographButton, CBackground)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(PhonographStopMsg)
+END_MESSAGE_MAP()
+
void CRecordPhonographButton::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_value, indent);
+ file->writeNumberLine(_active, indent);
CBackground::save(file, indent);
}
void CRecordPhonographButton::load(SimpleFile *file) {
file->readNumber();
- _value = file->readNumber();
+ _active = file->readNumber();
CBackground::load(file);
}
+bool CRecordPhonographButton::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ CPhonographRecordMsg recordMsg;
+ recordMsg.execute(getParent());
+
+ if (recordMsg._value) {
+ playSound("z#58.wav");
+ loadFrame(1);
+ _active = true;
+ }
+
+ return true;
+}
+
+bool CRecordPhonographButton::PhonographStopMsg(CPhonographStopMsg *msg) {
+ if (_active) {
+ playSound("z#57.wav");
+ loadFrame(0);
+ _active = false;
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/record_phonograph_button.h b/engines/titanic/game/record_phonograph_button.h
index 3383c01e31..985a4c4576 100644
--- a/engines/titanic/game/record_phonograph_button.h
+++ b/engines/titanic/game/record_phonograph_button.h
@@ -28,11 +28,14 @@
namespace Titanic {
class CRecordPhonographButton : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool PhonographStopMsg(CPhonographStopMsg *msg);
public:
- int _value;
+ bool _active;
public:
CLASSDEF;
- CRecordPhonographButton() : CBackground(), _value(0) {}
+ CRecordPhonographButton() : CBackground(), _active(false) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/replacement_ear.cpp b/engines/titanic/game/replacement_ear.cpp
index 1f9960365d..e8bd384207 100644
--- a/engines/titanic/game/replacement_ear.cpp
+++ b/engines/titanic/game/replacement_ear.cpp
@@ -24,6 +24,10 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CReplacementEar, CBackground)
+ ON_MESSAGE(VisibleMsg)
+END_MESSAGE_MAP()
+
void CReplacementEar::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CBackground::save(file, indent);
@@ -34,4 +38,11 @@ void CReplacementEar::load(SimpleFile *file) {
CBackground::load(file);
}
+bool CReplacementEar::VisibleMsg(CVisibleMsg *msg) {
+ setVisible(true);
+ playMovie(MOVIE_GAMESTATE);
+ playSound("z#64.wav");
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/replacement_ear.h b/engines/titanic/game/replacement_ear.h
index 0d282b7fb4..7775a9631a 100644
--- a/engines/titanic/game/replacement_ear.h
+++ b/engines/titanic/game/replacement_ear.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CReplacementEar : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool VisibleMsg(CVisibleMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/reserved_table.cpp b/engines/titanic/game/reserved_table.cpp
index a600190709..734d53af45 100644
--- a/engines/titanic/game/reserved_table.cpp
+++ b/engines/titanic/game/reserved_table.cpp
@@ -21,22 +21,55 @@
*/
#include "titanic/game/reserved_table.h"
+#include "titanic/core/room_item.h"
+#include "titanic/core/view_item.h"
+#include "titanic/npcs/maitre_d.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CReservedTable, CGameObject)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(PlayerTriesRestaurantTableMsg)
+END_MESSAGE_MAP()
+
void CReservedTable::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_value1, indent);
- file->writeNumberLine(_value2, indent);
+ file->writeNumberLine(_flag, indent);
+ file->writeNumberLine(_tableId, indent);
CGameObject::save(file, indent);
}
void CReservedTable::load(SimpleFile *file) {
file->readNumber();
- _value1 = file->readNumber();
- _value2 = file->readNumber();
+ _flag = file->readNumber();
+ _tableId = file->readNumber();
CGameObject::load(file);
}
+bool CReservedTable::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (!_flag) {
+ CPlayerTriesRestaurantTableMsg tryMsg(_tableId, 0);
+ tryMsg.execute(findRoom(), CReservedTable::_type, MSGFLAG_CLASS_DEF | MSGFLAG_SCAN);
+ }
+
+ return true;
+}
+
+bool CReservedTable::PlayerTriesRestaurantTableMsg(CPlayerTriesRestaurantTableMsg *msg) {
+ if (msg->_tableId == _tableId) {
+ if (!msg->_result) {
+ CMaitreD *maitreD = dynamic_cast<CMaitreD *>(findRoomObject("MaitreD"));
+ startTalking(maitreD, 118, maitreD->findView());
+ msg->_result = true;
+ }
+
+ _cursorId = CURSOR_INVALID;
+ _flag = true;
+ return true;
+ } else {
+ return false;
+ }
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/reserved_table.h b/engines/titanic/game/reserved_table.h
index a3532c7d14..bc037ae3d9 100644
--- a/engines/titanic/game/reserved_table.h
+++ b/engines/titanic/game/reserved_table.h
@@ -28,11 +28,15 @@
namespace Titanic {
class CReservedTable : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool PlayerTriesRestaurantTableMsg(CPlayerTriesRestaurantTableMsg *msg);
public:
- int _value1, _value2;
+ bool _flag;
+ int _tableId;
public:
CLASSDEF;
- CReservedTable() : CGameObject(), _value1(0), _value2(0) {}
+ CReservedTable() : CGameObject(), _flag(false), _tableId(0) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/restaurant_cylinder_holder.cpp b/engines/titanic/game/restaurant_cylinder_holder.cpp
index d70009f151..8726d1a925 100644
--- a/engines/titanic/game/restaurant_cylinder_holder.cpp
+++ b/engines/titanic/game/restaurant_cylinder_holder.cpp
@@ -24,20 +24,29 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CRestaurantCylinderHolder, CDropTarget)
+ ON_MESSAGE(EjectCylinderMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(QueryCylinderHolderMsg)
+ ON_MESSAGE(QueryCylinderNameMsg)
+ ON_MESSAGE(MouseDragStartMsg)
+END_MESSAGE_MAP()
+
CRestaurantCylinderHolder::CRestaurantCylinderHolder() : CDropTarget(),
_field118(0), _field11C(0), _field12C(0), _field130(0),
- _string6("z#61.wav"), _field140(1) {
+ _ejectSoundName("z#61.wav"), _defaultCursorId(CURSOR_ARROW) {
}
void CRestaurantCylinderHolder::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_field118, indent);
file->writeNumberLine(_field11C, indent);
- file->writeQuotedLine(_string5, indent);
+ file->writeQuotedLine(_target, indent);
file->writeNumberLine(_field12C, indent);
file->writeNumberLine(_field130, indent);
- file->writeQuotedLine(_string6, indent);
- file->writeNumberLine(_field140, indent);
+ file->writeQuotedLine(_ejectSoundName, indent);
+ file->writeNumberLine(_defaultCursorId, indent);
CDropTarget::save(file, indent);
}
@@ -46,13 +55,98 @@ void CRestaurantCylinderHolder::load(SimpleFile *file) {
file->readNumber();
_field118 = file->readNumber();
_field11C = file->readNumber();
- _string5 = file->readString();
+ _target = file->readString();
_field12C = file->readNumber();
_field130 = file->readNumber();
- _string6 = file->readString();
- _field140 = file->readNumber();
+ _ejectSoundName = file->readString();
+ _defaultCursorId = (CursorId)file->readNumber();
CDropTarget::load(file);
}
+bool CRestaurantCylinderHolder::EjectCylinderMsg(CEjectCylinderMsg *msg) {
+ _field11C = true;
+ bool hasCylinder = findByName("Phonograph Cylinder") != nullptr;
+
+ if (_field118) {
+ playClip(hasCylinder ? "CloseHolder_Full" : "CloseHolder_Empty",
+ MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ _fieldF4 = 1;
+ } else {
+ playClip(hasCylinder ? "OpenHolder_Full" : "OpenHolder_Empty",
+ MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ }
+
+ playSound(_ejectSoundName, 50);
+ return true;
+}
+
+bool CRestaurantCylinderHolder::EnterViewMsg(CEnterViewMsg *msg) {
+ if (_field118) {
+ CTreeItem *cylinder = findByName("Phonograph Cylinder", true);
+ if (cylinder) {
+ loadFrame(_dropFrame);
+ _cursorId = _dropCursorId;
+ } else {
+ loadFrame(_dragFrame);
+ _cursorId = _dragCursorId;
+ }
+ } else {
+ loadFrame(_field130);
+ _cursorId = _defaultCursorId;
+ }
+
+ return true;
+}
+
+bool CRestaurantCylinderHolder::MovieEndMsg(CMovieEndMsg *msg) {
+ _field11C = false;
+ if (_field118) {
+ _field118 = false;
+ _cursorId = _defaultCursorId;
+
+ CPhonographReadyToPlayMsg readyMsg;
+ readyMsg.execute(_target);
+ } else {
+ _field118 = true;
+ _fieldF4 = false;
+ _cursorId = findByName("Phonograph Cylinder") ? _dropCursorId : _dragCursorId;
+ }
+
+ CCylinderHolderReadyMsg holderMsg;
+ holderMsg.execute(_target);
+ return true;
+}
+
+bool CRestaurantCylinderHolder::QueryCylinderHolderMsg(CQueryCylinderHolderMsg *msg) {
+ CNamedItem *cylinder = findByName("Phonograph Cylinder", true);
+
+ msg->_value1 = _field118;
+ if (cylinder) {
+ msg->_value2 = 1;
+ msg->_target = cylinder;
+ }
+
+ return true;
+}
+
+bool CRestaurantCylinderHolder::QueryCylinderNameMsg(CQueryCylinderNameMsg *msg) {
+ CNamedItem *cylinder = findByName("Phonograph Cylinder", true);
+
+ if (cylinder) {
+ CQueryCylinderMsg queryMsg;
+ queryMsg.execute(cylinder);
+ msg->_name = queryMsg._name;
+ }
+
+ return true;
+}
+
+bool CRestaurantCylinderHolder::MouseDragStartMsg(CMouseDragStartMsg *msg) {
+ if (_field118)
+ return CDropTarget::MouseDragStartMsg(msg);
+ else
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/restaurant_cylinder_holder.h b/engines/titanic/game/restaurant_cylinder_holder.h
index 3aa979b0a5..cd0b0783bd 100644
--- a/engines/titanic/game/restaurant_cylinder_holder.h
+++ b/engines/titanic/game/restaurant_cylinder_holder.h
@@ -28,14 +28,21 @@
namespace Titanic {
class CRestaurantCylinderHolder : public CDropTarget {
+ DECLARE_MESSAGE_MAP;
+ bool EjectCylinderMsg(CEjectCylinderMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool QueryCylinderHolderMsg(CQueryCylinderHolderMsg *msg);
+ bool QueryCylinderNameMsg(CQueryCylinderNameMsg *msg);
+ bool MouseDragStartMsg(CMouseDragStartMsg *msg);
private:
int _field118;
int _field11C;
- CString _string5;
+ CString _target;
int _field12C;
int _field130;
- CString _string6;
- int _field140;
+ CString _ejectSoundName;
+ CursorId _defaultCursorId;
public:
CLASSDEF;
CRestaurantCylinderHolder();
diff --git a/engines/titanic/game/restaurant_phonograph.cpp b/engines/titanic/game/restaurant_phonograph.cpp
index 83a4ac3e71..881079e020 100644
--- a/engines/titanic/game/restaurant_phonograph.cpp
+++ b/engines/titanic/game/restaurant_phonograph.cpp
@@ -21,9 +21,20 @@
*/
#include "titanic/game/restaurant_phonograph.h"
+#include "titanic/core/room_item.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CRestaurantPhonograph, CPhonograph)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(PhonographPlayMsg)
+ ON_MESSAGE(PhonographStopMsg)
+ ON_MESSAGE(PhonographReadyToPlayMsg)
+ ON_MESSAGE(EjectCylinderMsg)
+ ON_MESSAGE(QueryPhonographState)
+ ON_MESSAGE(LockPhonographMsg)
+END_MESSAGE_MAP()
+
CRestaurantPhonograph::CRestaurantPhonograph() : CPhonograph(),
_fieldF8(1), _field114(0) {}
@@ -48,4 +59,89 @@ void CRestaurantPhonograph::load(SimpleFile *file) {
CPhonograph::load(file);
}
+bool CRestaurantPhonograph::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (!_fieldF8 && !_fieldE0) {
+ CQueryCylinderHolderMsg holderMsg;
+ holderMsg.execute(this);
+
+ if (!holderMsg._value1) {
+ CPhonographPlayMsg playMsg;
+ playMsg.execute(this);
+ } else if (holderMsg._value2) {
+ CEjectCylinderMsg ejectMsg;
+ ejectMsg.execute(this);
+
+ _fieldE8 = true;
+ if (_field114) {
+ loadFrame(_fieldEC);
+ playSound(_ejectSoundName);
+ }
+ }
+ }
+
+ return true;
+}
+
+bool CRestaurantPhonograph::PhonographPlayMsg(CPhonographPlayMsg *msg) {
+ if (_fieldE0) {
+ if (findView() == getView() && (!_fieldE8 || !_field114)) {
+ loadFrame(_fieldEC);
+ playSound(_ejectSoundName);
+ }
+
+ CQueryCylinderNameMsg nameMsg;
+ nameMsg.execute(this);
+ CRestaurantMusicChanged musicMsg(nameMsg._name);
+ musicMsg.execute(findRoom());
+ } else {
+ loadFrame(_fieldF0);
+ }
+
+ return true;
+}
+
+bool CRestaurantPhonograph::PhonographStopMsg(CPhonographStopMsg *msg) {
+ bool flag = _fieldE0;
+ CPhonograph::PhonographStopMsg(msg);
+
+ if (_fieldE0) {
+ loadFrame(_fieldF0);
+ if (flag)
+ playSound(_string3);
+ } else {
+ loadFrame(_fieldEC);
+ }
+
+ return true;
+}
+
+bool CRestaurantPhonograph::PhonographReadyToPlayMsg(CPhonographReadyToPlayMsg *msg) {
+ if (_fieldE8) {
+ CPhonographPlayMsg playMsg;
+ playMsg.execute(this);
+ _fieldE8 = false;
+ }
+
+ return true;
+}
+
+bool CRestaurantPhonograph::EjectCylinderMsg(CEjectCylinderMsg *msg) {
+ if (_fieldE0) {
+ CPhonographStopMsg stopMsg;
+ stopMsg.execute(this);
+ }
+
+ return true;
+}
+
+bool CRestaurantPhonograph::QueryPhonographState(CQueryPhonographState *msg) {
+ msg->_value = _fieldF8;
+ return true;
+}
+
+bool CRestaurantPhonograph::LockPhonographMsg(CLockPhonographMsg *msg) {
+ _fieldF8 = msg->_value;
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/restaurant_phonograph.h b/engines/titanic/game/restaurant_phonograph.h
index 710a2edd73..9661df0dfb 100644
--- a/engines/titanic/game/restaurant_phonograph.h
+++ b/engines/titanic/game/restaurant_phonograph.h
@@ -28,9 +28,17 @@
namespace Titanic {
class CRestaurantPhonograph : public CPhonograph {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool PhonographPlayMsg(CPhonographPlayMsg *msg);
+ bool PhonographStopMsg(CPhonographStopMsg *msg);
+ bool PhonographReadyToPlayMsg(CPhonographReadyToPlayMsg *msg);
+ bool EjectCylinderMsg(CEjectCylinderMsg *msg);
+ bool QueryPhonographState(CQueryPhonographState *msg);
+ bool LockPhonographMsg(CLockPhonographMsg *msg);
private:
int _fieldF8;
- CString _string2;
+ CString _ejectSoundName;
CString _string3;
int _field114;
public:
diff --git a/engines/titanic/game/sauce_dispensor.cpp b/engines/titanic/game/sauce_dispensor.cpp
index 8dc818d917..29f0be7ee4 100644
--- a/engines/titanic/game/sauce_dispensor.cpp
+++ b/engines/titanic/game/sauce_dispensor.cpp
@@ -21,9 +21,20 @@
*/
#include "titanic/game/sauce_dispensor.h"
+#include "titanic/carry/chicken.h"
+#include "titanic/carry/glass.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CSauceDispensor, CBackground)
+ ON_MESSAGE(Use)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(ActMsg)
+ ON_MESSAGE(LeaveViewMsg)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(StatusChangeMsg)
+END_MESSAGE_MAP()
+
CSauceDispensor::CSauceDispensor() : CBackground(),
_fieldEC(0), _fieldF0(0), _field104(0), _field108(0) {
}
@@ -54,4 +65,105 @@ void CSauceDispensor::load(SimpleFile *file) {
CBackground::load(file);
}
+bool CSauceDispensor::Use(CUse *msg) {
+ CVisibleMsg visibleMsg(true);
+
+ if (msg->_item->isEquals("Chicken")) {
+ CChicken *chicken = static_cast<CChicken *>(msg->_item);
+ _field104 = true;
+ if (_fieldF0) {
+ playSound("b#15.wav", 50);
+
+ if (chicken->_string6 != "None") {
+ petDisplayMessage(1, "This foodstuff is already sufficiently garnished.");
+ msg->execute("Chicken");
+ } else {
+ setVisible(true);
+ if (chicken->_field12C) {
+ playMovie(_pos1.x, _pos1.y, MOVIE_NOTIFY_OBJECT);
+ } else {
+ CActMsg actMsg(_string3);
+ actMsg.execute("Chicken");
+ playMovie(_pos2.x, _pos2.y, MOVIE_NOTIFY_OBJECT);
+ }
+ }
+
+ if (_fieldF0)
+ return true;
+ }
+
+ CMovieEndMsg endMsg(0, 0);
+ endMsg.execute(this);
+ playSound("z#120.wav");
+
+ petDisplayMessage(1, "Sadly, this dispenser is currently empty.");
+ } else if (msg->_item->isEquals("BeerGlass")) {
+ CGlass *glass = static_cast<CGlass *>(msg->_item);
+ _field108 = true;
+
+ if (_field104 || _fieldF0) {
+ petAddToInventory();
+ } else if (glass->_string6 != "None") {
+ visibleMsg.execute("BeerGlass");
+ } else if (_fieldEC) {
+ glass->setPosition(Point(
+ _bounds.left + (_bounds.width() / 2) - (glass->_bounds.width() / 2),
+ 300));
+ setVisible(true);
+
+ CActMsg actMsg(_string3);
+ actMsg.execute("BeerGlass");
+ }
+ }
+
+ return true;
+}
+
+bool CSauceDispensor::MovieEndMsg(CMovieEndMsg *msg) {
+ setVisible(false);
+ _fieldEC = false;
+
+ CActMsg actMsg("GoToPET");
+ if (_field104)
+ actMsg.execute("Chicken");
+ if (_field108)
+ actMsg.execute("BeerGlass");
+
+ _field104 = false;
+ _field108 = false;
+ return true;
+}
+
+bool CSauceDispensor::ActMsg(CActMsg *msg) {
+ if (msg->_action == "StarlingsDead")
+ _fieldF0 = true;
+
+ return true;
+}
+
+bool CSauceDispensor::LeaveViewMsg(CLeaveViewMsg *msg) {
+ setVisible(false);
+ loadFrame(0);
+
+ if (_field108) {
+ CGameObject *glass = findRoomObject("Beerglass");
+ if (glass)
+ glass->petAddToInventory();
+ }
+
+ _field104 = false;
+ _field108 = false;
+ return true;
+}
+
+bool CSauceDispensor::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ petDisplayMessage(1, "Please place food source beneath dispenser for sauce delivery.");
+ return true;
+}
+
+bool CSauceDispensor::StatusChangeMsg(CStatusChangeMsg *msg) {
+ petDisplayMessage(1, "Please place food source beneath dispenser for sauce delivery.");
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/sauce_dispensor.h b/engines/titanic/game/sauce_dispensor.h
index aa177050d5..f8021f368b 100644
--- a/engines/titanic/game/sauce_dispensor.h
+++ b/engines/titanic/game/sauce_dispensor.h
@@ -28,6 +28,13 @@
namespace Titanic {
class CSauceDispensor : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool Use(CUse *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool ActMsg(CActMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool StatusChangeMsg(CStatusChangeMsg *msg);
public:
CString _string3;
int _fieldEC;
diff --git a/engines/titanic/game/search_point.cpp b/engines/titanic/game/search_point.cpp
index f60a3132b7..bbe923267a 100644
--- a/engines/titanic/game/search_point.cpp
+++ b/engines/titanic/game/search_point.cpp
@@ -24,6 +24,10 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CSearchPoint, CGameObject)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
void CSearchPoint::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_value, indent);
@@ -36,4 +40,21 @@ void CSearchPoint::load(SimpleFile *file) {
CGameObject::load(file);
}
+bool CSearchPoint::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (_value > 0) {
+ CGameObject *child = dynamic_cast<CGameObject *>(getFirstChild());
+ if (child) {
+ child->petAddToInventory();
+ CVisibleMsg visibleMsg(true);
+ visibleMsg.execute(child->getName());
+ playSound("z#47.wav");
+ }
+
+ if (--_value == 0)
+ _cursorId = CURSOR_ARROW;
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/search_point.h b/engines/titanic/game/search_point.h
index 3c5639b104..421f272804 100644
--- a/engines/titanic/game/search_point.h
+++ b/engines/titanic/game/search_point.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CSearchPoint : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
public:
int _value;
public:
diff --git a/engines/titanic/game/season_background.cpp b/engines/titanic/game/season_background.cpp
index 1c63f3d892..20ad6aca1d 100644
--- a/engines/titanic/game/season_background.cpp
+++ b/engines/titanic/game/season_background.cpp
@@ -24,28 +24,113 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CSeasonBackground, CBackground)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(ChangeSeasonMsg)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(ActMsg)
+END_MESSAGE_MAP()
+
CSeasonBackground::CSeasonBackground() : CBackground(),
- _fieldE0(0), _fieldE4(0), _fieldE8(46), _fieldEC(0) {
+ _seasonNum(SEASON_SUMMER), _flag(false), _defaultFrame(46), _unused(0) {
}
void CSeasonBackground::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldE0, indent);
- file->writeNumberLine(_fieldE4, indent);
- file->writeNumberLine(_fieldE8, indent);
- file->writeNumberLine(_fieldEC, indent);
+ file->writeNumberLine(_seasonNum, indent);
+ file->writeNumberLine(_flag, indent);
+ file->writeNumberLine(_defaultFrame, indent);
+ file->writeNumberLine(_unused, indent);
CBackground::save(file, indent);
}
void CSeasonBackground::load(SimpleFile *file) {
file->readNumber();
- _fieldE0 = file->readNumber();
- _fieldE4 = file->readNumber();
- _fieldE8 = file->readNumber();
- _fieldEC = file->readNumber();
+ _seasonNum = (Season)file->readNumber();
+ _flag = file->readNumber();
+ _defaultFrame = file->readNumber();
+ _unused = file->readNumber();
CBackground::load(file);
}
+bool CSeasonBackground::EnterViewMsg(CEnterViewMsg *msg) {
+ loadFrame(_defaultFrame);
+ return true;
+}
+
+bool CSeasonBackground::ChangeSeasonMsg(CChangeSeasonMsg *msg) {
+ _seasonNum = (Season)(((int)_seasonNum + 1) % 4);
+
+ switch (_seasonNum) {
+ case SEASON_SUMMER:
+ playMovie(0, 45, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ _defaultFrame = 45;
+ break;
+
+ case SEASON_AUTUMN:
+ if (_flag) {
+ playMovie(232, 278, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ _defaultFrame = 278;
+ } else {
+ playMovie(45, 91, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ _defaultFrame = 91;
+ }
+ break;
+
+ case SEASON_WINTER:
+ if (_flag) {
+ playMovie(278, 326, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ _defaultFrame = 326;
+ } else {
+ CStatusChangeMsg changeMsg;
+ changeMsg._newStatus = 0;
+ changeMsg.execute("PickUpSpeechCentre");
+ playMovie(91, 139, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ _defaultFrame = 139;
+ }
+ break;
+
+ case SEASON_SPRING:
+ if (_flag) {
+ playMovie(326, 417, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ _defaultFrame = 417;
+ } else {
+ playMovie(139, 228, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ _defaultFrame = 228;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool CSeasonBackground::MovieEndMsg(CMovieEndMsg *msg) {
+ if (msg->_endFrame == _defaultFrame) {
+ CTurnOn onMsg;
+ onMsg.execute("SeasonalAdjust");
+ }
+
+ if (msg->_endFrame == 91 && !_flag) {
+ CStatusChangeMsg changeMsg;
+ changeMsg.execute("PickUpSpeechCentre");
+ }
+
+ return true;
+}
+
+bool CSeasonBackground::ActMsg(CActMsg *msg) {
+ if (msg->_action == "PlayerGetsSpeechCentre") {
+ loadFrame(278);
+ _defaultFrame = 278;
+ _flag = true;
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/season_background.h b/engines/titanic/game/season_background.h
index f0fd2cdc63..d30fd7aedc 100644
--- a/engines/titanic/game/season_background.h
+++ b/engines/titanic/game/season_background.h
@@ -28,11 +28,16 @@
namespace Titanic {
class CSeasonBackground : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool ChangeSeasonMsg(CChangeSeasonMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool ActMsg(CActMsg *msg);
public:
- int _fieldE0;
- int _fieldE4;
- int _fieldE8;
- int _fieldEC;
+ Season _seasonNum;
+ bool _flag;
+ int _defaultFrame;
+ int _unused;
public:
CLASSDEF;
CSeasonBackground();
diff --git a/engines/titanic/game/season_barrel.cpp b/engines/titanic/game/season_barrel.cpp
index 9594396885..e08cdf323b 100644
--- a/engines/titanic/game/season_barrel.cpp
+++ b/engines/titanic/game/season_barrel.cpp
@@ -24,19 +24,38 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CSeasonBarrel, CBackground)
+ ON_MESSAGE(ChangeSeasonMsg)
+ ON_MESSAGE(EnterViewMsg)
+END_MESSAGE_MAP()
+
void CSeasonBarrel::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldE0, indent);
- file->writeNumberLine(_fieldE4, indent);
+ file->writeNumberLine(_unused, indent);
+ file->writeNumberLine(_startFrame, indent);
CBackground::save(file, indent);
}
void CSeasonBarrel::load(SimpleFile *file) {
file->readNumber();
- _fieldE0 = file->readNumber();
- _fieldE4 = file->readNumber();
+ _unused = file->readNumber();
+ _startFrame = file->readNumber();
CBackground::load(file);
}
+bool CSeasonBarrel::ChangeSeasonMsg(CChangeSeasonMsg *msg) {
+ if (_startFrame >= 28)
+ _startFrame = 0;
+
+ playMovie(_startFrame, _startFrame + 7, 0);
+ _startFrame += 7;
+ return true;
+}
+
+bool CSeasonBarrel::EnterViewMsg(CEnterViewMsg *msg) {
+ loadFrame(_startFrame);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/season_barrel.h b/engines/titanic/game/season_barrel.h
index f77864599d..6296b6f7b1 100644
--- a/engines/titanic/game/season_barrel.h
+++ b/engines/titanic/game/season_barrel.h
@@ -28,12 +28,15 @@
namespace Titanic {
class CSeasonBarrel : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool ChangeSeasonMsg(CChangeSeasonMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
public:
- int _fieldE0;
- int _fieldE4;
+ int _unused;
+ int _startFrame;
public:
CLASSDEF;
- CSeasonBarrel() : CBackground(), _fieldE0(0), _fieldE4(7) {}
+ CSeasonBarrel() : CBackground(), _unused(0), _startFrame(7) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/seasonal_adjustment.cpp b/engines/titanic/game/seasonal_adjustment.cpp
index 33a0ae89c5..1f1cb88afb 100644
--- a/engines/titanic/game/seasonal_adjustment.cpp
+++ b/engines/titanic/game/seasonal_adjustment.cpp
@@ -21,9 +21,20 @@
*/
#include "titanic/game/seasonal_adjustment.h"
+#include "titanic/core/project_item.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CSeasonalAdjustment, CBackground)
+ ON_MESSAGE(StatusChangeMsg)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(MouseButtonUpMsg)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(TurnOn)
+ ON_MESSAGE(TurnOff)
+ ON_MESSAGE(ActMsg)
+END_MESSAGE_MAP()
+
void CSeasonalAdjustment::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_fieldE0, indent);
@@ -40,4 +51,86 @@ void CSeasonalAdjustment::load(SimpleFile *file) {
CBackground::load(file);
}
+bool CSeasonalAdjustment::StatusChangeMsg(CStatusChangeMsg *msg) {
+ CChangeSeasonMsg changeMsg;
+ switch (stateGetSeason()) {
+ case SEASON_SUMMER:
+ changeMsg._season = "Summer";
+ break;
+ case SEASON_AUTUMN:
+ changeMsg._season = "Autumn";
+ break;
+ case SEASON_WINTER:
+ changeMsg._season = "Winter";
+ break;
+ case SEASON_SPRING:
+ changeMsg._season = "Spring";
+ break;
+ default:
+ break;
+ }
+
+ changeMsg.execute(getRoot(), nullptr, MSGFLAG_SCAN);
+ return true;
+}
+
+bool CSeasonalAdjustment::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ return true;
+}
+
+bool CSeasonalAdjustment::MouseButtonUpMsg(CMouseButtonUpMsg *msg) {
+ playSound("z#42.wav");
+ if (!_fieldE4) {
+ petDisplayMessage(1, "The Seasonal Adjustment switch is not operational at the present time.");
+ } else if (!_fieldE0) {
+ playMovie(0, 6, MOVIE_NOTIFY_OBJECT);
+ playMovie(6, 18, 0);
+ }
+
+ return true;
+}
+
+bool CSeasonalAdjustment::MovieEndMsg(CMovieEndMsg *msg) {
+ if (msg->_endFrame == 6) {
+ stateChangeSeason();
+ CStatusChangeMsg changeMsg;
+ changeMsg.execute(this);
+ CTurnOff offMsg;
+ offMsg.execute(this);
+ offMsg.execute("LeftPanExit");
+ offMsg.execute("RightPanExit");
+ }
+
+ return true;
+}
+
+bool CSeasonalAdjustment::TurnOn(CTurnOn *msg) {
+ if (_fieldE0) {
+ _fieldE0 = false;
+ CTurnOn onMsg;
+ onMsg.execute("LeftPanExit");
+ onMsg.execute("RightPanExit");
+ }
+
+ return true;
+}
+
+bool CSeasonalAdjustment::TurnOff(CTurnOff *msg) {
+ _fieldE0 = true;
+ return true;
+}
+
+bool CSeasonalAdjustment::ActMsg(CActMsg *msg) {
+ if (msg->_action == "PlayerGetsSpeechCentre") {
+ msg->execute("SeasonBackground");
+ msg->execute("ArbGate");
+ } else if (msg->_action == "EnableObject") {
+ _fieldE4 = true;
+ } else if (msg->_action == "DisableObject") {
+ _fieldE4 = false;
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/seasonal_adjustment.h b/engines/titanic/game/seasonal_adjustment.h
index f96c13619d..4b7ef3d4f6 100644
--- a/engines/titanic/game/seasonal_adjustment.h
+++ b/engines/titanic/game/seasonal_adjustment.h
@@ -27,15 +27,16 @@
namespace Titanic {
-enum Season {
- SPRING = 0,
- SUMMER = 1,
- AUTUMN = 2,
- WINTER = 3
-};
-
class CSeasonalAdjustment : public CBackground {
-public:
+ DECLARE_MESSAGE_MAP;
+ bool StatusChangeMsg(CStatusChangeMsg *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool MouseButtonUpMsg(CMouseButtonUpMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool TurnOn(CTurnOn *msg);
+ bool TurnOff(CTurnOff *msg);
+ bool ActMsg(CActMsg *msg);
+private:
int _fieldE0;
int _fieldE4;
public:
diff --git a/engines/titanic/game/service_elevator_window.cpp b/engines/titanic/game/service_elevator_window.cpp
index 95b2735b37..b0cc53abb4 100644
--- a/engines/titanic/game/service_elevator_window.cpp
+++ b/engines/titanic/game/service_elevator_window.cpp
@@ -21,9 +21,19 @@
*/
#include "titanic/game/service_elevator_window.h"
+#include "titanic/core/room_item.h"
+#include "titanic/npcs/doorbot.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CServiceElevatorWindow, CBackground)
+ ON_MESSAGE(ServiceElevatorFloorChangeMsg)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(EnterViewMsg)
+END_MESSAGE_MAP()
+
+static const int FACTORS[4] = { 0, 20, 100, 0 };
+
CServiceElevatorWindow::CServiceElevatorWindow() : CBackground(),
_fieldE0(0), _fieldE4(0), _fieldE8(0), _fieldEC(0) {
}
@@ -48,4 +58,57 @@ void CServiceElevatorWindow::load(SimpleFile *file) {
CBackground::load(file);
}
+bool CServiceElevatorWindow::ServiceElevatorFloorChangeMsg(CServiceElevatorFloorChangeMsg *msg) {
+ if (getView() == findView()) {
+ CDoorbot *doorbot = dynamic_cast<CDoorbot *>(findRoom()->findByName("Doorbot"));
+ int val = (_fieldE8 && doorbot) ? 65 : 15;
+ CMovieClip *clip = _movieClips.findByName("Going Up");
+
+ if (!clip)
+ return true;
+
+ int count = _endFrame - _startFrame;
+ setMovieFrameRate(1.0 * count / val);
+
+ int startFrame = clip->_startFrame + count * FACTORS[msg->_value1] / 100;
+ int endFrame = clip->_startFrame + count * FACTORS[msg->_value2] / 100;
+
+ if (_fieldE4) {
+ playMovie(startFrame, endFrame, MOVIE_NOTIFY_OBJECT);
+ } else {
+ playMovie(startFrame, endFrame, 0);
+ if (_fieldEC)
+ playClip("Into Space");
+ }
+ }
+
+ _fieldE0 = msg->_value2;
+ return true;
+}
+
+bool CServiceElevatorWindow::MovieEndMsg(CMovieEndMsg *msg) {
+ CServiceElevatorMsg elevMsg(5);
+ elevMsg.execute(findRoom()->findByName("Service Elevator Entity"));
+ return true;
+}
+
+bool CServiceElevatorWindow::EnterViewMsg(CEnterViewMsg *msg) {
+ if (_fieldEC) {
+ playClip("Fade Up");
+ playMovie(1, 2, 0);
+ } else {
+ CMovieClip *clip = _movieClips.findByName("Going Up");
+
+ if (clip) {
+ int frameNum = clip->_startFrame + (clip->_endFrame - clip->_startFrame)
+ * FACTORS[_fieldE0] / 100;
+ loadFrame(frameNum);
+ } else {
+ loadFrame(0);
+ }
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/service_elevator_window.h b/engines/titanic/game/service_elevator_window.h
index 4233b8405a..88e1663aba 100644
--- a/engines/titanic/game/service_elevator_window.h
+++ b/engines/titanic/game/service_elevator_window.h
@@ -28,6 +28,10 @@
namespace Titanic {
class CServiceElevatorWindow : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool ServiceElevatorFloorChangeMsg(CServiceElevatorFloorChangeMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
public:
int _fieldE0;
int _fieldE4;
diff --git a/engines/titanic/game/sgt/bedhead.cpp b/engines/titanic/game/sgt/bedhead.cpp
index 6f427ab625..216d22ee71 100644
--- a/engines/titanic/game/sgt/bedhead.cpp
+++ b/engines/titanic/game/sgt/bedhead.cpp
@@ -21,6 +21,7 @@
*/
#include "titanic/game/sgt/bedhead.h"
+#include "titanic/titanic.h"
namespace Titanic {
@@ -29,6 +30,52 @@ BEGIN_MESSAGE_MAP(CBedhead, CSGTStateRoom)
ON_MESSAGE(TurnOff)
END_MESSAGE_MAP()
+void BedheadEntry::load(Common::SeekableReadStream *s) {
+ _name1 = readStringFromStream(s);
+ _name2 = readStringFromStream(s);
+ _name3 = readStringFromStream(s);
+ _name4 = readStringFromStream(s);
+ _startFrame = s->readUint32LE();
+ _endFrame = s->readUint32LE();
+}
+
+/*------------------------------------------------------------------------*/
+
+void BedheadEntries::load(Common::SeekableReadStream *s, int count) {
+ resize(count);
+ for (int idx = 0; idx < count; ++idx)
+ (*this)[idx].load(s);
+}
+
+/*------------------------------------------------------------------------*/
+
+void TurnOnEntries::load(Common::SeekableReadStream *s) {
+ _closed.load(s, 4);
+ _restingTV.load(s, 2);
+ _restingUV.load(s, 2);
+ _closedWrong.load(s, 2);
+}
+
+/*------------------------------------------------------------------------*/
+
+void TurnOffEntries::load(Common::SeekableReadStream *s) {
+ _open.load(s, 3);
+ _restingUTV.load(s, 1);
+ _restingV.load(s, 1);
+ _restingG.load(s, 3);
+ _openWrong.load(s, 1);
+ _restingDWrong.load(s, 1);
+}
+
+/*------------------------------------------------------------------------*/
+
+CBedhead::CBedhead() : CSGTStateRoom() {
+ Common::SeekableReadStream *s = g_vm->_filesManager->getResource("DATA/BEDHEAD");
+ _on.load(s);
+ _off.load(s);
+ delete s;
+}
+
void CBedhead::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CSGTStateRoom::save(file, indent);
@@ -40,12 +87,83 @@ void CBedhead::load(SimpleFile *file) {
}
bool CBedhead::TurnOn(CTurnOn *msg) {
- // TODO
+ if (_statics->_v2 == "Closed" || _statics->_v2 == "RestingUnderTV")
+ return true;
+
+ const BedheadEntries *data = nullptr;
+ if (_statics->_v1 == "Closed")
+ data = &_on._closed;
+ else if (_statics->_v1 == "RestingTV")
+ data = &_on._restingTV;
+ else if (_statics->_v1 == "RestingUV")
+ data = &_on._restingUV;
+ else if (_statics->_v1 == "ClosedWrong")
+ data = &_on._closedWrong;
+ else
+ return true;
+
+ for (uint idx = 0; idx < data->size(); ++idx) {
+ const BedheadEntry &entry = (*data)[idx];
+ if ((entry._name1 == _statics->_v4 || entry._name1 == "Any")
+ && (entry._name2 == _statics->_v3 || entry._name2 == "Any")
+ && (entry._name3 == _statics->_v5 || entry._name3 == "Any")) {
+ CVisibleMsg visibleMsg(false);
+ visibleMsg.execute("Bedfoot");
+ setVisible(true);
+
+ _statics->_v1 = entry._name4;
+ playMovie(entry._startFrame, entry._endFrame, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ playSound("b#6.wav");
+ _fieldE0 = false;
+ }
+ }
+
+ if (_statics->_v1 == "Open") {
+ playMovie(71, 78, 0);
+ playSound("196_436 bed inflate 2.wav");
+ }
+
return true;
}
bool CBedhead::TurnOff(CTurnOff *msg) {
- // TODO
+ if (_statics->_v1 == "Open") {
+ playMovie(78, 85, 0);
+ playSound("191_436_bed inflate deflate.wav");
+ }
+
+ BedheadEntries *data = nullptr;
+ if (_statics->_v1 == "Open")
+ data = &_off._open;
+ else if (_statics->_v1 == "RestingUTV")
+ data = &_off._restingUTV;
+ else if (_statics->_v1 == "RestingV")
+ data = &_off._restingV;
+ else if (_statics->_v1 == "RestingG")
+ data = &_off._restingG;
+ else if (_statics->_v1 == "OpenWrong")
+ data = &_off._openWrong;
+ else if (_statics->_v1 == "RestingDWrong")
+ data = &_off._restingDWrong;
+ else
+ return true;
+
+ for (uint idx = 0; idx < data->size(); ++idx) {
+ const BedheadEntry &entry = (*data)[idx];
+ if ((entry._name1 == _statics->_v4 || entry._name1 == "Any")
+ && (entry._name2 == _statics->_v3 || entry._name2 == "Any")
+ && (entry._name3 == _statics->_v5 || entry._name3 == "Any")) {
+ CVisibleMsg visibleMsg(false);
+ visibleMsg.execute("Bedfoot");
+ setVisible(true);
+
+ _statics->_v1 = entry._name4;
+ playMovie(entry._startFrame, entry._endFrame, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ playSound("193_436_bed fold up 1.wav");
+ _fieldE0 = false;
+ }
+ }
+
return true;
}
diff --git a/engines/titanic/game/sgt/bedhead.h b/engines/titanic/game/sgt/bedhead.h
index 665dec021c..7784cb8caf 100644
--- a/engines/titanic/game/sgt/bedhead.h
+++ b/engines/titanic/game/sgt/bedhead.h
@@ -23,16 +23,56 @@
#ifndef TITANIC_BEDHEAD_H
#define TITANIC_BEDHEAD_H
+#include "common/array.h"
#include "titanic/game/sgt/sgt_state_room.h"
namespace Titanic {
+struct BedheadEntry {
+ CString _name1;
+ CString _name2;
+ CString _name3;
+ CString _name4;
+ int _startFrame;
+ int _endFrame;
+
+ void load(Common::SeekableReadStream *s);
+};
+class BedheadEntries : public Common::Array<BedheadEntry> {
+public:
+ void load(Common::SeekableReadStream *s, int count);
+};
+
+struct TurnOnEntries {
+ BedheadEntries _closed;
+ BedheadEntries _restingTV;
+ BedheadEntries _restingUV;
+ BedheadEntries _closedWrong;
+
+ void load(Common::SeekableReadStream *s);
+};
+
+struct TurnOffEntries {
+ BedheadEntries _open;
+ BedheadEntries _restingUTV;
+ BedheadEntries _restingV;
+ BedheadEntries _restingG;
+ BedheadEntries _openWrong;
+ BedheadEntries _restingDWrong;
+
+ void load(Common::SeekableReadStream *s);
+};
+
class CBedhead : public CSGTStateRoom {
DECLARE_MESSAGE_MAP;
bool TurnOn(CTurnOn *msg);
bool TurnOff(CTurnOff *msg);
+private:
+ TurnOnEntries _on;
+ TurnOffEntries _off;
public:
CLASSDEF;
+ CBedhead();
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/sgt/sgt_doors.cpp b/engines/titanic/game/sgt/sgt_doors.cpp
index 516b0f1351..71eae9800c 100644
--- a/engines/titanic/game/sgt/sgt_doors.cpp
+++ b/engines/titanic/game/sgt/sgt_doors.cpp
@@ -21,13 +21,21 @@
*/
#include "titanic/game/sgt/sgt_doors.h"
+#include "titanic/pet_control/pet_control.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CSGTDoors, CGameObject)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(LeaveViewMsg)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(LeaveRoomMsg)
+END_MESSAGE_MAP()
+
void CSGTDoors::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_value1, indent);
- file->writeNumberLine(_value2, indent);
+ file->writeNumberLine(_open, indent);
CGameObject::save(file, indent);
}
@@ -35,9 +43,58 @@ void CSGTDoors::save(SimpleFile *file, int indent) {
void CSGTDoors::load(SimpleFile *file) {
file->readNumber();
_value1 = file->readNumber();
- _value2 = file->readNumber();
+ _open = file->readNumber();
CGameObject::load(file);
}
+bool CSGTDoors::EnterViewMsg(CEnterViewMsg *msg) {
+ setVisible(true);
+ _open = true;
+ CPetControl *pet = getPetControl();
+
+ if (pet) {
+ int roomNum = pet->getRoomsRoomNum();
+ static const int START_FRAMES[7] = { 0, 26, 30, 34, 38, 42, 46 };
+ static const int END_FRAMES[7] = { 12, 29, 33, 37, 41, 45, 49 };
+
+ if (pet->getRooms1CC() == 1)
+ playMovie(START_FRAMES[roomNum], END_FRAMES[roomNum],
+ MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ else
+ playMovie(0, 12, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ }
+
+ return true;
+}
+
+bool CSGTDoors::LeaveViewMsg(CLeaveViewMsg *msg) {
+ return true;
+}
+
+bool CSGTDoors::MovieEndMsg(CMovieEndMsg *msg) {
+ setVisible(!_open);
+ return true;
+}
+
+bool CSGTDoors::LeaveRoomMsg(CLeaveRoomMsg *msg) {
+ setVisible(true);
+ _open = false;
+ CPetControl *pet = getPetControl();
+
+ if (pet) {
+ int roomNum = pet->getRoomsRoomNum();
+ static const int START_FRAMES[7] = { 12, 69, 65, 61, 57, 53, 49 };
+ static const int END_FRAMES[7] = { 25, 72, 68, 64, 60, 56, 52 };
+
+ if (pet->getRooms1CC() == 1)
+ playMovie(START_FRAMES[roomNum], END_FRAMES[roomNum],
+ MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ else
+ playMovie(12, 25, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/sgt/sgt_doors.h b/engines/titanic/game/sgt/sgt_doors.h
index 4b4f4a3153..b19c5860af 100644
--- a/engines/titanic/game/sgt/sgt_doors.h
+++ b/engines/titanic/game/sgt/sgt_doors.h
@@ -28,11 +28,17 @@
namespace Titanic {
class CSGTDoors : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool LeaveRoomMsg(CLeaveRoomMsg *msg);
public:
- int _value1, _value2;
+ int _value1;
+ bool _open;
public:
CLASSDEF;
- CSGTDoors() : CGameObject(), _value1(0), _value2(0) {}
+ CSGTDoors() : CGameObject(), _value1(0), _open(false) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/sgt/sgt_nav.cpp b/engines/titanic/game/sgt/sgt_nav.cpp
index f98e486fd0..c004f947d2 100644
--- a/engines/titanic/game/sgt/sgt_nav.cpp
+++ b/engines/titanic/game/sgt/sgt_nav.cpp
@@ -24,6 +24,11 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(SGTNav, CSGTStateRoom)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(MouseMoveMsg)
+END_MESSAGE_MAP()
+
void SGTNav::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CSGTStateRoom::save(file, indent);
@@ -34,4 +39,43 @@ void SGTNav::load(SimpleFile *file) {
CSGTStateRoom::load(file);
}
+bool SGTNav::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ CTurnOn onMsg;
+ CTurnOff offMsg;
+
+ if (_statics->_v6 == "Open" && _statics->_v1 == "Open") {
+ if (_statics->_v3 == "Open")
+ offMsg.execute("Vase");
+ if (_statics->_v4 == "Closed")
+ onMsg.execute("SGTTV");
+ if (_statics->_v7 == "Open")
+ offMsg.execute("Drawer");
+ if (_statics->_v8 == "Open")
+ offMsg.execute("Armchair");
+ if (_statics->_v9 == "Open")
+ offMsg.execute("Deskchair");
+ if (_statics->_v12 == "Open")
+ offMsg.execute("Toilet");
+
+ changeView("SGTState.Node 2.E");
+ } else if (_statics->_v1 == "Open") {
+ petDisplayMessage(1, "This is your stateroom. It is for sleeping. If you desire "
+ "entertainment or relaxation, please visit your local leisure lounge.");
+ } else if (_statics->_v6 == "Closed") {
+ petDisplayMessage(1, "The bed will not currently support your weight."
+ " We are working on this problem but are unlikely to be able to fix it.");
+ }
+
+ return true;
+}
+
+bool SGTNav::MouseMoveMsg(CMouseMoveMsg *msg) {
+ if (_statics->_v6 == "Open" && _statics->_v1 == "Open")
+ _cursorId = CURSOR_MOVE_FORWARD;
+ else
+ _cursorId = CURSOR_ARROW;
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/sgt/sgt_nav.h b/engines/titanic/game/sgt/sgt_nav.h
index 40fdc4eff1..78f6417229 100644
--- a/engines/titanic/game/sgt/sgt_nav.h
+++ b/engines/titanic/game/sgt/sgt_nav.h
@@ -28,6 +28,9 @@
namespace Titanic {
class SGTNav : public CSGTStateRoom {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool MouseMoveMsg(CMouseMoveMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/sgt/sgt_navigation.cpp b/engines/titanic/game/sgt/sgt_navigation.cpp
index 7bb64f934d..031226226f 100644
--- a/engines/titanic/game/sgt/sgt_navigation.cpp
+++ b/engines/titanic/game/sgt/sgt_navigation.cpp
@@ -21,9 +21,16 @@
*/
#include "titanic/game/sgt/sgt_navigation.h"
+#include "titanic/pet_control/pet_control.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CSGTNavigation, CGameObject)
+ ON_MESSAGE(StatusChangeMsg)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(EnterViewMsg)
+END_MESSAGE_MAP()
+
CSGTNavigationStatics *CSGTNavigation::_statics;
void CSGTNavigation::init() {
@@ -36,7 +43,7 @@ void CSGTNavigation::deinit() {
void CSGTNavigation::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_statics->_changeViewFlag, indent);
+ file->writeNumberLine(_statics->_changeViewNum, indent);
file->writeQuotedLine(_statics->_destView, indent);
file->writeQuotedLine(_statics->_destRoom, indent);
@@ -45,11 +52,79 @@ void CSGTNavigation::save(SimpleFile *file, int indent) {
void CSGTNavigation::load(SimpleFile *file) {
file->readNumber();
- _statics->_changeViewFlag = file->readNumber();
+ _statics->_changeViewNum = file->readNumber();
_statics->_destView = file->readString();
_statics->_destRoom = file->readString();
CGameObject::load(file);
}
+bool CSGTNavigation::StatusChangeMsg(CStatusChangeMsg *msg) {
+ CPetControl *pet = getPetControl();
+
+ if (isEquals("SGTLL")) {
+ static const int FRAMES[7] = { 0, 149, 112, 74, 0, 36, 74 };
+ _statics->_changeViewNum = msg->_newStatus;
+ if (pet->getRooms1CC() != _statics->_changeViewNum) {
+ changeView("SGTLittleLift.Node 1.N");
+ }
+
+ int startVal = pet->getRooms1CC();
+ if (startVal > _statics->_changeViewNum)
+ playMovie(FRAMES[startVal], FRAMES[_statics->_changeViewNum], MOVIE_GAMESTATE);
+ else
+ playMovie(FRAMES[startVal + 3], FRAMES[_statics->_changeViewNum + 3], MOVIE_GAMESTATE);
+
+ _cursorId = _statics->_changeViewNum != 1 ? CURSOR_MOVE_FORWARD : CURSOR_INVALID;
+
+ pet->setRooms1CC(_statics->_changeViewNum);
+ pet->resetRoomsHighlight();
+ }
+
+ return true;
+}
+
+bool CSGTNavigation::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (compareRoomNameTo("SgtLobby")) {
+ _statics->_destView = getRoomNodeName();
+ _statics->_destRoom = "SgtLobby";
+ changeView("SGTState.Node 1.S");
+ } else if (compareRoomNameTo("SGTLittleLift")) {
+ if (_statics->_changeViewNum != 1) {
+ _statics->_destRoom = "SGTLittleLift";
+ changeView("SGTState.Node 1.S");
+ }
+ } else if (compareRoomNameTo("SGTState")) {
+ if (_statics->_destRoom == "SgtLobby") {
+ if (compareViewNameTo("SGTState.Node 2.N")) {
+ changeView("SGTState.Node 1.N");
+ _statics->_destView += ".S";
+ } else {
+ _statics->_destView += ".N";
+ }
+
+ changeView(_statics->_destView);
+ } else if (_statics->_destRoom == "SGTLittleLift") {
+ if (compareViewNameTo("SGTState.Node 1.S")) {
+ changeView("SGTLittleLift.Node 1.N");
+ } else {
+ changeView("SGTState.Node 1.N");
+ changeView("SGTLittleLift.Node 1.S");
+ }
+ }
+ }
+
+ return true;
+}
+
+bool CSGTNavigation::EnterViewMsg(CEnterViewMsg *msg) {
+ if (isEquals("SGTLL")) {
+ static const int FRAMES[3] = { 0, 36, 74 };
+ CPetControl *pet = getPetControl();
+ loadFrame(FRAMES[pet->getRooms1CC() - 1]);
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/sgt/sgt_navigation.h b/engines/titanic/game/sgt/sgt_navigation.h
index ed58d918e9..69ecd1267a 100644
--- a/engines/titanic/game/sgt/sgt_navigation.h
+++ b/engines/titanic/game/sgt/sgt_navigation.h
@@ -28,12 +28,16 @@
namespace Titanic {
struct CSGTNavigationStatics {
- bool _changeViewFlag;
+ int _changeViewNum;
CString _destView;
CString _destRoom;
};
class CSGTNavigation : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool StatusChangeMsg(CStatusChangeMsg *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
protected:
static CSGTNavigationStatics *_statics;
public:
diff --git a/engines/titanic/game/sgt/sgt_restaurant_doors.cpp b/engines/titanic/game/sgt/sgt_restaurant_doors.cpp
index 74a71e75b2..5c36ceb0ff 100644
--- a/engines/titanic/game/sgt/sgt_restaurant_doors.cpp
+++ b/engines/titanic/game/sgt/sgt_restaurant_doors.cpp
@@ -24,6 +24,10 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CSGTRestaurantDoors, CGameObject)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
void CSGTRestaurantDoors::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_fieldBC, indent);
@@ -36,4 +40,10 @@ void CSGTRestaurantDoors::load(SimpleFile *file) {
CGameObject::load(file);
}
+bool CSGTRestaurantDoors::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ CTurnOff offMsg;
+ offMsg.execute("ChickenDispenser");
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/sgt/sgt_restaurant_doors.h b/engines/titanic/game/sgt/sgt_restaurant_doors.h
index 2a10d8f059..bcaaa71014 100644
--- a/engines/titanic/game/sgt/sgt_restaurant_doors.h
+++ b/engines/titanic/game/sgt/sgt_restaurant_doors.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CSGTRestaurantDoors : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
private:
int _fieldBC;
public:
diff --git a/engines/titanic/game/sgt/sgt_state_control.cpp b/engines/titanic/game/sgt/sgt_state_control.cpp
index 07c1f5efc0..9617f2f127 100644
--- a/engines/titanic/game/sgt/sgt_state_control.cpp
+++ b/engines/titanic/game/sgt/sgt_state_control.cpp
@@ -24,16 +24,59 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CSGTStateControl, CBackground)
+ ON_MESSAGE(PETUpMsg)
+ ON_MESSAGE(PETDownMsg)
+ ON_MESSAGE(PETActivateMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(LeaveViewMsg)
+END_MESSAGE_MAP()
+
void CSGTStateControl::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldE0, indent);
+ file->writeNumberLine(_state, indent);
CBackground::save(file, indent);
}
void CSGTStateControl::load(SimpleFile *file) {
file->readNumber();
- _fieldE0 = file->readNumber();
+ _state = file->readNumber();
CBackground::load(file);
}
+bool CSGTStateControl::PETUpMsg(CPETUpMsg *msg) {
+ // WORKAROUND: Redundant code in original not included
+ return true;
+}
+
+bool CSGTStateControl::PETDownMsg(CPETDownMsg *msg) {
+ // WORKAROUND: Redundant code in original not included
+ return true;
+}
+
+bool CSGTStateControl::PETActivateMsg(CPETActivateMsg *msg) {
+ if (msg->_name == "SGTSelector") {
+ static const char *const TARGETS[] = {
+ "Vase", "Bedfoot", "Toilet", "Drawer", "SGTTV", "Armchair", "BedHead",
+ "WashStand", "Desk", "DeskChair", "Basin", "ChestOfDrawers"
+ };
+ _state = msg->_numValue;
+ CActMsg actMsg;
+ actMsg.execute(TARGETS[_state]);
+ }
+
+ return true;
+}
+
+bool CSGTStateControl::EnterViewMsg(CEnterViewMsg *msg) {
+ _state = 1;
+ petSetRemoteTarget();
+ return true;
+}
+
+bool CSGTStateControl::LeaveViewMsg(CLeaveViewMsg *msg) {
+ petClear();
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/sgt/sgt_state_control.h b/engines/titanic/game/sgt/sgt_state_control.h
index 49fd5113cd..6f96359761 100644
--- a/engines/titanic/game/sgt/sgt_state_control.h
+++ b/engines/titanic/game/sgt/sgt_state_control.h
@@ -24,15 +24,22 @@
#define TITANIC_SGT_STATE_CONTROL_H
#include "titanic/core/background.h"
+#include "titanic/messages/pet_messages.h"
namespace Titanic {
class CSGTStateControl : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool PETUpMsg(CPETUpMsg *msg);
+ bool PETDownMsg(CPETDownMsg *msg);
+ bool PETActivateMsg(CPETActivateMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
private:
- int _fieldE0;
+ int _state;
public:
CLASSDEF;
- CSGTStateControl() : CBackground(), _fieldE0(1) {}
+ CSGTStateControl() : CBackground(), _state(1) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/sgt/sgt_tv.cpp b/engines/titanic/game/sgt/sgt_tv.cpp
index ae4c59e2f9..08ed381b2b 100644
--- a/engines/titanic/game/sgt/sgt_tv.cpp
+++ b/engines/titanic/game/sgt/sgt_tv.cpp
@@ -24,6 +24,12 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CSGTTV, CSGTStateRoom)
+ ON_MESSAGE(TurnOff)
+ ON_MESSAGE(TurnOn)
+ ON_MESSAGE(MovieEndMsg)
+END_MESSAGE_MAP()
+
void CSGTTV::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CSGTStateRoom::save(file, indent);
@@ -34,4 +40,35 @@ void CSGTTV::load(SimpleFile *file) {
CSGTStateRoom::load(file);
}
+bool CSGTTV::TurnOff(CTurnOff *msg) {
+ if (CSGTStateRoom::_statics->_v4 == "Open") {
+ CSGTStateRoom::_statics->_v4 = "Closed";
+ _fieldE0 = true;
+ _startFrame = 6;
+ _endFrame = 12;
+ playMovie(6, 12, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ }
+
+ return true;
+}
+
+bool CSGTTV::TurnOn(CTurnOn *msg) {
+ if (CSGTStateRoom::_statics->_v4 == "Closed" &&
+ CSGTStateRoom::_statics->_v2 == "Closed") {
+ CSGTStateRoom::_statics->_v4 = "Open";
+ setVisible(true);
+ _fieldE0 = false;
+ _startFrame = 1;
+ _endFrame = 6;
+ playMovie(1, 6, MOVIE_GAMESTATE);
+ }
+
+ return true;
+}
+
+bool CSGTTV::MovieEndMsg(CMovieEndMsg *msg) {
+ setVisible(false);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/sgt/sgt_tv.h b/engines/titanic/game/sgt/sgt_tv.h
index 90fed90efe..e5de38e84b 100644
--- a/engines/titanic/game/sgt/sgt_tv.h
+++ b/engines/titanic/game/sgt/sgt_tv.h
@@ -28,6 +28,10 @@
namespace Titanic {
class CSGTTV : public CSGTStateRoom {
+ DECLARE_MESSAGE_MAP;
+ bool TurnOff(CTurnOff *msg);
+ bool TurnOn(CTurnOn *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/sgt/toilet.cpp b/engines/titanic/game/sgt/toilet.cpp
index 799abd6c76..b8e87b645a 100644
--- a/engines/titanic/game/sgt/toilet.cpp
+++ b/engines/titanic/game/sgt/toilet.cpp
@@ -24,6 +24,12 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CToilet, CSGTStateRoom)
+ ON_MESSAGE(TurnOn)
+ ON_MESSAGE(TurnOff)
+ ON_MESSAGE(MovieEndMsg)
+END_MESSAGE_MAP()
+
void CToilet::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CSGTStateRoom::save(file, indent);
@@ -34,4 +40,42 @@ void CToilet::load(SimpleFile *file) {
CSGTStateRoom::load(file);
}
+bool CToilet::TurnOn(CTurnOn *msg) {
+ if (CSGTStateRoom::_statics->_v12 == "Closed"
+ && CSGTStateRoom::_statics->_v10 == "Open"
+ && CSGTStateRoom::_statics->_v8 == "Closed") {
+ setVisible(true);
+ CSGTStateRoom::_statics->_v12 = "Open";
+
+ _fieldE0 = false;
+ _startFrame = 0;
+ _endFrame = 11;
+ playMovie(0, 11, MOVIE_GAMESTATE);
+ playSound("b#1.wav");
+ }
+
+ return true;
+}
+
+bool CToilet::TurnOff(CTurnOff *msg) {
+ if (CSGTStateRoom::_statics->_v12 == "Open") {
+ CSGTStateRoom::_statics->_v12 = "Closed";
+
+ _fieldE0 = true;
+ _startFrame = 11;
+ _endFrame = 18;
+ playMovie(11, 18, MOVIE_GAMESTATE);
+ playSound("b#1.wav");
+ }
+
+ return true;
+}
+
+bool CToilet::MovieEndMsg(CMovieEndMsg *msg) {
+ if (CSGTStateRoom::_statics->_v12 == "Closed")
+ setVisible(false);
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/sgt/toilet.h b/engines/titanic/game/sgt/toilet.h
index d87531ad7a..a4bc318fb2 100644
--- a/engines/titanic/game/sgt/toilet.h
+++ b/engines/titanic/game/sgt/toilet.h
@@ -28,6 +28,10 @@
namespace Titanic {
class CToilet : public CSGTStateRoom {
+ DECLARE_MESSAGE_MAP;
+ bool TurnOn(CTurnOn *msg);
+ bool TurnOff(CTurnOff *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/sgt/vase.cpp b/engines/titanic/game/sgt/vase.cpp
index 3e04b5db9e..2d37818340 100644
--- a/engines/titanic/game/sgt/vase.cpp
+++ b/engines/titanic/game/sgt/vase.cpp
@@ -24,6 +24,12 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CVase, CSGTStateRoom)
+ ON_MESSAGE(TurnOn)
+ ON_MESSAGE(TurnOff)
+ ON_MESSAGE(MovieEndMsg)
+END_MESSAGE_MAP()
+
void CVase::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CSGTStateRoom::save(file, indent);
@@ -34,4 +40,38 @@ void CVase::load(SimpleFile *file) {
CSGTStateRoom::load(file);
}
+bool CVase::TurnOn(CTurnOn *msg) {
+ if (CSGTStateRoom::_statics->_v3 == "Closed") {
+ CSGTStateRoom::_statics->_v3 = "Open";
+ setVisible(true);
+ _fieldE0 = false;
+ _startFrame = 1;
+ _endFrame = 12;
+ playMovie(1, 12, MOVIE_GAMESTATE);
+ }
+
+ return true;
+}
+
+bool CVase::TurnOff(CTurnOff *msg) {
+ if (CSGTStateRoom::_statics->_v3 == "Open"
+ && CSGTStateRoom::_statics->_v1 != "RestingV"
+ && CSGTStateRoom::_statics->_v1 != "RestingUV") {
+ CSGTStateRoom::_statics->_v3 = "Closed";
+ _fieldE0 = true;
+ _startFrame = 12;
+ _endFrame = 25;
+ playMovie(12, 25, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ }
+
+ return true;
+}
+
+bool CVase::MovieEndMsg(CMovieEndMsg *msg) {
+ if (CSGTStateRoom::_statics->_v3 == "Closed")
+ setVisible(false);
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/sgt/vase.h b/engines/titanic/game/sgt/vase.h
index 8aa35acdf5..e07d9efb80 100644
--- a/engines/titanic/game/sgt/vase.h
+++ b/engines/titanic/game/sgt/vase.h
@@ -28,6 +28,10 @@
namespace Titanic {
class CVase : public CSGTStateRoom {
+ DECLARE_MESSAGE_MAP;
+ bool TurnOn(CTurnOn *msg);
+ bool TurnOff(CTurnOff *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/sgt/washstand.cpp b/engines/titanic/game/sgt/washstand.cpp
index 8127a59a59..afdc74414d 100644
--- a/engines/titanic/game/sgt/washstand.cpp
+++ b/engines/titanic/game/sgt/washstand.cpp
@@ -24,6 +24,12 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CWashstand, CSGTStateRoom)
+ ON_MESSAGE(TurnOn)
+ ON_MESSAGE(TurnOff)
+ ON_MESSAGE(MovieEndMsg)
+END_MESSAGE_MAP()
+
void CWashstand::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CSGTStateRoom::save(file, indent);
@@ -34,4 +40,36 @@ void CWashstand::load(SimpleFile *file) {
CSGTStateRoom::load(file);
}
+bool CWashstand::TurnOn(CTurnOn *msg) {
+ if (_statics->_v10 == "Closed" && _statics->_v2 == "NotOnWashstand") {
+ setVisible(true);
+ _statics->_v10 = "Open";
+ _fieldE0 = false;
+ _startFrame = 0;
+ _endFrame = 14;
+ playMovie(0, 14, MOVIE_GAMESTATE);
+ playSound("b#14.wav");
+ }
+
+ return true;
+}
+
+bool CWashstand::TurnOff(CTurnOff *msg) {
+ if (_statics->_v10 == "Open" && _statics->_v11 == "Closed"
+ && _statics->_v12 == "Closed" && _statics->_v2 == "Open") {
+ _statics->_v10 = "Closed";
+ _fieldE0 = true;
+ _startFrame = 14;
+ _endFrame = 28;
+ playMovie(14, 28, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
+ playSound("b#14.wav");
+ }
+
+ return true;
+}
+
+bool CWashstand::MovieEndMsg(CMovieEndMsg *msg) {
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/sgt/washstand.h b/engines/titanic/game/sgt/washstand.h
index f140b17f49..1b72cfa1c4 100644
--- a/engines/titanic/game/sgt/washstand.h
+++ b/engines/titanic/game/sgt/washstand.h
@@ -28,6 +28,10 @@
namespace Titanic {
class CWashstand : public CSGTStateRoom {
+ DECLARE_MESSAGE_MAP;
+ bool TurnOn(CTurnOn *msg);
+ bool TurnOff(CTurnOff *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/ship_setting.cpp b/engines/titanic/game/ship_setting.cpp
index 462f396501..93800e899b 100644
--- a/engines/titanic/game/ship_setting.cpp
+++ b/engines/titanic/game/ship_setting.cpp
@@ -21,35 +21,109 @@
*/
#include "titanic/game/ship_setting.h"
+#include "titanic/core/project_item.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CShipSetting, CBackground)
+ ON_MESSAGE(AddHeadPieceMsg)
+ ON_MESSAGE(SetFrameMsg)
+ ON_MESSAGE(EnterRoomMsg)
+ ON_MESSAGE(MouseDragStartMsg)
+END_MESSAGE_MAP()
+
CShipSetting::CShipSetting() : CBackground(),
- _string4("NULL"), _string5("NULL") {
+ _itemName("NULL"), _frameTarget("NULL") {
}
void CShipSetting::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeQuotedLine(_string3, indent);
+ file->writeQuotedLine(_target, indent);
file->writePoint(_pos1, indent);
- file->writeQuotedLine(_string4, indent);
- file->writeQuotedLine(_string5, indent);
+ file->writeQuotedLine(_itemName, indent);
+ file->writeQuotedLine(_frameTarget, indent);
CBackground::save(file, indent);
}
void CShipSetting::load(SimpleFile *file) {
file->readNumber();
- _string3 = file->readString();
+ _target = file->readString();
_pos1 = file->readPoint();
- _string4 = file->readString();
- _string5 = file->readString();
+ _itemName = file->readString();
+ _frameTarget = file->readString();
CBackground::load(file);
}
+bool CShipSetting::AddHeadPieceMsg(CAddHeadPieceMsg *msg) {
+ _cursorId = CURSOR_HAND;
+
+ if (msg->_value == "Enable") {
+ CTurnOn onMsg;
+ onMsg.execute(_target);
+
+ if (isEquals("ChickenSetting")) {
+ CActMsg actMsg("DecreaseQuantity");
+ actMsg.execute("ChickenDispenser");
+ }
+ } else {
+ CTurnOff offMsg;
+ offMsg.execute(_target);
+ }
+
+ return true;
+}
+
+bool CShipSetting::SetFrameMsg(CSetFrameMsg *msg) {
+ msg->execute(_frameTarget);
+ return true;
+}
+
bool CShipSetting::EnterRoomMsg(CEnterRoomMsg *msg) {
- warning("CShipSetting::handleEvent");
+ CSetFrameMsg frameMsg;
+
+ if (_itemName == "ChickenBridge")
+ frameMsg._frameNumber = 1;
+ else if (_itemName == "FanBridge")
+ frameMsg._frameNumber = 2;
+ else if (_itemName == "SeasonBridge")
+ frameMsg._frameNumber = 3;
+ else if (_itemName == "BeamBridge")
+ frameMsg._frameNumber = 4;
+
+ frameMsg.execute(this);
+ return true;
+}
+
+bool CShipSetting::MouseDragStartMsg(CMouseDragStartMsg *msg) {
+ if (!checkStartDragging(msg))
+ return false;
+ if (_itemName == "NULL")
+ return true;
+
+ CTurnOff offMsg;
+ offMsg.execute(_target);
+
+ if (isEquals("ChickenSetting") || _itemName == "ChickenBridge") {
+ CActMsg actMsg("IncreaseQuantity");
+ actMsg.execute("ChickenDispenser");
+ }
+
+ if (_itemName != "NULL") {
+ CPassOnDragStartMsg passMsg(msg->_mousePos, 1);
+ passMsg.execute(_itemName);
+
+ msg->_dragItem = getRoot()->findByName(_itemName);
+
+ CVisibleMsg visibleMsg(true);
+ visibleMsg.execute(_itemName);
+ }
+
+ CSetFrameMsg frameMsg(0);
+ frameMsg.execute(_frameTarget);
+ _itemName = "NULL";
+ _cursorId = CURSOR_ARROW;
return true;
}
diff --git a/engines/titanic/game/ship_setting.h b/engines/titanic/game/ship_setting.h
index 4fcc10a424..198d97d250 100644
--- a/engines/titanic/game/ship_setting.h
+++ b/engines/titanic/game/ship_setting.h
@@ -29,12 +29,16 @@
namespace Titanic {
class CShipSetting : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool AddHeadPieceMsg(CAddHeadPieceMsg *msg);
+ bool SetFrameMsg(CSetFrameMsg *msg);
bool EnterRoomMsg(CEnterRoomMsg *msg);
+ bool MouseDragStartMsg(CMouseDragStartMsg *msg);
public:
- CString _string3;
+ CString _target;
Point _pos1;
- CString _string4;
- CString _string5;
+ CString _itemName;
+ CString _frameTarget;
public:
CLASSDEF;
CShipSetting();
diff --git a/engines/titanic/game/ship_setting_button.cpp b/engines/titanic/game/ship_setting_button.cpp
index 7dc2cabac0..d485e06668 100644
--- a/engines/titanic/game/ship_setting_button.cpp
+++ b/engines/titanic/game/ship_setting_button.cpp
@@ -24,25 +24,69 @@
namespace Titanic {
-CShipSettingButton::CShipSettingButton() : CGameObject(), _fieldC8(0), _fieldCC(0) {
+BEGIN_MESSAGE_MAP(CShipSettingButton, CGameObject)
+ ON_MESSAGE(TurnOn)
+ ON_MESSAGE(TurnOff)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(EnterViewMsg)
+END_MESSAGE_MAP()
+
+CShipSettingButton::CShipSettingButton() : CGameObject(), _pressed(false), _enabled(false) {
}
void CShipSettingButton::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeQuotedLine(_string1, indent);
- file->writeNumberLine(_fieldC8, indent);
- file->writeNumberLine(_fieldCC, indent);
+ file->writeQuotedLine(_target, indent);
+ file->writeNumberLine(_pressed, indent);
+ file->writeNumberLine(_enabled, indent);
CGameObject::save(file, indent);
}
void CShipSettingButton::load(SimpleFile *file) {
file->readNumber();
- _string1 = file->readString();
- _fieldC8 = file->readNumber();
- _fieldCC = file->readNumber();
+ _target = file->readString();
+ _pressed = file->readNumber();
+ _enabled = file->readNumber();
CGameObject::load(file);
}
+bool CShipSettingButton::TurnOn(CTurnOn *msg) {
+ _pressed = true;
+ return true;
+}
+
+bool CShipSettingButton::TurnOff(CTurnOff *msg) {
+ _pressed = false;
+ return true;
+}
+
+bool CShipSettingButton::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (_pressed) {
+ if (_enabled)
+ playMovie(8, 16, 0);
+ else
+ playMovie(0, 8, 0);
+
+ _enabled = !_enabled;
+ CActMsg actMsg(_enabled ? "EnableObject" : "DisableObject");
+ actMsg.execute(_target);
+ } else {
+ if (_enabled) {
+ playMovie(8, 16, 0);
+ playMovie(0, 8, 0);
+ } else {
+ playMovie(0, 16, 0);
+ }
+ }
+
+ return true;
+}
+
+bool CShipSettingButton::EnterViewMsg(CEnterViewMsg *msg) {
+ loadFrame(_enabled ? 8 : 16);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/ship_setting_button.h b/engines/titanic/game/ship_setting_button.h
index e152e8e2c3..e5457fa532 100644
--- a/engines/titanic/game/ship_setting_button.h
+++ b/engines/titanic/game/ship_setting_button.h
@@ -28,10 +28,15 @@
namespace Titanic {
class CShipSettingButton : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool TurnOn(CTurnOn *msg);
+ bool TurnOff(CTurnOff *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
private:
- CString _string1;
- int _fieldC8;
- int _fieldCC;
+ CString _target;
+ bool _pressed;
+ bool _enabled;
public:
CLASSDEF;
CShipSettingButton();
diff --git a/engines/titanic/game/show_cell_points.cpp b/engines/titanic/game/show_cell_points.cpp
index 7d54401a02..985cb93734 100644
--- a/engines/titanic/game/show_cell_points.cpp
+++ b/engines/titanic/game/show_cell_points.cpp
@@ -21,21 +21,50 @@
*/
#include "titanic/game/show_cell_points.h"
+#include "titanic/pet_control/pet_control.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CShowCellpoints, CGameObject)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(LeaveViewMsg)
+END_MESSAGE_MAP()
+
void CShowCellpoints::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeQuotedLine(_strValue, indent);
- file->writeNumberLine(_numValue, indent);
+ file->writeQuotedLine(_npcName, indent);
+ file->writeNumberLine(_flag, indent);
CGameObject::save(file, indent);
}
void CShowCellpoints::load(SimpleFile *file) {
file->readNumber();
- _strValue = file->readString();
- _numValue = file->readNumber();
+ _npcName = file->readString();
+ _flag = file->readNumber();
CGameObject::load(file);
}
+bool CShowCellpoints::EnterViewMsg(CEnterViewMsg *msg) {
+ CPetControl *pet = getPetControl();
+ if (pet) {
+ petSetArea(PET_CONVERSATION);
+ pet->setActiveNPC(_npcName);
+ pet->incAreaLocks();
+ _flag = true;
+ }
+
+ return true;
+}
+
+bool CShowCellpoints::LeaveViewMsg(CLeaveViewMsg *msg) {
+ CPetControl *pet = getPetControl();
+ if (pet && _flag) {
+ pet->resetDials0();
+ pet->decAreaLocks();
+ _flag = false;
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/show_cell_points.h b/engines/titanic/game/show_cell_points.h
index 9de2e06dca..205547d7c2 100644
--- a/engines/titanic/game/show_cell_points.h
+++ b/engines/titanic/game/show_cell_points.h
@@ -28,12 +28,15 @@
namespace Titanic {
class CShowCellpoints : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
public:
- CString _strValue;
- int _numValue;
+ CString _npcName;
+ bool _flag;
public:
CLASSDEF;
- CShowCellpoints() : CGameObject(), _numValue(0) {}
+ CShowCellpoints() : CGameObject(), _flag(false) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/speech_dispensor.cpp b/engines/titanic/game/speech_dispensor.cpp
index f9cc019672..20ff3c69e0 100644
--- a/engines/titanic/game/speech_dispensor.cpp
+++ b/engines/titanic/game/speech_dispensor.cpp
@@ -24,15 +24,26 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CSpeechDispensor, CBackground)
+ ON_MESSAGE(FrameMsg)
+ ON_MESSAGE(MouseButtonUpMsg)
+ ON_MESSAGE(StatusChangeMsg)
+ ON_MESSAGE(ChangeSeasonMsg)
+END_MESSAGE_MAP()
+
+CSpeechDispensor::CSpeechDispensor() : CBackground(), _dragItem(nullptr),
+ _fieldE0(0), _state(0), _fieldEC(0), _fieldF8(0), _seasonNum(SEASON_SUMMER) {
+}
+
void CSpeechDispensor::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_fieldE0, indent);
- file->writeNumberLine(_fieldE4, indent);
+ file->writeNumberLine(_state, indent);
file->writeNumberLine(_fieldEC, indent);
- file->writeNumberLine(_fieldF0, indent);
- file->writeNumberLine(_fieldF4, indent);
+ file->writeNumberLine(_itemPos.x, indent);
+ file->writeNumberLine(_itemPos.y, indent);
file->writeNumberLine(_fieldF8, indent);
- file->writeNumberLine(_fieldFC, indent);
+ file->writeNumberLine(_seasonNum, indent);
CBackground::save(file, indent);
}
@@ -40,14 +51,93 @@ void CSpeechDispensor::save(SimpleFile *file, int indent) {
void CSpeechDispensor::load(SimpleFile *file) {
file->readNumber();
_fieldE0 = file->readNumber();
- _fieldE4 = file->readNumber();
+ _state = file->readNumber();
_fieldEC = file->readNumber();
- _fieldF0 = file->readNumber();
- _fieldF4 = file->readNumber();
+ _itemPos.x = file->readNumber();
+ _itemPos.y = file->readNumber();
_fieldF8 = file->readNumber();
- _fieldFC = file->readNumber();
+ _seasonNum = (Season)file->readNumber();
CBackground::load(file);
}
+bool CSpeechDispensor::FrameMsg(CFrameMsg *msg) {
+ if (_fieldEC || _seasonNum == SEASON_SUMMER || _seasonNum == SEASON_SPRING)
+ return true;
+
+ CGameObject *dragObject = getDraggingObject();
+ if (!_dragItem && dragObject && getView() == findView()) {
+ if (dragObject->isEquals("Perch")) {
+ petDisplayMessage(1, "This stick is too short to reach the branches.");
+ return true;
+ }
+
+ if (dragObject->isEquals("LongStick"))
+ _dragItem = dragObject;
+ }
+
+ if (_dragItem) {
+ Point pt(_itemPos.x + _dragItem->_bounds.left,
+ _itemPos.y + _dragItem->_bounds.top);
+ if (!checkPoint(pt, true))
+ return true;
+
+ switch (_state) {
+ case 0:
+ playSound("z#93.wav");
+ if (_seasonNum == SEASON_WINTER) {
+ petDisplayMessage(1, "You cannot get this, it is frozen to the branch.");
+ _fieldE0 = false;
+ _state = 1;
+ } else {
+ if (++_fieldE0 >= 5) {
+ CActMsg actMsg("PlayerGetsSpeechCentre");
+ actMsg.execute("SeasonalAdjust");
+ CSpeechFallsFromTreeMsg fallMsg(pt);
+ fallMsg.execute("SpeechCentre");
+
+ _fieldEC = true;
+ _fieldE0 = false;
+ }
+
+ _state = 1;
+ }
+ break;
+
+ case 2:
+ _state = 0;
+ ++_fieldE0;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return true;
+}
+
+bool CSpeechDispensor::MouseButtonUpMsg(CMouseButtonUpMsg *msg) {
+ if (!_fieldEC) {
+ playSound("z#93.wav");
+ if (_fieldF8) {
+ petDisplayMessage(1, "Sadly, this is out of your reach.");
+ } else {
+ petDisplayMessage(1, "You can't pick this up on account of it being stuck to the branch.");
+ }
+ }
+
+ return true;
+}
+
+bool CSpeechDispensor::StatusChangeMsg(CStatusChangeMsg *msg) {
+ _fieldF8 = msg->_newStatus == 1;
+ return true;
+}
+
+bool CSpeechDispensor::ChangeSeasonMsg(CChangeSeasonMsg *msg) {
+ _seasonNum = (Season)(((int)_seasonNum + 1) % 4);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/speech_dispensor.h b/engines/titanic/game/speech_dispensor.h
index 3b877e8d99..038cc024cc 100644
--- a/engines/titanic/game/speech_dispensor.h
+++ b/engines/titanic/game/speech_dispensor.h
@@ -28,17 +28,22 @@
namespace Titanic {
class CSpeechDispensor : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool FrameMsg(CFrameMsg *msg);
+ bool MouseButtonUpMsg(CMouseButtonUpMsg *msg);
+ bool StatusChangeMsg(CStatusChangeMsg *msg);
+ bool ChangeSeasonMsg(CChangeSeasonMsg *msg);
private:
int _fieldE0;
- int _fieldE4;
- int _fieldE8;
+ int _state;
+ CGameObject *_dragItem;
int _fieldEC;
- int _fieldF0;
- int _fieldF4;
+ Point _itemPos;
int _fieldF8;
- int _fieldFC;
+ Season _seasonNum;
public:
CLASSDEF;
+ CSpeechDispensor();
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/starling_puret.cpp b/engines/titanic/game/starling_puret.cpp
index 359ad774df..2f1909d963 100644
--- a/engines/titanic/game/starling_puret.cpp
+++ b/engines/titanic/game/starling_puret.cpp
@@ -24,16 +24,56 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CStarlingPuret, CGameObject)
+ ON_MESSAGE(StatusChangeMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(MovieEndMsg)
+END_MESSAGE_MAP()
+
void CStarlingPuret::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_value, indent);
+ file->writeNumberLine(_flag, indent);
CGameObject::save(file, indent);
}
void CStarlingPuret::load(SimpleFile *file) {
file->readNumber();
- _value = file->readNumber();
+ _flag = file->readNumber();
CGameObject::load(file);
}
+bool CStarlingPuret::StatusChangeMsg(CStatusChangeMsg *msg) {
+ _flag = msg->_newStatus == 1;
+ if (_flag) {
+ CStatusChangeMsg changeMsg;
+ changeMsg._newStatus = 1;
+ changeMsg.execute("StarlingLoop01");
+ }
+
+ return true;
+}
+
+bool CStarlingPuret::EnterViewMsg(CEnterViewMsg *msg) {
+ if (_flag) {
+ CStatusChangeMsg changeMsg;
+ changeMsg._newStatus = 1;
+ changeMsg.execute("PromDeckStarlings");
+
+ playMovie(MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ CSignalObject signalMsg;
+ signalMsg._numValue = 4;
+ signalMsg.execute("PromDeckStarlings");
+ _flag = false;
+ }
+
+ return true;
+}
+
+bool CStarlingPuret::MovieEndMsg(CMovieEndMsg *msg) {
+ CActMsg actMsg("StarlingsDead");
+ actMsg.execute("FanController");
+ actMsg.execute("BirdSauceDisp");
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/starling_puret.h b/engines/titanic/game/starling_puret.h
index fcd3319958..62a6173093 100644
--- a/engines/titanic/game/starling_puret.h
+++ b/engines/titanic/game/starling_puret.h
@@ -28,11 +28,15 @@
namespace Titanic {
class CStarlingPuret : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool StatusChangeMsg(CStatusChangeMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
private:
- int _value;
+ bool _flag;
public:
CLASSDEF;
- CStarlingPuret() : CGameObject(), _value(0) {}
+ CStarlingPuret() : CGameObject(), _flag(false) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/stop_phonograph_button.cpp b/engines/titanic/game/stop_phonograph_button.cpp
index d18f4713ac..75e0ca9337 100644
--- a/engines/titanic/game/stop_phonograph_button.cpp
+++ b/engines/titanic/game/stop_phonograph_button.cpp
@@ -24,6 +24,10 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CStopPhonographButton, CBackground)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
void CStopPhonographButton::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CBackground::save(file, indent);
@@ -34,4 +38,19 @@ void CStopPhonographButton::load(SimpleFile *file) {
CBackground::load(file);
}
+bool CStopPhonographButton::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ CQueryPhonographState queryMsg;
+ queryMsg.execute(getParent());
+
+ if (!queryMsg._value) {
+ playMovie(0, 1, 0);
+ playMovie(1, 0, 0);
+
+ CPhonographStopMsg stopMsg;
+ stopMsg.execute(getParent());
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/stop_phonograph_button.h b/engines/titanic/game/stop_phonograph_button.h
index b469375e20..d416c4f8fe 100644
--- a/engines/titanic/game/stop_phonograph_button.h
+++ b/engines/titanic/game/stop_phonograph_button.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CStopPhonographButton : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/sub_glass.cpp b/engines/titanic/game/sub_glass.cpp
index f1349f06ea..041f49097d 100644
--- a/engines/titanic/game/sub_glass.cpp
+++ b/engines/titanic/game/sub_glass.cpp
@@ -24,17 +24,25 @@
namespace Titanic {
-CSUBGlass::CSUBGlass() : _fieldBC(0), _fieldC0(0), _fieldC4(1), _fieldC8(0) {
+BEGIN_MESSAGE_MAP(CSUBGlass, CGameObject)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(MouseButtonUpMsg)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(SignalObject)
+ ON_MESSAGE(LeaveViewMsg)
+END_MESSAGE_MAP()
+
+CSUBGlass::CSUBGlass() : _fieldBC(0), _startFrame(0), _endFrame(1), _signalStartFrame(0) {
}
void CSUBGlass::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_fieldBC, indent);
- file->writeNumberLine(_fieldC0, indent);
- file->writeNumberLine(_fieldC4, indent);
- file->writeNumberLine(_fieldC8, indent);
- file->writeNumberLine(_fieldCC, indent);
- file->writeQuotedLine(_string, indent);
+ file->writeNumberLine(_startFrame, indent);
+ file->writeNumberLine(_endFrame, indent);
+ file->writeNumberLine(_signalStartFrame, indent);
+ file->writeNumberLine(_signalEndFrame, indent);
+ file->writeQuotedLine(_target, indent);
CGameObject::save(file, indent);
}
@@ -42,13 +50,58 @@ void CSUBGlass::save(SimpleFile *file, int indent) {
void CSUBGlass::load(SimpleFile *file) {
file->readNumber();
_fieldBC = file->readNumber();
- _fieldC0 = file->readNumber();
- _fieldC4 = file->readNumber();
- _fieldC8 = file->readNumber();
- _fieldCC = file->readNumber();
- _string = file->readString();
+ _startFrame = file->readNumber();
+ _endFrame = file->readNumber();
+ _signalStartFrame = file->readNumber();
+ _signalEndFrame = file->readNumber();
+ _target = file->readString();
CGameObject::load(file);
}
+bool CSUBGlass::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ return true;
+}
+
+bool CSUBGlass::MouseButtonUpMsg(CMouseButtonUpMsg *msg) {
+ if (!_fieldBC && _startFrame >= 0) {
+ _fieldBC = true;
+ playMovie(_startFrame, _endFrame, MOVIE_NOTIFY_OBJECT);
+ playSound("z#30.wav");
+ }
+
+ return true;
+}
+
+bool CSUBGlass::MovieEndMsg(CMovieEndMsg *msg) {
+ if (msg->_endFrame == _endFrame) {
+ _fieldBC = true;
+ CSignalObject signalMsg(getName(), 1);
+ signalMsg.execute(_target);
+ }
+
+ return true;
+}
+
+bool CSUBGlass::SignalObject(CSignalObject *msg) {
+ if (msg->_numValue == 1) {
+ setVisible(true);
+
+ if (_signalStartFrame >= 0) {
+ playMovie(_signalStartFrame, _signalEndFrame, MOVIE_GAMESTATE);
+ playSound("z#30.wav");
+ _fieldBC = false;
+ }
+ }
+
+ return true;
+}
+
+bool CSUBGlass::LeaveViewMsg(CLeaveViewMsg *msg) {
+ _fieldBC = false;
+ setVisible(true);
+ loadFrame(0);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/sub_glass.h b/engines/titanic/game/sub_glass.h
index aab5c8400e..22d16ff4d5 100644
--- a/engines/titanic/game/sub_glass.h
+++ b/engines/titanic/game/sub_glass.h
@@ -28,13 +28,19 @@
namespace Titanic {
class CSUBGlass : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool MouseButtonUpMsg(CMouseButtonUpMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool SignalObject(CSignalObject *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
private:
int _fieldBC;
- int _fieldC0;
- int _fieldC4;
- int _fieldC8;
- int _fieldCC;
- CString _string;
+ int _startFrame;
+ int _endFrame;
+ int _signalStartFrame;
+ int _signalEndFrame;
+ CString _target;
public:
CLASSDEF;
CSUBGlass();
diff --git a/engines/titanic/game/sub_wrapper.cpp b/engines/titanic/game/sub_wrapper.cpp
index dcc489316b..4080487d6d 100644
--- a/engines/titanic/game/sub_wrapper.cpp
+++ b/engines/titanic/game/sub_wrapper.cpp
@@ -24,16 +24,56 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CSUBWrapper, CGameObject)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(SignalObject)
+END_MESSAGE_MAP()
+
void CSUBWrapper::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_value, indent);
+ file->writeNumberLine(_flag, indent);
CGameObject::save(file, indent);
}
void CSUBWrapper::load(SimpleFile *file) {
file->readNumber();
- _value = file->readNumber();
+ _flag = file->readNumber();
CGameObject::load(file);
}
+bool CSUBWrapper::MovieEndMsg(CMovieEndMsg *msg) {
+ if (_flag) {
+ stopMovie();
+ setVisible(false);
+ _flag = false;
+ }
+
+ return true;
+}
+
+bool CSUBWrapper::SignalObject(CSignalObject *msg) {
+ switch (msg->_numValue) {
+ case 1:
+ if (!_flag) {
+ loadFrame(0);
+ setVisible(true);
+ playMovie(MOVIE_NOTIFY_OBJECT);
+ _flag = true;
+ }
+ break;
+
+ case 2:
+ if (!_flag) {
+ setVisible(true);
+ _flag = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/sub_wrapper.h b/engines/titanic/game/sub_wrapper.h
index 81f8fdc941..1094a2e677 100644
--- a/engines/titanic/game/sub_wrapper.h
+++ b/engines/titanic/game/sub_wrapper.h
@@ -28,11 +28,14 @@
namespace Titanic {
class CSUBWrapper : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool SignalObject(CSignalObject *msg);
public:
- int _value;
+ bool _flag;
public:
CLASSDEF;
- CSUBWrapper() : CGameObject(), _value(0) {}
+ CSUBWrapper() : CGameObject(), _flag(false) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/sweet_bowl.cpp b/engines/titanic/game/sweet_bowl.cpp
index e14f900e77..d0a2525bc4 100644
--- a/engines/titanic/game/sweet_bowl.cpp
+++ b/engines/titanic/game/sweet_bowl.cpp
@@ -24,6 +24,12 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CSweetBowl, CGameObject)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(ActMsg)
+END_MESSAGE_MAP()
+
void CSweetBowl::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CGameObject::save(file, indent);
@@ -34,4 +40,28 @@ void CSweetBowl::load(SimpleFile *file) {
CGameObject::load(file);
}
+bool CSweetBowl::MovieEndMsg(CMovieEndMsg *msg) {
+ setVisible(false);
+ return true;
+}
+
+bool CSweetBowl::EnterViewMsg(CEnterViewMsg *msg) {
+ setVisible(false);
+ loadSound("b#43.wav");
+ playSound("b#42.wav");
+ return true;
+}
+
+bool CSweetBowl::ActMsg(CActMsg *msg) {
+ if (msg->_action == "Jiggle") {
+ setVisible(true);
+ playMovie(MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
+ playSound(getRandomNumber(1) == 1 ? "b#42.wav" : "b#43.wav");
+ }
+
+ petDisplayMessage(isEquals("BowlNutsRustler") ?
+ "A bowl of pistachio nuts." : "Not a bowl of pistachio nuts.");
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/sweet_bowl.h b/engines/titanic/game/sweet_bowl.h
index cf3d0023a4..53433c8c08 100644
--- a/engines/titanic/game/sweet_bowl.h
+++ b/engines/titanic/game/sweet_bowl.h
@@ -28,6 +28,10 @@
namespace Titanic {
class CSweetBowl : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool ActMsg(CActMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/third_class_canal.cpp b/engines/titanic/game/third_class_canal.cpp
index 6b0a101f7b..97b559e35d 100644
--- a/engines/titanic/game/third_class_canal.cpp
+++ b/engines/titanic/game/third_class_canal.cpp
@@ -24,6 +24,10 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CThirdClassCanal, CBackground)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
void CThirdClassCanal::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CBackground::save(file, indent);
@@ -34,4 +38,9 @@ void CThirdClassCanal::load(SimpleFile *file) {
CBackground::load(file);
}
+bool CThirdClassCanal::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ petDisplayMessage("This area is off limits to passengers.");
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/third_class_canal.h b/engines/titanic/game/third_class_canal.h
index f6fc471444..d0be8c05aa 100644
--- a/engines/titanic/game/third_class_canal.h
+++ b/engines/titanic/game/third_class_canal.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CThirdClassCanal : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/throw_tv_down_well.cpp b/engines/titanic/game/throw_tv_down_well.cpp
index c8a9fc7c9e..9de028cbde 100644
--- a/engines/titanic/game/throw_tv_down_well.cpp
+++ b/engines/titanic/game/throw_tv_down_well.cpp
@@ -24,18 +24,73 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CThrowTVDownWell, CGameObject)
+ ON_MESSAGE(ActMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(TimerMsg)
+ ON_MESSAGE(MovieFrameMsg)
+END_MESSAGE_MAP()
+
void CThrowTVDownWell::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeQuotedLine(_strValue, indent);
- file->writeNumberLine(_numValue, indent);
+ file->writeQuotedLine(_viewName, indent);
+ file->writeNumberLine(_flag, indent);
CGameObject::save(file, indent);
}
void CThrowTVDownWell::load(SimpleFile *file) {
file->readNumber();
- _strValue = file->readString();
- _numValue = file->readNumber();
+ _viewName = file->readString();
+ _flag = file->readNumber();
CGameObject::load(file);
}
+bool CThrowTVDownWell::ActMsg(CActMsg *msg) {
+ if (msg->_action == "ThrowTVDownWell" && !_flag) {
+ CString viewName = getFullViewName();
+ lockMouse();
+ addTimer(1, 8000, 0);
+
+ CActMsg actMsg("ThrownTVDownWell");
+ actMsg.execute("BOWTelevisionMonitor");
+ }
+
+ return true;
+}
+
+bool CThrowTVDownWell::EnterViewMsg(CEnterViewMsg *msg) {
+ playMovie(MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ movieEvent(49);
+ return true;
+}
+
+bool CThrowTVDownWell::MovieEndMsg(CMovieEndMsg *msg) {
+ sleep(2000);
+ changeView("ParrotLobby.Node 11.N");
+ playSound("z#471.wav");
+ addTimer(2, 7000, 0);
+ return true;
+}
+
+bool CThrowTVDownWell::TimerMsg(CTimerMsg *msg) {
+ if (msg->_actionVal == 1) {
+ changeView("ParrotLobby.Node 10.N");
+ } else if (msg->_actionVal == 2) {
+ playSound("z#468.wav", 50);
+ sleep(1500);
+ changeView(_viewName);
+ _viewName = "NULL";
+ unlockMouse();
+ playSound("z#47.wav");
+ }
+
+ return true;
+}
+
+bool CThrowTVDownWell::MovieFrameMsg(CMovieFrameMsg *msg) {
+ playSound("z#470.wav");
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/throw_tv_down_well.h b/engines/titanic/game/throw_tv_down_well.h
index b6003aa3ef..c9e8fd57a9 100644
--- a/engines/titanic/game/throw_tv_down_well.h
+++ b/engines/titanic/game/throw_tv_down_well.h
@@ -28,12 +28,18 @@
namespace Titanic {
class CThrowTVDownWell : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool ActMsg(CActMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool TimerMsg(CTimerMsg *msg);
+ bool MovieFrameMsg(CMovieFrameMsg *msg);
public:
- CString _strValue;
- int _numValue;
+ CString _viewName;
+ bool _flag;
public:
CLASSDEF;
- CThrowTVDownWell() : CGameObject(), _numValue(0) {}
+ CThrowTVDownWell() : CGameObject(), _flag(false) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game/titania_still_control.cpp b/engines/titanic/game/titania_still_control.cpp
index 67866ecdcb..1ce0a85b4e 100644
--- a/engines/titanic/game/titania_still_control.cpp
+++ b/engines/titanic/game/titania_still_control.cpp
@@ -24,6 +24,11 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CTitaniaStillControl, CGameObject)
+ ON_MESSAGE(SetFrameMsg)
+ ON_MESSAGE(VisibleMsg)
+END_MESSAGE_MAP()
+
void CTitaniaStillControl::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CGameObject::save(file, indent);
@@ -34,4 +39,15 @@ void CTitaniaStillControl::load(SimpleFile *file) {
CGameObject::load(file);
}
+bool CTitaniaStillControl::SetFrameMsg(CSetFrameMsg *msg) {
+ loadFrame(msg->_frameNumber);
+ setVisible(true);
+ return true;
+}
+
+bool CTitaniaStillControl::VisibleMsg(CVisibleMsg *msg) {
+ setVisible(false);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/titania_still_control.h b/engines/titanic/game/titania_still_control.h
index 66c3045187..b77227a539 100644
--- a/engines/titanic/game/titania_still_control.h
+++ b/engines/titanic/game/titania_still_control.h
@@ -28,6 +28,9 @@
namespace Titanic {
class CTitaniaStillControl : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool SetFrameMsg(CSetFrameMsg *msg);
+ bool VisibleMsg(CVisibleMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/tow_parrot_nav.cpp b/engines/titanic/game/tow_parrot_nav.cpp
index 9361808870..57f1649add 100644
--- a/engines/titanic/game/tow_parrot_nav.cpp
+++ b/engines/titanic/game/tow_parrot_nav.cpp
@@ -21,9 +21,14 @@
*/
#include "titanic/game/tow_parrot_nav.h"
+#include "titanic/npcs/parrot.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CTOWParrotNav, CGameObject)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
void CTOWParrotNav::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CGameObject::save(file, indent);
@@ -34,4 +39,16 @@ void CTOWParrotNav::load(SimpleFile *file) {
CGameObject::load(file);
}
+bool CTOWParrotNav::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ CActMsg actMsg("EnteringFromTOW");
+ actMsg.execute("PerchedParrot");
+
+ CString clipString = "_EXIT,36,1,N,9,3,N";
+ if (CParrot::_v4)
+ clipString += 'a';
+ changeView("ParrotLobby.Node 3.N", clipString);
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/tow_parrot_nav.h b/engines/titanic/game/tow_parrot_nav.h
index 17618ff6de..252d9b631d 100644
--- a/engines/titanic/game/tow_parrot_nav.h
+++ b/engines/titanic/game/tow_parrot_nav.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CTOWParrotNav : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/transport/lift_indicator.cpp b/engines/titanic/game/transport/lift_indicator.cpp
index 1336daf7aa..7471affc36 100644
--- a/engines/titanic/game/transport/lift_indicator.cpp
+++ b/engines/titanic/game/transport/lift_indicator.cpp
@@ -93,14 +93,14 @@ bool CLiftindicator::EnterViewMsg(CEnterViewMsg *msg) {
case 1:
case 2:
setPosition(Point(_bounds.left, _indicatorPos.y +
- multiplier * CLift::_elevator1Floor));
+ (int)(multiplier * CLift::_elevator1Floor)));
_startFrame = CLift::_elevator1Floor;
break;
case 3:
case 4:
setPosition(Point(_bounds.left, _indicatorPos.y +
- multiplier * CLift::_elevator3Floor));
+ (int)(multiplier * CLift::_elevator3Floor)));
_startFrame = CLift::_elevator3Floor;
break;
@@ -115,14 +115,14 @@ bool CLiftindicator::EnterViewMsg(CEnterViewMsg *msg) {
case 1:
case 2:
setPosition(Point(_bounds.left, _indicatorPos.y +
- multiplier * CLift::_elevator2Floor));
+ (int)(multiplier * CLift::_elevator2Floor)));
_startFrame = CLift::_elevator2Floor;
break;
case 3:
case 4:
setPosition(Point(_bounds.left, _indicatorPos.y +
- multiplier * CLift::_elevator4Floor));
+ (int)(multiplier * CLift::_elevator4Floor)));
_startFrame = CLift::_elevator4Floor;
break;
@@ -158,8 +158,8 @@ bool CLiftindicator::PETActivateMsg(CPETActivateMsg *msg) {
&& pet->getRoomsFloorNum() != CLift::_elevator4Floor) {
petDisplayMessage(1, "This elevator is currently in an advanced state of non-functionality.");
} else {
- _start = _indicatorPos.y + _startFrame * multiplier;
- _end = _indicatorPos.y + _endFrame * multiplier;
+ _start = _indicatorPos.y + (int)(_startFrame * multiplier);
+ _end = _indicatorPos.y + (int)(_endFrame * multiplier);
lockMouse();
addTimer(100);
diff --git a/engines/titanic/game/transport/service_elevator.cpp b/engines/titanic/game/transport/service_elevator.cpp
index 1ea8d14e36..1980825cb6 100644
--- a/engines/titanic/game/transport/service_elevator.cpp
+++ b/engines/titanic/game/transport/service_elevator.cpp
@@ -21,15 +21,27 @@
*/
#include "titanic/game/transport/service_elevator.h"
+#include "titanic/core/room_item.h"
+#include "titanic/npcs/doorbot.h"
-namespace Titanic {
+namespace Titanic {
-int CServiceElevator::_v1;
+BEGIN_MESSAGE_MAP(CServiceElevator, CTransport)
+ ON_MESSAGE(BodyInBilgeRoomMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(ServiceElevatorMsg)
+ ON_MESSAGE(TimerMsg)
+ ON_MESSAGE(ServiceElevatorFloorRequestMsg)
+ ON_MESSAGE(LeaveRoomMsg)
+ ON_MESSAGE(OpeningCreditsMsg)
+END_MESSAGE_MAP()
+
+bool CServiceElevator::_v1;
int CServiceElevator::_v2;
int CServiceElevator::_v3;
CServiceElevator::CServiceElevator() : CTransport(),
- _fieldF8(0), _fieldFC(0), _field100(0), _field104(0) {
+ _fieldF8(0), _soundHandle1(0), _timerId(0), _soundHandle2(0) {
}
void CServiceElevator::save(SimpleFile *file, int indent) {
@@ -38,9 +50,9 @@ void CServiceElevator::save(SimpleFile *file, int indent) {
file->writeNumberLine(_v2, indent);
file->writeNumberLine(_v3, indent);
file->writeNumberLine(_fieldF8, indent);
- file->writeNumberLine(_fieldFC, indent);
- file->writeNumberLine(_field100, indent);
- file->writeNumberLine(_field104, indent);
+ file->writeNumberLine(_soundHandle1, indent);
+ file->writeNumberLine(_timerId, indent);
+ file->writeNumberLine(_soundHandle2, indent);
CTransport::save(file, indent);
}
@@ -51,11 +63,208 @@ void CServiceElevator::load(SimpleFile *file) {
_v2 = file->readNumber();
_v3 = file->readNumber();
_fieldF8 = file->readNumber();
- _fieldFC = file->readNumber();
- _field100 = file->readNumber();
- _field104 = file->readNumber();
+ _soundHandle1 = file->readNumber();
+ _timerId = file->readNumber();
+ _soundHandle2 = file->readNumber();
CTransport::load(file);
}
+bool CServiceElevator::BodyInBilgeRoomMsg(CBodyInBilgeRoomMsg *msg) {
+ _v2 = true;
+ _string1 = "BilgeRoomWith.Node 2.N";
+ return true;
+}
+
+bool CServiceElevator::EnterViewMsg(CEnterViewMsg *msg) {
+ petShow();
+ return true;
+}
+
+bool CServiceElevator::ServiceElevatorMsg(CServiceElevatorMsg *msg) {
+ switch (msg->_value) {
+ case 1:
+ case 2:
+ case 3: {
+ switch (msg->_value) {
+ case 1:
+ _v3 = 0;
+ break;
+ case 2:
+ _v3 = 1;
+ break;
+ case 3:
+ _v3 = 2;
+ break;
+ }
+
+ CServiceElevatorFloorRequestMsg requestMsg;
+ requestMsg.execute(this);
+ break;
+ }
+
+ case 4:
+ if (!_string1.empty()) {
+ if (_string1 == "DeepSpace") {
+ disableMouse();
+ _soundHandle1 = playSound("z#413.wav", 50);
+ _timerId = addTimer(1, 1000, 500);
+ } else {
+ changeView(_string1);
+ }
+ }
+ break;
+
+ case 5:
+ _fieldF8 = false;
+ _fieldDC = _v3;
+ loadSound("z#423.wav");
+ stopSound(_soundHandle2);
+ _soundHandle2 = playSound("z#423.wav", 80);
+
+ switch (_fieldDC) {
+ case 0:
+ _string1 = "DeepSpace";
+ _string2 = "a#2.wav";
+ queueSound("z#416.wav", _soundHandle2, 50);
+ break;
+
+ case 1:
+ _string1 = _v2 ? "BilgeRoomWith.Node 2.N" : "BilgeRoom.Node 1.N";
+ queueSound("z#421.wav", _soundHandle2, 50);
+ break;
+
+ case 2:
+ _string1 = _v1 ? "MoonEmbLobby.Node 1.NE" : "EmbLobby.Node 1.NE";
+ queueSound("z#411.wav", _soundHandle2, 50);
+ break;
+
+ default:
+ break;
+ }
+
+ enableMouse();
+ if (findRoom()->findByName("Doorbot"))
+ addTimer(3, 3000, 0);
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool CServiceElevator::TimerMsg(CTimerMsg *msg) {
+ CDoorbot *doorbot = dynamic_cast<CDoorbot *>(findRoom()->findByName("Doorbot"));
+
+ switch (msg->_actionVal) {
+ case 0:
+ case 1:
+ if (!isSoundActive(_soundHandle1)) {
+ stopAnimTimer(_timerId);
+ if (msg->_actionVal == 0) {
+ _fieldF8 = true;
+ CServiceElevatorFloorChangeMsg changeMsg(_fieldDC, _v3);
+ changeMsg.execute(getRoom());
+ _soundHandle2 = playSound("z#424.wav");
+
+ if (doorbot) {
+ CActMsg actMsg("DoorbotPlayerPressedTopButton");
+ actMsg.execute(doorbot);
+ }
+ } else {
+ enableMouse();
+ if (doorbot) {
+ CActMsg actMsg;
+ if (_v3 == 0)
+ actMsg._action = "DoorbotPlayerPressedBottomButton";
+ else if (_v3 == 1)
+ actMsg._action = "DoorbotPlayerPressedMiddleButton";
+
+ actMsg.execute(doorbot);
+ }
+ }
+ }
+ break;
+
+ case 3: {
+ CActMsg actMsg("DoorbotReachedEmbLobby");
+ actMsg.execute(doorbot);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool CServiceElevator::ServiceElevatorFloorRequestMsg(CServiceElevatorFloorRequestMsg *msg) {
+ disableMouse();
+ CDoorbot *doorbot = dynamic_cast<CDoorbot *>(findRoom()->findByName("Doorbot"));
+
+ if (doorbot && _v3 == 0) {
+ _soundHandle1 = playSound("z#415.wav", 50);
+ addTimer(1, 1000, 500);
+ } else if (doorbot && _v3 == 1) {
+ _soundHandle1 = playSound("z#417.wav", 50);
+ addTimer(1, 1000, 500);
+ } else if (_fieldDC == _v3) {
+ switch (_v3) {
+ case 0:
+ _soundHandle1 = playSound("z#415.wav", 50);
+ break;
+ case 1:
+ _soundHandle1 = playSound("z#420.wav", 50);
+ break;
+ case 2:
+ _soundHandle1 = playSound("z#410.wav", 50);
+ break;
+ default:
+ break;
+ }
+
+ addTimer(1, 1000, 500);
+ } else {
+ switch (_v3) {
+ case 0:
+ _soundHandle1 = playSound("z#414.wav", 50);
+ break;
+ case 1:
+ _soundHandle1 = playSound(_fieldDC ? "z#419.wav" : "z#418.wav", 50);
+ break;
+ case 2:
+ _soundHandle1 = playSound("z#414.wav", 50);
+ break;
+ default:
+ break;
+ }
+
+ addTimer(0, 1000, 500);
+ }
+
+ return true;
+}
+
+bool CServiceElevator::LeaveRoomMsg(CLeaveRoomMsg *msg) {
+ CDoorbot *doorbot = dynamic_cast<CDoorbot *>(findRoom()->findByName("Doorbot"));
+
+ if (doorbot) {
+ CPutBotBackInHisBoxMsg boxMsg(0);
+ boxMsg.execute("Doorbot");
+ doorbot->performAction(false);
+ enableMouse();
+ }
+
+ return true;
+}
+
+bool CServiceElevator::OpeningCreditsMsg(COpeningCreditsMsg *msg) {
+ _v1 = false;
+ _string1 = "EmbLobby.Node 1.NE";
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/transport/service_elevator.h b/engines/titanic/game/transport/service_elevator.h
index b2c135021a..5cf1f6f0d5 100644
--- a/engines/titanic/game/transport/service_elevator.h
+++ b/engines/titanic/game/transport/service_elevator.h
@@ -28,15 +28,23 @@
namespace Titanic {
class CServiceElevator : public CTransport {
+ DECLARE_MESSAGE_MAP;
+ bool BodyInBilgeRoomMsg(CBodyInBilgeRoomMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool ServiceElevatorMsg(CServiceElevatorMsg *msg);
+ bool TimerMsg(CTimerMsg *msg);
+ bool ServiceElevatorFloorRequestMsg(CServiceElevatorFloorRequestMsg *msg);
+ bool LeaveRoomMsg(CLeaveRoomMsg *msg);
+ bool OpeningCreditsMsg(COpeningCreditsMsg *msg);
private:
- static int _v1;
+ static bool _v1;
static int _v2;
static int _v3;
int _fieldF8;
- int _fieldFC;
- int _field100;
- int _field104;
+ int _soundHandle1;
+ int _timerId;
+ int _soundHandle2;
public:
CLASSDEF;
CServiceElevator();
diff --git a/engines/titanic/game/up_lighter.cpp b/engines/titanic/game/up_lighter.cpp
index f03b8f37a0..d133a7e9df 100644
--- a/engines/titanic/game/up_lighter.cpp
+++ b/engines/titanic/game/up_lighter.cpp
@@ -21,9 +21,21 @@
*/
#include "titanic/game/up_lighter.h"
+#include "titanic/core/project_item.h"
+#include "titanic/npcs/parrot.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CUpLighter, CDropTarget)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(PumpingMsg)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(EnterRoomMsg)
+ ON_MESSAGE(ChangeSeasonMsg)
+ ON_MESSAGE(TimerMsg)
+ ON_MESSAGE(LeaveRoomMsg)
+END_MESSAGE_MAP()
+
CUpLighter::CUpLighter() : CDropTarget(), _field118(0),
_field11C(0), _field120(0), _field124(0) {
}
@@ -48,8 +60,61 @@ void CUpLighter::load(SimpleFile *file) {
CDropTarget::load(file);
}
+bool CUpLighter::MovieEndMsg(CMovieEndMsg *msg) {
+ if (_field118) {
+ playSound("z#47.wav");
+ _field124 = true;
+
+ CVisibleMsg visibleMsg(true);
+ visibleMsg.execute("NoseHolder");
+ CDropZoneLostObjectMsg lostMsg(nullptr);
+ lostMsg.execute(this);
+ _clipName.clear();
+ _itemMatchName = "Nothing";
+ _field118 = 0;
+ }
+
+ return true;
+}
+
+bool CUpLighter::PumpingMsg(CPumpingMsg *msg) {
+ _field118 = msg->_value;
+ _clipName = (_field118 && !_field124) ? "WholeSequence" : "HoseToNose";
+ return true;
+}
+
+bool CUpLighter::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ CTrueTalkTriggerActionMsg triggerMsg(280245, 0, 0);
+ triggerMsg.execute(getRoot(), CParrot::_type,
+ MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_CLASS_DEF | MSGFLAG_SCAN);
+ return true;
+}
+
bool CUpLighter::EnterRoomMsg(CEnterRoomMsg *msg) {
- warning("CUpLighter::handleEvent");
+ _field11C = true;
+ addTimer(5000 + getRandomNumber(15000), 0);
+ return true;
+}
+
+bool CUpLighter::ChangeSeasonMsg(CChangeSeasonMsg *msg) {
+ _field120 = msg->_season == "Spring";
+ if (_field120)
+ addTimer(5000 + getRandomNumber(15000), 0);
+ return true;
+}
+
+bool CUpLighter::TimerMsg(CTimerMsg *msg) {
+ if (_field120 && _field11C & !_field118) {
+ CActMsg actMsg("Sneeze");
+ actMsg.execute(findRoom()->findByName("NoseHolder"));
+ addTimer(1000 + getRandomNumber(19000), 0);
+ }
+
+ return true;
+}
+
+bool CUpLighter::LeaveRoomMsg(CLeaveRoomMsg *msg) {
+ _field11C = false;
return true;
}
diff --git a/engines/titanic/game/up_lighter.h b/engines/titanic/game/up_lighter.h
index 2367e41314..e6a53cf7bd 100644
--- a/engines/titanic/game/up_lighter.h
+++ b/engines/titanic/game/up_lighter.h
@@ -29,7 +29,14 @@
namespace Titanic {
class CUpLighter : public CDropTarget {
+ DECLARE_MESSAGE_MAP;
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool PumpingMsg(CPumpingMsg *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
bool EnterRoomMsg(CEnterRoomMsg *msg);
+ bool ChangeSeasonMsg(CChangeSeasonMsg *msg);
+ bool TimerMsg(CTimerMsg *msg);
+ bool LeaveRoomMsg(CLeaveRoomMsg *msg);
private:
int _field118;
int _field11C;
diff --git a/engines/titanic/game/useless_lever.cpp b/engines/titanic/game/useless_lever.cpp
index e48ad55a71..82d8983710 100644
--- a/engines/titanic/game/useless_lever.cpp
+++ b/engines/titanic/game/useless_lever.cpp
@@ -24,6 +24,11 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CUselessLever, CToggleButton)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(EnterViewMsg)
+END_MESSAGE_MAP()
+
void CUselessLever::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
CToggleButton::save(file, indent);
@@ -34,4 +39,23 @@ void CUselessLever::load(SimpleFile *file) {
CToggleButton::load(file);
}
+bool CUselessLever::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (_fieldE0) {
+ playMovie(15, 30, 0);
+ playSound("z#56.wav");
+ _fieldE0 = false;
+ } else {
+ playMovie(0, 14, 0);
+ playSound("z#56.wav");
+ _fieldE0 = true;
+ }
+
+ return true;
+}
+
+bool CUselessLever::EnterViewMsg(CEnterViewMsg *msg) {
+ loadFrame(_fieldE0 ? 15 : 0);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/useless_lever.h b/engines/titanic/game/useless_lever.h
index 27397de216..33ed94b2ac 100644
--- a/engines/titanic/game/useless_lever.h
+++ b/engines/titanic/game/useless_lever.h
@@ -28,6 +28,9 @@
namespace Titanic {
class CUselessLever : public CToggleButton {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/game/wheel_button.cpp b/engines/titanic/game/wheel_button.cpp
index 19c42a8807..730a5d9005 100644
--- a/engines/titanic/game/wheel_button.cpp
+++ b/engines/titanic/game/wheel_button.cpp
@@ -24,14 +24,20 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CWheelButton, CBackground)
+ ON_MESSAGE(SignalObject)
+ ON_MESSAGE(TimerMsg)
+ ON_MESSAGE(LeaveViewMsg)
+END_MESSAGE_MAP()
+
CWheelButton::CWheelButton() : CBackground(),
- _fieldE0(0), _fieldE4(0), _fieldE8(0) {
+ _fieldE0(false), _timerId(0), _fieldE8(0) {
}
void CWheelButton::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_fieldE0, indent);
- file->writeNumberLine(_fieldE4, indent);
+ file->writeNumberLine(_timerId, indent);
file->writeNumberLine(_fieldE8, indent);
CBackground::save(file, indent);
@@ -40,10 +46,43 @@ void CWheelButton::save(SimpleFile *file, int indent) {
void CWheelButton::load(SimpleFile *file) {
file->readNumber();
_fieldE0 = file->readNumber();
- _fieldE4 = file->readNumber();
+ _timerId = file->readNumber();
_fieldE8 = file->readNumber();
CBackground::load(file);
}
+bool CWheelButton::SignalObject(CSignalObject *msg) {
+ bool oldFlag = _fieldE0;
+ _fieldE0 = msg->_numValue != 0;
+
+ if (oldFlag != _fieldE0) {
+ if (_fieldE0) {
+ _timerId = addTimer(500, 500);
+ } else {
+ stopAnimTimer(_timerId);
+ _timerId = 0;
+ setVisible(false);
+ }
+ }
+
+ return true;
+}
+
+bool CWheelButton::TimerMsg(CTimerMsg *msg) {
+ setVisible(!_visible);
+ makeDirty();
+ return true;
+}
+
+bool CWheelButton::LeaveViewMsg(CLeaveViewMsg *msg) {
+ if (_timerId) {
+ stopAnimTimer(_timerId);
+ _timerId = 0;
+ setVisible(false);
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/wheel_button.h b/engines/titanic/game/wheel_button.h
index cb089a660f..2725e60622 100644
--- a/engines/titanic/game/wheel_button.h
+++ b/engines/titanic/game/wheel_button.h
@@ -28,9 +28,13 @@
namespace Titanic {
class CWheelButton : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool SignalObject(CSignalObject *msg);
+ bool TimerMsg(CTimerMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
public:
- int _fieldE0;
- int _fieldE4;
+ bool _fieldE0;
+ int _timerId;
int _fieldE8;
public:
CLASSDEF;
diff --git a/engines/titanic/game/wheel_hotspot.cpp b/engines/titanic/game/wheel_hotspot.cpp
index f9af594cd5..544e6f5470 100644
--- a/engines/titanic/game/wheel_hotspot.cpp
+++ b/engines/titanic/game/wheel_hotspot.cpp
@@ -24,6 +24,11 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CWheelHotSpot, CBackground)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(SignalObject)
+END_MESSAGE_MAP()
+
void CWheelHotSpot::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_fieldE0, indent);
@@ -40,4 +45,39 @@ void CWheelHotSpot::load(SimpleFile *file) {
CBackground::load(file);
}
+bool CWheelHotSpot::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (_fieldE0) {
+ CActMsg actMsg;
+
+ switch (_fieldE4) {
+ case 1:
+ actMsg._action = "Stop";
+ actMsg.execute("CaptainsWheel");
+ break;
+
+ case 2:
+ actMsg._action = "Cruise";
+ actMsg.execute("CaptainsWheel");
+ break;
+
+ case 3:
+ actMsg._action = "Go";
+ actMsg.execute("CaptainsWheel");
+ break;
+
+ default:
+ break;
+ }
+ } else if (_fieldE4 == 3) {
+ petDisplayMessage("Go where?");
+ }
+
+ return true;
+}
+
+bool CWheelHotSpot::SignalObject(CSignalObject *msg) {
+ _fieldE0 = msg->_numValue != 0;
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/wheel_hotspot.h b/engines/titanic/game/wheel_hotspot.h
index 364fe9a060..e9071a2fa4 100644
--- a/engines/titanic/game/wheel_hotspot.h
+++ b/engines/titanic/game/wheel_hotspot.h
@@ -28,6 +28,9 @@
namespace Titanic {
class CWheelHotSpot : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool SignalObject(CSignalObject *msg);
public:
int _fieldE0;
int _fieldE4;
diff --git a/engines/titanic/game/wheel_spin.cpp b/engines/titanic/game/wheel_spin.cpp
index daa9918e29..79f83873e1 100644
--- a/engines/titanic/game/wheel_spin.cpp
+++ b/engines/titanic/game/wheel_spin.cpp
@@ -24,16 +24,36 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CWheelSpin, CBackground)
+ ON_MESSAGE(SignalObject)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
void CWheelSpin::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_value, indent);
+ file->writeNumberLine(_active, indent);
CBackground::save(file, indent);
}
void CWheelSpin::load(SimpleFile *file) {
file->readNumber();
- _value = file->readNumber();
+ _active = file->readNumber();
CBackground::load(file);
}
+bool CWheelSpin::SignalObject(CSignalObject *msg) {
+ _active = msg->_numValue != 0;
+ setVisible(_active);
+ return true;
+}
+
+bool CWheelSpin::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (_active) {
+ CActMsg actMsg("Spin");
+ actMsg.execute("CaptainsWheel");
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/game/wheel_spin.h b/engines/titanic/game/wheel_spin.h
index 509db1a4bf..f7993f0188 100644
--- a/engines/titanic/game/wheel_spin.h
+++ b/engines/titanic/game/wheel_spin.h
@@ -28,11 +28,14 @@
namespace Titanic {
class CWheelSpin : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool SignalObject(CSignalObject *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
public:
- int _value;
+ bool _active;
public:
CLASSDEF;
- CWheelSpin() : CBackground(), _value(0) {}
+ CWheelSpin() : CBackground(), _active(false) {}
/**
* Save the data for the class to file
diff --git a/engines/titanic/game_manager.cpp b/engines/titanic/game_manager.cpp
index 73ec5de993..7d9dc37a10 100644
--- a/engines/titanic/game_manager.cpp
+++ b/engines/titanic/game_manager.cpp
@@ -164,7 +164,7 @@ void CGameManager::update() {
frameMessage(getRoom());
_timers.update(g_vm->_events->getTicksCount());
_trueTalkManager.removeCompleted();
- _trueTalkManager.update2();
+
CScreenManager::_screenManagerPtr->_mouseCursor->update();
CViewItem *view = getView();
diff --git a/engines/titanic/game_state.cpp b/engines/titanic/game_state.cpp
index 5628161558..8814dba831 100644
--- a/engines/titanic/game_state.cpp
+++ b/engines/titanic/game_state.cpp
@@ -47,7 +47,7 @@ bool CGameStateMovieList::clear() {
CGameState::CGameState(CGameManager *gameManager) :
_gameManager(gameManager), _gameLocation(this),
_passengerClass(0), _priorClass(0), _mode(GSMODE_NONE),
- _field14(0), _petActive(false), _field1C(false), _quitGame(false),
+ _seasonNum(SEASON_SUMMER), _petActive(false), _field1C(false), _quitGame(false),
_field24(0), _nodeChangeCtr(0), _nodeEnterTicks(0), _field38(0) {
}
@@ -55,7 +55,7 @@ void CGameState::save(SimpleFile *file) const {
file->writeNumber(_petActive);
file->writeNumber(_passengerClass);
file->writeNumber(_priorClass);
- file->writeNumber(_field14);
+ file->writeNumber(_seasonNum);
file->writeNumber(_field24);
file->writeNumber(_field38);
_gameLocation.save(file);
@@ -66,7 +66,7 @@ void CGameState::load(SimpleFile *file) {
_petActive = file->readNumber() != 0;
_passengerClass = file->readNumber();
_priorClass = file->readNumber();
- _field14 = file->readNumber();
+ _seasonNum = (Season)file->readNumber();
_field24 = file->readNumber();
_field38 = file->readNumber();
_gameLocation.load(file);
diff --git a/engines/titanic/game_state.h b/engines/titanic/game_state.h
index 0bfa0d5b31..70d47b55c1 100644
--- a/engines/titanic/game_state.h
+++ b/engines/titanic/game_state.h
@@ -35,7 +35,14 @@ class CGameManager;
enum GameStateMode {
GSMODE_NONE = 0, GSMODE_INTERACTIVE = 1, GSMODE_CUTSCENE = 2,
- GSMODE_3 = 3, GSMODE_4 = 4, GSMODE_5 = 5, GSMODE_PENDING_LOAD = 6
+ GSMODE_3 = 3, GSMODE_4 = 4, GSMODE_INSERT_CD = 5, GSMODE_PENDING_LOAD = 6
+};
+
+enum Season {
+ SEASON_SUMMER = 0,
+ SEASON_AUTUMN = 1,
+ SEASON_WINTER = 2,
+ SEASON_SPRING = 3
};
PTR_LIST_ITEM(CMovie);
@@ -60,7 +67,7 @@ public:
int _passengerClass;
int _priorClass;
GameStateMode _mode;
- int _field14;
+ Season _seasonNum;
bool _petActive;
bool _field1C;
bool _quitGame;
@@ -127,7 +134,13 @@ public:
*/
void addMovie(CMovie *movie);
- void inc14() { _field14 = (_field14 + 1) & 3; }
+ /**
+ * Change to the next season
+ */
+ void changeSeason() {
+ _seasonNum = (Season)(((int)_seasonNum + 1) & 3);
+ }
+
void set24(int v) { _field24 = v; }
int get24() const { return _field24; }
int getNodeChangedCtr() const { return _nodeChangeCtr; }
diff --git a/engines/titanic/gfx/edit_control.cpp b/engines/titanic/gfx/edit_control.cpp
index 4098220c3a..3f3c4d4035 100644
--- a/engines/titanic/gfx/edit_control.cpp
+++ b/engines/titanic/gfx/edit_control.cpp
@@ -190,8 +190,8 @@ bool CEditControl::EditControlMsg(CEditControlMsg *msg) {
case 14: {
makeDirty();
- CString borderName = _fieldF4 ? CString('*', _text.size()) : _text;
- setTextBorder(borderName);
+ CString str = _fieldF4 ? CString('*', _text.size()) : _text;
+ setText(str);
int textWidth = getTextWidth();
if (_fieldF0 == 2) {
diff --git a/engines/titanic/gfx/move_object_button.cpp b/engines/titanic/gfx/move_object_button.cpp
index bdc90a673c..bcd2b2bd76 100644
--- a/engines/titanic/gfx/move_object_button.cpp
+++ b/engines/titanic/gfx/move_object_button.cpp
@@ -21,9 +21,14 @@
*/
#include "titanic/gfx/move_object_button.h"
+#include "titanic/core/project_item.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMoveObjectButton, CSTButton)
+ ON_MESSAGE(MouseButtonUpMsg)
+END_MESSAGE_MAP()
+
CMoveObjectButton::CMoveObjectButton() : CSTButton(), _field11C(1) {
}
@@ -43,4 +48,14 @@ void CMoveObjectButton::load(SimpleFile *file) {
CSTButton::load(file);
}
+bool CMoveObjectButton::MouseButtonUpMsg(CMouseButtonUpMsg *msg) {
+ CGameObject *obj = dynamic_cast<CGameObject *>(getRoot()->findByName(_actionTarget));
+ if (obj) {
+ obj->petAddToInventory();
+ obj->setVisible(_field11C);
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/gfx/move_object_button.h b/engines/titanic/gfx/move_object_button.h
index eb2fdc4ff2..46c49c36e2 100644
--- a/engines/titanic/gfx/move_object_button.h
+++ b/engines/titanic/gfx/move_object_button.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CMoveObjectButton : public CSTButton {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonUpMsg(CMouseButtonUpMsg *msg);
private:
Point _pos1;
int _field11C;
diff --git a/engines/titanic/gfx/music_control.cpp b/engines/titanic/gfx/music_control.cpp
index 85a3d777ef..317bec209f 100644
--- a/engines/titanic/gfx/music_control.cpp
+++ b/engines/titanic/gfx/music_control.cpp
@@ -24,15 +24,20 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMusicControl, CBackground)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(MouseDoubleClickMsg)
+END_MESSAGE_MAP()
+
CMusicControl::CMusicControl() : CBackground(),
- _fieldE0(0), _fieldE4(0), _fieldE8(1), _fieldEC(1) {
+ _controlArea(BELLS), _controlVal(0), _controlMax(1), _fieldEC(1) {
}
void CMusicControl::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldE0, indent);
- file->writeNumberLine(_fieldE4, indent);
- file->writeNumberLine(_fieldE8, indent);
+ file->writeNumberLine(_controlArea, indent);
+ file->writeNumberLine(_controlVal, indent);
+ file->writeNumberLine(_controlMax, indent);
file->writeNumberLine(_fieldEC, indent);
CBackground::save(file, indent);
@@ -40,12 +45,24 @@ void CMusicControl::save(SimpleFile *file, int indent) {
void CMusicControl::load(SimpleFile *file) {
file->readNumber();
- _fieldE0 = file->readNumber();
- _fieldE4 = file->readNumber();
- _fieldE8 = file->readNumber();
+ _controlArea = (MusicControlArea)file->readNumber();
+ _controlVal = file->readNumber();
+ _controlMax = file->readNumber();
_fieldEC = file->readNumber();
CBackground::load(file);
}
+bool CMusicControl::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ CMusicSettingChangedMsg changedMsg;
+ changedMsg.execute(this);
+ return true;
+}
+
+bool CMusicControl::MouseDoubleClickMsg(CMouseDoubleClickMsg *msg) {
+ CMusicSettingChangedMsg changedMsg;
+ changedMsg.execute(this);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/gfx/music_control.h b/engines/titanic/gfx/music_control.h
index 04085f789c..a0e73392f9 100644
--- a/engines/titanic/gfx/music_control.h
+++ b/engines/titanic/gfx/music_control.h
@@ -24,14 +24,18 @@
#define TITANIC_MUSIC_CONTROL_H
#include "titanic/core/background.h"
+#include "titanic/sound/music_room.h"
namespace Titanic {
class CMusicControl : public CBackground {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool MouseDoubleClickMsg(CMouseDoubleClickMsg *msg);
public:
- int _fieldE0;
- int _fieldE4;
- int _fieldE8;
+ MusicControlArea _controlArea;
+ int _controlVal;
+ int _controlMax;
int _fieldEC;
public:
CLASSDEF;
diff --git a/engines/titanic/gfx/music_slider_pitch.cpp b/engines/titanic/gfx/music_slider_pitch.cpp
new file mode 100644
index 0000000000..5f0432e742
--- /dev/null
+++ b/engines/titanic/gfx/music_slider_pitch.cpp
@@ -0,0 +1,67 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "titanic/gfx/music_slider_pitch.h"
+
+namespace Titanic {
+
+BEGIN_MESSAGE_MAP(CMusicSliderPitch, CMusicSlider)
+ ON_MESSAGE(MusicSettingChangedMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(QueryMusicControlSettingMsg)
+END_MESSAGE_MAP()
+
+void CMusicSliderPitch::save(SimpleFile *file, int indent) {
+ file->writeNumberLine(1, indent);
+ CMusicSlider::save(file, indent);
+}
+
+void CMusicSliderPitch::load(SimpleFile *file) {
+ file->readNumber();
+ CMusicSlider::load(file);
+}
+
+bool CMusicSliderPitch::MusicSettingChangedMsg(CMusicSettingChangedMsg *msg) {
+ if (_fieldEC) {
+ if (++_controlVal > _controlMax)
+ _controlVal = 0;
+
+ loadFrame(3 - _controlVal);
+ playSound("z#54.wav", 50);
+ } else {
+ playSound("z#46.wav");
+ }
+
+ return true;
+}
+
+bool CMusicSliderPitch::EnterViewMsg(CEnterViewMsg *msg) {
+ loadFrame(3 - _controlVal);
+ return true;
+}
+
+bool CMusicSliderPitch::QueryMusicControlSettingMsg(CQueryMusicControlSettingMsg *msg) {
+ msg->_value = _controlVal - 2;
+ return true;
+}
+
+} // End of namespace Titanic
diff --git a/engines/titanic/gfx/music_slider_pitch.h b/engines/titanic/gfx/music_slider_pitch.h
index 10c1d62c3a..c375c6db33 100644
--- a/engines/titanic/gfx/music_slider_pitch.h
+++ b/engines/titanic/gfx/music_slider_pitch.h
@@ -28,24 +28,22 @@
namespace Titanic {
class CMusicSliderPitch : public CMusicSlider {
+ DECLARE_MESSAGE_MAP;
+ bool MusicSettingChangedMsg(CMusicSettingChangedMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool QueryMusicControlSettingMsg(CQueryMusicControlSettingMsg *msg);
public:
CLASSDEF;
/**
* Save the data for the class to file
*/
- virtual void save(SimpleFile *file, int indent) {
- file->writeNumberLine(1, indent);
- CMusicSlider::save(file, indent);
- }
+ virtual void save(SimpleFile *file, int indent);
/**
* Load the data for the class from file
*/
- virtual void load(SimpleFile *file) {
- file->readNumber();
- CMusicSlider::load(file);
- }
+ virtual void load(SimpleFile *file);
};
} // End of namespace Titanic
diff --git a/engines/titanic/gfx/music_slider_speed.cpp b/engines/titanic/gfx/music_slider_speed.cpp
new file mode 100644
index 0000000000..93af5d82b7
--- /dev/null
+++ b/engines/titanic/gfx/music_slider_speed.cpp
@@ -0,0 +1,67 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "titanic/gfx/music_slider_speed.h"
+
+namespace Titanic {
+
+BEGIN_MESSAGE_MAP(CMusicSliderSpeed, CMusicSlider)
+ ON_MESSAGE(MusicSettingChangedMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(QueryMusicControlSettingMsg)
+END_MESSAGE_MAP()
+
+void CMusicSliderSpeed::save(SimpleFile *file, int indent) {
+ file->writeNumberLine(1, indent);
+ CMusicSlider::save(file, indent);
+}
+
+void CMusicSliderSpeed::load(SimpleFile *file) {
+ file->readNumber();
+ CMusicSlider::load(file);
+}
+
+bool CMusicSliderSpeed::MusicSettingChangedMsg(CMusicSettingChangedMsg *msg) {
+ if (_fieldEC) {
+ if (++_controlVal > _controlMax)
+ _controlVal = 0;
+
+ loadFrame(3 - _controlVal);
+ playSound("z#54.wav", 50);
+ } else {
+ playSound("z#46.wav");
+ }
+
+ return true;
+}
+
+bool CMusicSliderSpeed::EnterViewMsg(CEnterViewMsg *msg) {
+ loadFrame(3 - _controlVal);
+ return true;
+}
+
+bool CMusicSliderSpeed::QueryMusicControlSettingMsg(CQueryMusicControlSettingMsg *msg) {
+ msg->_value = _controlVal - 1;
+ return true;
+}
+
+} // End of namespace Titanic
diff --git a/engines/titanic/gfx/music_slider_speed.h b/engines/titanic/gfx/music_slider_speed.h
index 9814ca0312..2d54f4487c 100644
--- a/engines/titanic/gfx/music_slider_speed.h
+++ b/engines/titanic/gfx/music_slider_speed.h
@@ -27,26 +27,24 @@
namespace Titanic {
- class CMusicSliderSpeed : public CMusicSlider {
- public:
- CLASSDEF;
-
- /**
- * Save the data for the class to file
- */
- virtual void save(SimpleFile *file, int indent) {
- file->writeNumberLine(1, indent);
- CMusicSlider::save(file, indent);
- }
-
- /**
- * Load the data for the class from file
- */
- virtual void load(SimpleFile *file) {
- file->readNumber();
- CMusicSlider::load(file);
- }
- };
+class CMusicSliderSpeed : public CMusicSlider {
+ DECLARE_MESSAGE_MAP;
+ bool MusicSettingChangedMsg(CMusicSettingChangedMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool QueryMusicControlSettingMsg(CQueryMusicControlSettingMsg *msg);
+public:
+ CLASSDEF;
+
+ /**
+ * Save the data for the class to file
+ */
+ virtual void save(SimpleFile *file, int indent);
+
+ /**
+ * Load the data for the class from file
+ */
+ virtual void load(SimpleFile *file);
+};
} // End of namespace Titanic
diff --git a/engines/titanic/gfx/chev_switch.cpp b/engines/titanic/gfx/music_switch_inversion.cpp
index 177f0ada76..d11df79ab4 100644
--- a/engines/titanic/gfx/chev_switch.cpp
+++ b/engines/titanic/gfx/music_switch_inversion.cpp
@@ -20,58 +20,47 @@
*
*/
-#include "titanic/gfx/chev_switch.h"
+#include "titanic/gfx/music_switch_inversion.h"
namespace Titanic {
-BEGIN_MESSAGE_MAP(CChevSwitch, CToggleSwitch)
- ON_MESSAGE(MouseButtonUpMsg)
- ON_MESSAGE(SetChevButtonImageMsg)
- ON_MESSAGE(MouseButtonDownMsg)
+BEGIN_MESSAGE_MAP(CMusicSwitchInversion, CMusicSwitch)
+ ON_MESSAGE(MusicSettingChangedMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(QueryMusicControlSettingMsg)
END_MESSAGE_MAP()
-CChevSwitch::CChevSwitch() : CToggleSwitch(), _value(0) {
-}
-
-void CChevSwitch::save(SimpleFile *file, int indent) {
+void CMusicSwitchInversion::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- CToggleSwitch::save(file, indent);
+ CMusicSwitch::save(file, indent);
}
-void CChevSwitch::load(SimpleFile *file) {
+void CMusicSwitchInversion::load(SimpleFile *file) {
file->readNumber();
- CToggleSwitch::load(file);
-}
-
-bool CChevSwitch::MouseButtonUpMsg(CMouseButtonUpMsg *msg) {
- return true;
+ CMusicSwitch::load(file);
}
-bool CChevSwitch::SetChevButtonImageMsg(CSetChevButtonImageMsg *msg) {
- if (msg->_value2 && getParent()) {
- error("TODO: Don't know parent type");
- }
+bool CMusicSwitchInversion::MusicSettingChangedMsg(CMusicSettingChangedMsg *msg) {
+ if (_fieldEC) {
+ if (++_controlVal > _controlMax)
+ _controlVal = 0;
- _fieldBC = msg->_value1;
- if (_fieldBC) {
- loadImage((_value & 1) ? "on_odd.tga" : "on_even.tga");
+ loadFrame(_controlVal);
+ playSound("z#59.wav", 50);
} else {
- loadImage((_value & 1) ? "off_odd.tga" : "off_even.tga");
+ playSound("z#46.wav");
}
return true;
}
-bool CChevSwitch::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
- _fieldBC ^= 1;
- if (getParent()) {
- CSetChevPanelBitMsg bitMsg(_value, _fieldBC);
- bitMsg.execute(getParent());
- }
-
- CSetChevButtonImageMsg chevMsg(_fieldBC, 0);
- chevMsg.execute(this);
+bool CMusicSwitchInversion::EnterViewMsg(CEnterViewMsg *msg) {
+ loadFrame(_controlVal);
+ return true;
+}
+bool CMusicSwitchInversion::QueryMusicControlSettingMsg(CQueryMusicControlSettingMsg *msg) {
+ msg->_value = _controlVal;
return true;
}
diff --git a/engines/titanic/gfx/music_switch_inversion.h b/engines/titanic/gfx/music_switch_inversion.h
index 8b3718cf14..869b4745ea 100644
--- a/engines/titanic/gfx/music_switch_inversion.h
+++ b/engines/titanic/gfx/music_switch_inversion.h
@@ -28,24 +28,22 @@
namespace Titanic {
class CMusicSwitchInversion : public CMusicSwitch {
+ DECLARE_MESSAGE_MAP;
+ bool MusicSettingChangedMsg(CMusicSettingChangedMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool QueryMusicControlSettingMsg(CQueryMusicControlSettingMsg *msg);
public:
CLASSDEF;
/**
* Save the data for the class to file
*/
- virtual void save(SimpleFile *file, int indent) {
- file->writeNumberLine(1, indent);
- CMusicSwitch::save(file, indent);
- }
+ virtual void save(SimpleFile *file, int indent);
/**
* Load the data for the class from file
*/
- virtual void load(SimpleFile *file) {
- file->readNumber();
- CMusicSwitch::load(file);
- }
+ virtual void load(SimpleFile *file);
};
} // End of namespace Titanic
diff --git a/engines/titanic/gfx/music_switch_reverse.cpp b/engines/titanic/gfx/music_switch_reverse.cpp
new file mode 100644
index 0000000000..9fe6d51d47
--- /dev/null
+++ b/engines/titanic/gfx/music_switch_reverse.cpp
@@ -0,0 +1,66 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "titanic/gfx/music_switch_reverse.h"
+
+namespace Titanic {
+
+BEGIN_MESSAGE_MAP(CMusicSwitchReverse, CMusicSwitch)
+ ON_MESSAGE(MusicSettingChangedMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(QueryMusicControlSettingMsg)
+END_MESSAGE_MAP()
+
+void CMusicSwitchReverse::save(SimpleFile *file, int indent) {
+ file->writeNumberLine(1, indent);
+ CMusicSwitch::save(file, indent);
+}
+
+void CMusicSwitchReverse::load(SimpleFile *file) {
+ file->readNumber();
+ CMusicSwitch::load(file);
+}
+bool CMusicSwitchReverse::MusicSettingChangedMsg(CMusicSettingChangedMsg *msg) {
+ if (_fieldEC) {
+ if (++_controlVal > _controlMax)
+ _controlVal = 0;
+
+ loadFrame(_controlVal);
+ playSound("z#59.wav", 50);
+ } else {
+ playSound("z#46.wav");
+ }
+
+ return true;
+}
+
+bool CMusicSwitchReverse::EnterViewMsg(CEnterViewMsg *msg) {
+ loadFrame(_controlVal);
+ return true;
+}
+
+bool CMusicSwitchReverse::QueryMusicControlSettingMsg(CQueryMusicControlSettingMsg *msg) {
+ msg->_value = _controlVal;
+ return true;
+}
+
+} // End of namespace Titanic
diff --git a/engines/titanic/gfx/music_switch_reverse.h b/engines/titanic/gfx/music_switch_reverse.h
index 3bfcb53b00..c101f19d25 100644
--- a/engines/titanic/gfx/music_switch_reverse.h
+++ b/engines/titanic/gfx/music_switch_reverse.h
@@ -27,26 +27,24 @@
namespace Titanic {
- class CMusicSwitchReverse : public CMusicSwitch {
- public:
- CLASSDEF;
-
- /**
- * Save the data for the class to file
- */
- virtual void save(SimpleFile *file, int indent) {
- file->writeNumberLine(1, indent);
- CMusicSwitch::save(file, indent);
- }
-
- /**
- * Load the data for the class from file
- */
- virtual void load(SimpleFile *file) {
- file->readNumber();
- CMusicSwitch::load(file);
- }
- };
+class CMusicSwitchReverse : public CMusicSwitch {
+ DECLARE_MESSAGE_MAP;
+ bool MusicSettingChangedMsg(CMusicSettingChangedMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool QueryMusicControlSettingMsg(CQueryMusicControlSettingMsg *msg);
+public:
+ CLASSDEF;
+
+ /**
+ * Save the data for the class to file
+ */
+ virtual void save(SimpleFile *file, int indent);
+
+ /**
+ * Load the data for the class from file
+ */
+ virtual void load(SimpleFile *file);
+};
} // End of namespace Titanic
diff --git a/engines/titanic/gfx/music_voice_mute.cpp b/engines/titanic/gfx/music_voice_mute.cpp
new file mode 100644
index 0000000000..ff59edc988
--- /dev/null
+++ b/engines/titanic/gfx/music_voice_mute.cpp
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "titanic/gfx/music_voice_mute.h"
+#include "titanic/sound/music_room.h"
+
+namespace Titanic {
+
+BEGIN_MESSAGE_MAP(CMusicVoiceMute, CMusicControl)
+ ON_MESSAGE(MusicSettingChangedMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(QueryMusicControlSettingMsg)
+END_MESSAGE_MAP()
+
+bool CMusicVoiceMute::MusicSettingChangedMsg(CMusicSettingChangedMsg *msg) {
+ if (++_controlVal > _controlMax)
+ _controlVal = 0;
+
+ CMusicRoom *musicRoom = getMusicRoom();
+ musicRoom->setItem5(_controlArea, _controlVal == 1 ? 1 : 0);
+ loadFrame(1 - _controlVal);
+ playSound("z#55.wav", 50);
+
+ return true;
+}
+
+bool CMusicVoiceMute::EnterViewMsg(CEnterViewMsg *msg) {
+ loadFrame(1 - _controlVal);
+ CMusicRoom *musicRoom = getMusicRoom();
+ musicRoom->setItem5(_controlArea, _controlVal == 1 ? 1 : 0);
+
+ return true;
+}
+
+bool CMusicVoiceMute::QueryMusicControlSettingMsg(CQueryMusicControlSettingMsg *msg) {
+ msg->_value = _controlVal;
+ return true;
+}
+
+} // End of namespace Titanic
diff --git a/engines/titanic/gfx/music_voice_mute.h b/engines/titanic/gfx/music_voice_mute.h
index ca15806c09..f64b107423 100644
--- a/engines/titanic/gfx/music_voice_mute.h
+++ b/engines/titanic/gfx/music_voice_mute.h
@@ -28,6 +28,10 @@
namespace Titanic {
class CMusicVoiceMute : public CMusicControl {
+ DECLARE_MESSAGE_MAP;
+ bool MusicSettingChangedMsg(CMusicSettingChangedMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool QueryMusicControlSettingMsg(CQueryMusicControlSettingMsg *msg);
public:
CLASSDEF;
diff --git a/engines/titanic/gfx/slider_button.cpp b/engines/titanic/gfx/slider_button.cpp
index 0633158e97..b3dbbed08f 100644
--- a/engines/titanic/gfx/slider_button.cpp
+++ b/engines/titanic/gfx/slider_button.cpp
@@ -24,6 +24,14 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CSliderButton, CSTButton)
+ ON_MESSAGE(MouseButtonUpMsg)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(MouseDragMoveMsg)
+ ON_MESSAGE(StatusChangeMsg)
+ ON_MESSAGE(EnterViewMsg)
+END_MESSAGE_MAP()
+
CSliderButton::CSliderButton() : CSTButton(), _field114(0),
_field118(0), _field11C(0) {
}
@@ -48,4 +56,39 @@ void CSliderButton::load(SimpleFile *file) {
CSTButton::load(file);
}
+bool CSliderButton::MouseButtonUpMsg(CMouseButtonUpMsg *msg) {
+ _pos1 = msg->_mousePos;
+ CStatusChangeMsg changeMsg;
+ changeMsg.execute(this);
+ return true;
+}
+
+bool CSliderButton::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ _pos1 = msg->_mousePos;
+ return true;
+}
+
+bool CSliderButton::MouseDragMoveMsg(CMouseDragMoveMsg *msg) {
+ _pos1 = msg->_mousePos;
+ if (_field118) {
+ CStatusChangeMsg changeMsg;
+ changeMsg.execute(this);
+ }
+
+ return true;
+}
+
+bool CSliderButton::StatusChangeMsg(CStatusChangeMsg *msg) {
+ CStatusChangeMsg changeMsg;
+ changeMsg._oldStatus = _currentStatus;
+ _currentStatus = (_pos1.y - _bounds.top) / _field11C;
+ changeMsg._newStatus = _currentStatus;
+ changeMsg.execute(_actionTarget);
+ return true;
+}
+
+bool CSliderButton::EnterViewMsg(CEnterViewMsg *msg) {
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/gfx/slider_button.h b/engines/titanic/gfx/slider_button.h
index 398290bb05..18ebbae3db 100644
--- a/engines/titanic/gfx/slider_button.h
+++ b/engines/titanic/gfx/slider_button.h
@@ -28,6 +28,12 @@
namespace Titanic {
class CSliderButton : public CSTButton {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonUpMsg(CMouseButtonUpMsg *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool MouseDragMoveMsg(CMouseDragMoveMsg *msg);
+ bool StatusChangeMsg(CStatusChangeMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
private:
int _field114;
int _field118;
diff --git a/engines/titanic/gfx/status_change_button.cpp b/engines/titanic/gfx/status_change_button.cpp
index 6644247ff2..e38f1ee07e 100644
--- a/engines/titanic/gfx/status_change_button.cpp
+++ b/engines/titanic/gfx/status_change_button.cpp
@@ -24,6 +24,10 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CStatusChangeButton, CSTButton)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
CStatusChangeButton::CStatusChangeButton() : CSTButton() {
}
@@ -37,4 +41,11 @@ void CStatusChangeButton::load(SimpleFile *file) {
CSTButton::load(file);
}
+bool CStatusChangeButton::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ CStatusChangeMsg changeMsg;
+ changeMsg._newStatus = _statusInc;
+ changeMsg.execute(_actionTarget);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/gfx/status_change_button.h b/engines/titanic/gfx/status_change_button.h
index 9e410c66f2..9d187493a7 100644
--- a/engines/titanic/gfx/status_change_button.h
+++ b/engines/titanic/gfx/status_change_button.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CStatusChangeButton : public CSTButton {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
public:
CLASSDEF;
CStatusChangeButton();
diff --git a/engines/titanic/gfx/toggle_button.h b/engines/titanic/gfx/toggle_button.h
index 5328072982..4fb7cdfaba 100644
--- a/engines/titanic/gfx/toggle_button.h
+++ b/engines/titanic/gfx/toggle_button.h
@@ -29,7 +29,7 @@ namespace Titanic {
class CToggleButton : public CBackground {
DECLARE_MESSAGE_MAP;
-private:
+protected:
int _fieldE0;
public:
CLASSDEF;
diff --git a/engines/titanic/gfx/toggle_switch.cpp b/engines/titanic/gfx/toggle_switch.cpp
index 20cbb863ee..815f96cb5a 100644
--- a/engines/titanic/gfx/toggle_switch.cpp
+++ b/engines/titanic/gfx/toggle_switch.cpp
@@ -24,12 +24,18 @@
namespace Titanic {
-CToggleSwitch::CToggleSwitch() : CGameObject(), _fieldBC(0) {
+BEGIN_MESSAGE_MAP(CToggleSwitch, CGameObject)
+ ON_MESSAGE(MouseButtonUpMsg)
+ ON_MESSAGE(ChildDragStartMsg)
+ ON_MESSAGE(ChildDragMoveMsg)
+END_MESSAGE_MAP()
+
+CToggleSwitch::CToggleSwitch() : CGameObject(), _pressed(false) {
}
void CToggleSwitch::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldBC, indent);
+ file->writeNumberLine(_pressed, indent);
file->writePoint(_pos1, indent);
CGameObject::save(file, indent);
@@ -37,10 +43,30 @@ void CToggleSwitch::save(SimpleFile *file, int indent) {
void CToggleSwitch::load(SimpleFile *file) {
file->readNumber();
- _fieldBC = file->readNumber();
+ _pressed = file->readNumber();
_pos1 = file->readPoint();
CGameObject::load(file);
}
+bool CToggleSwitch::MouseButtonUpMsg(CMouseButtonUpMsg *msg) {
+ _pressed = !_pressed;
+ if (_pressed)
+ fn10(0, 0, 0);
+ else
+ fn10(0xff, 0xff, 0xff);
+ return true;
+}
+
+bool CToggleSwitch::ChildDragStartMsg(CChildDragStartMsg *msg) {
+ _pos1.x = msg->_mousePos.x - _bounds.left;
+ _pos1.y = msg->_mousePos.y - _bounds.top;
+ return true;
+}
+
+bool CToggleSwitch::ChildDragMoveMsg(CChildDragMoveMsg *msg) {
+ setPosition(Point(msg->_mousePos.x - _pos1.x, msg->_mousePos.y - _pos1.y));
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/gfx/toggle_switch.h b/engines/titanic/gfx/toggle_switch.h
index 8e7d057d8c..69b8c50eec 100644
--- a/engines/titanic/gfx/toggle_switch.h
+++ b/engines/titanic/gfx/toggle_switch.h
@@ -28,8 +28,12 @@
namespace Titanic {
class CToggleSwitch : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonUpMsg(CMouseButtonUpMsg *msg);
+ bool ChildDragStartMsg(CChildDragStartMsg *msg);
+ bool ChildDragMoveMsg(CChildDragMoveMsg *msg);
protected:
- int _fieldBC;
+ bool _pressed;
Point _pos1;
public:
CLASSDEF;
diff --git a/engines/titanic/main_game_window.cpp b/engines/titanic/main_game_window.cpp
index 486bc417d7..690acdc25f 100644
--- a/engines/titanic/main_game_window.cpp
+++ b/engines/titanic/main_game_window.cpp
@@ -49,19 +49,24 @@ CMainGameWindow::CMainGameWindow(TitanicEngine *vm): _vm(vm),
CMainGameWindow::~CMainGameWindow() {
}
-bool CMainGameWindow::Create() {
- Image image;
- image.load("TITANIC");
-
- // TODO: Stuff
- return true;
-}
-
void CMainGameWindow::applicationStarting() {
// Set the video mode
CScreenManager *screenManager = CScreenManager::setCurrent();
screenManager->setMode(640, 480, 16, 0, true);
+#if 0
+ // Show the initial copyright & info screen for the game
+ if (gDebugLevel <= 0) {
+ Image image;
+ image.load("Bitmap/TITANIC");
+ _vm->_screen->blitFrom(image, Point(
+ SCREEN_WIDTH / 2 - image.w / 2,
+ SCREEN_HEIGHT / 2 - image.h / 2
+ ));
+ _vm->_events->sleep(5000);
+ }
+#endif
+
// Set up the game project, and get game slot
int saveSlot = getSavegameSlot();
if (saveSlot == -2)
@@ -77,8 +82,6 @@ void CMainGameWindow::applicationStarting() {
_inputAllowed = true;
_gameManager->_gameState.setMode(GSMODE_INTERACTIVE);
- // TODO: Cursor/image
-
// Generate starting messages for entering the view, node, and room.
// Note the old fields are nullptr, since there's no previous view/node/room
CViewItem *view = _gameManager->_gameState._gameLocation.getView();
@@ -157,8 +160,9 @@ void CMainGameWindow::draw() {
scrManager->drawCursors();
break;
- case GSMODE_5:
- g_vm->_filesManager->debug(scrManager);
+ case GSMODE_INSERT_CD:
+ scrManager->drawCursors();
+ _vm->_filesManager->insertCD(scrManager);
break;
case GSMODE_PENDING_LOAD:
@@ -216,7 +220,7 @@ void CMainGameWindow::drawViewContents(CScreenManager *screenManager) {
}
void CMainGameWindow::mouseChanged() {
- if (_gameManager->_gameState._mode != GSMODE_5)
+ if (_gameManager->_gameState._mode != GSMODE_INSERT_CD)
_gameManager->update();
}
diff --git a/engines/titanic/main_game_window.h b/engines/titanic/main_game_window.h
index 82e24e250e..070f7df69b 100644
--- a/engines/titanic/main_game_window.h
+++ b/engines/titanic/main_game_window.h
@@ -104,11 +104,6 @@ public:
virtual void keyUp(Common::KeyState keyState);
/**
- * Creates the window
- */
- bool Create();
-
- /**
* Called when the application starts
*/
void applicationStarting();
diff --git a/engines/titanic/messages/messages.h b/engines/titanic/messages/messages.h
index fa05416fdc..b70bc5e16c 100644
--- a/engines/titanic/messages/messages.h
+++ b/engines/titanic/messages/messages.h
@@ -189,7 +189,7 @@ MESSAGE1(CAnimateMaitreDMsg, int, value, 0);
MESSAGE1(CArboretumGateMsg, int, value, 0);
MESSAGE0(CArmPickedUpFromTableMsg);
MESSAGE0(CBodyInBilgeRoomMsg);
-MESSAGE1(CBowlStateChangeMsg, int, value, 0);
+MESSAGE1(CBowlStateChangeMsg, int, state, 0);
MESSAGE2(CCarryObjectArrivedMsg, CString, strValue, "", int, numValue, 0);
MESSAGE2(CChangeMusicMsg, CString, filename, "", int, flags, 0);
MESSAGE1(CChangeSeasonMsg, CString, season, "Summer");
@@ -245,14 +245,14 @@ MESSAGE1(CLoadSuccessMsg, int, ticks, 0);
MESSAGE1(CLockPhonographMsg, int, value, 0);
MESSAGE0(CMaitreDDefeatedMsg);
MESSAGE0(CMaitreDHappyMsg);
-MESSAGE1(CMissiveOMatActionMsg, int, value, 0);
+MESSAGE1(CMissiveOMatActionMsg, int, action, 0);
MESSAGE0(CMoveToStartPosMsg);
MESSAGE2(CMovieEndMsg, int, startFrame, 0, int, endFrame, 0);
MESSAGE2(CMovieFrameMsg, int, frameNumber, 0, int, value2, 0);
MESSAGE0(CMusicHasStartedMsg);
MESSAGE0(CMusicHasStoppedMsg);
MESSAGE0(CMusicSettingChangedMsg);
-MESSAGE2(CNPCPlayAnimationMsg, const char *const *, names, nullptr, int, value2, 0);
+MESSAGE2(CNPCPlayAnimationMsg, const char *const *, names, nullptr, int, maxDuration, 0);
MESSAGE1(CNPCPlayIdleAnimationMsg, const char *const *, names, 0);
MESSAGE3(CNPCPlayTalkingAnimationMsg, int, value1, 0, int, value2, 0, const char *const *, names, nullptr);
MESSAGE0(CNPCQueueIdleAnimMsg);
@@ -267,14 +267,14 @@ MESSAGE0(CPhonographReadyToPlayMsg);
MESSAGE1(CPhonographRecordMsg, int, value, 0);
MESSAGE3(CPhonographStopMsg, int, value1, 0, int, value2, 0, int, value3, 0);
MESSAGE2(CPlayRangeMsg, int, value1, 0, int, value2, 0);
-MESSAGE2(CPlayerTriesRestaurantTableMsg, int, value1, 0, int, value2, 0);
+MESSAGE2(CPlayerTriesRestaurantTableMsg, int, tableId, 0, bool, result, false);
MESSAGE1(CPreSaveMsg, int, value, 0);
MESSAGE1(CProdMaitreDMsg, int, value, 0);
MESSAGE2(CPumpingMsg, int, value, 0, CGameObject *, object, nullptr);
MESSAGE1(CPutBotBackInHisBoxMsg, int, value, 0);
MESSAGE1(CPutParrotBackMsg, int, value, 0);
MESSAGE0(CPuzzleSolvedMsg);
-MESSAGE3(CQueryCylinderHolderMsg, int, value1, 0, int, value2, 0, int, value3, 0);
+MESSAGE3(CQueryCylinderHolderMsg, int, value1, 0, int, value2, 0, CTreeItem *, target, (CTreeItem *)nullptr);
MESSAGE1(CQueryCylinderMsg, CString, name, "");
MESSAGE1(CQueryCylinderNameMsg, CString, name, "");
MESSAGE3(CQueryCylinderTypeMsg, int, value1, 0, int, value2, 0, int, value3, 0);
@@ -303,10 +303,10 @@ MESSAGE2(CSetVolumeMsg, int, volume, 70, int, secondsTransition, 0);
MESSAGE2(CShipSettingMsg, int, value, 0, CString, name, "");
MESSAGE1(CShowTextMsg, CString, value, "NO TEXT INCLUDED!!!");
MESSAGE2(CSignalObject, CString, strValue, "", int, numValue, 0);
-MESSAGE2(CSpeechFallsFromTreeMsg, int, value1, 0, int, value2, 0);
+MESSAGE1(CSpeechFallsFromTreeMsg, Point, pos, Point());
MESSAGE1(CStartMusicMsg, CMusicPlayer *, musicPlayer, (CMusicPlayer *)nullptr);
MESSAGE3(CStatusChangeMsg, int, oldStatus, 0, int, newStatus, 0, bool, success, false);
-MESSAGE1(CStopMusicMsg, int, value, 0);
+MESSAGE1(CStopMusicMsg, CMusicPlayer *, musicPlayer, (CMusicPlayer *)nullptr);
MESSAGE4(CSubAcceptCCarryMsg, CString, string1, "", int, value1, 0, int, value2, 0, CCarry *, item, nullptr);
MESSAGE0(CSubDeliverCCarryMsg);
MESSAGE0(CSubSendCCarryMsg);
diff --git a/engines/titanic/messages/pet_messages.h b/engines/titanic/messages/pet_messages.h
index 48e5bab64c..60981726ed 100644
--- a/engines/titanic/messages/pet_messages.h
+++ b/engines/titanic/messages/pet_messages.h
@@ -35,7 +35,7 @@ MESSAGE0(CPETLostObjectMsg);
MESSAGE0(CPETObjectSelectedMsg);
MESSAGE1(CPETObjectStateMsg, int, value, 0);
MESSAGE0(CPETPhotoOnOffMsg);
-MESSAGE1(CPETPlaySoundMsg, int, value, 0);
+MESSAGE1(CPETPlaySoundMsg, int, soundNum, 0);
MESSAGE0(CPETReceiveMsg);
MESSAGE0(CPETSetStarDestinationMsg);
MESSAGE1(CPETStarFieldLockMsg, int, value, 0);
diff --git a/engines/titanic/messages/service_elevator_door.cpp b/engines/titanic/messages/service_elevator_door.cpp
index 748790e4aa..7011b1ad44 100644
--- a/engines/titanic/messages/service_elevator_door.cpp
+++ b/engines/titanic/messages/service_elevator_door.cpp
@@ -24,6 +24,10 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CServiceElevatorDoor, CDoorAutoSoundEvent)
+ ON_MESSAGE(PreEnterNodeMsg)
+END_MESSAGE_MAP()
+
CServiceElevatorDoor::CServiceElevatorDoor() : CDoorAutoSoundEvent() {
_string1 = "z#31.wav";
_string2 = "z#32.wav";
@@ -45,4 +49,10 @@ void CServiceElevatorDoor::load(SimpleFile *file) {
CDoorAutoSoundEvent::load(file);
}
+bool CServiceElevatorDoor::PreEnterNodeMsg(CPreEnterNodeMsg *msg) {
+ if (!findRoom()->isEquals("BilgeRoomWith"))
+ CDoorAutoSoundEvent::PreEnterNodeMsg(msg);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/messages/service_elevator_door.h b/engines/titanic/messages/service_elevator_door.h
index cc8da0917d..69ad1e15b9 100644
--- a/engines/titanic/messages/service_elevator_door.h
+++ b/engines/titanic/messages/service_elevator_door.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CServiceElevatorDoor : public CDoorAutoSoundEvent {
+ DECLARE_MESSAGE_MAP;
+ bool PreEnterNodeMsg(CPreEnterNodeMsg *msg);
public:
CLASSDEF;
CServiceElevatorDoor();
diff --git a/engines/titanic/module.mk b/engines/titanic/module.mk
index a3afc7e4a4..793427991d 100644
--- a/engines/titanic/module.mk
+++ b/engines/titanic/module.mk
@@ -157,6 +157,8 @@ MODULE_OBJS := \
game/music_system_lock.o \
game/musical_instrument.o \
game/nav_helmet.o \
+ game/nav_helmet_off.o \
+ game/nav_helmet_on.o \
game/navigation_computer.o \
game/no_nut_bowl.o \
game/nose_holder.o \
@@ -240,7 +242,7 @@ MODULE_OBJS := \
game/pickup/pick_up_speech_centre.o \
game/pickup/pick_up_vis_centre.o \
game/placeholder/bar_shelf_vis_centre.o \
- game/placeholder/place_holder_item.o \
+ game/placeholder/place_holder.o \
game/placeholder/lemon_on_bar.o \
game/placeholder/tv_on_bar.o \
game/transport/gondolier.o \
@@ -275,7 +277,6 @@ MODULE_OBJS := \
gfx/chev_right_off.o \
gfx/chev_right_on.o \
gfx/chev_send_rec_switch.o \
- gfx/chev_switch.o \
gfx/edit_control.o \
gfx/elevator_button.o \
gfx/get_from_succ.o \
@@ -294,7 +295,12 @@ MODULE_OBJS := \
gfx/move_object_button.o \
gfx/music_control.o \
gfx/music_slider.o \
+ gfx/music_slider_pitch.o \
+ gfx/music_slider_speed.o \
gfx/music_switch.o \
+ gfx/music_switch_inversion.o \
+ gfx/music_switch_reverse.o \
+ gfx/music_voice_mute.o \
gfx/send_to_succ.o \
gfx/sgt_selector.o \
gfx/slider_button.o \
@@ -468,6 +474,7 @@ MODULE_OBJS := \
support/screen_manager.o \
support/simple_file.o \
support/string.o \
+ support/string_parser.o \
support/text_cursor.o \
support/time_event_info.o \
support/video_surface.o \
diff --git a/engines/titanic/moves/enter_exit_mini_lift.cpp b/engines/titanic/moves/enter_exit_mini_lift.cpp
index e626d70a9e..3caa674ab8 100644
--- a/engines/titanic/moves/enter_exit_mini_lift.cpp
+++ b/engines/titanic/moves/enter_exit_mini_lift.cpp
@@ -56,7 +56,7 @@ bool CEnterExitMiniLift::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
if (pet)
pet->setRoomsRoomNum(_destRoomNum);
} else if (compareRoomNameTo("SGTLittleLift")) {
- if (_statics->_changeViewFlag) {
+ if (_statics->_changeViewNum) {
changeView(_statics->_destView);
}
}
@@ -65,7 +65,7 @@ bool CEnterExitMiniLift::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
}
bool CEnterExitMiniLift::EnterViewMsg(CEnterViewMsg *msg) {
- _cursorId = _statics->_changeViewFlag ? CURSOR_MOVE_FORWARD : CURSOR_INVALID;
+ _cursorId = _statics->_changeViewNum ? CURSOR_MOVE_FORWARD : CURSOR_INVALID;
return true;
}
diff --git a/engines/titanic/moves/exit_arboretum.cpp b/engines/titanic/moves/exit_arboretum.cpp
index e0c2ab9c9d..ba162843b5 100644
--- a/engines/titanic/moves/exit_arboretum.cpp
+++ b/engines/titanic/moves/exit_arboretum.cpp
@@ -57,7 +57,7 @@ void CExitArboretum::load(SimpleFile *file) {
bool CExitArboretum::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
if (_enabled) {
CActMsg actMsg;
- if (_seasonNum == AUTUMN) {
+ if (_seasonNum == SEASON_WINTER) {
switch (_fieldCC) {
case 0:
actMsg._action = "ExitLFrozen";
diff --git a/engines/titanic/moves/move_player_in_parrot_room.cpp b/engines/titanic/moves/move_player_in_parrot_room.cpp
index df38c63cd4..1ef2e96e92 100644
--- a/engines/titanic/moves/move_player_in_parrot_room.cpp
+++ b/engines/titanic/moves/move_player_in_parrot_room.cpp
@@ -24,6 +24,11 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMovePlayerInParrotRoom, CMovePlayerTo)
+ ON_MESSAGE(ActMsg)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
CMovePlayerInParrotRoom::CMovePlayerInParrotRoom() : CMovePlayerTo() {
}
@@ -37,4 +42,20 @@ void CMovePlayerInParrotRoom::load(SimpleFile *file) {
CMovePlayerTo::load(file);
}
+bool CMovePlayerInParrotRoom::ActMsg(CActMsg *msg) {
+ if (msg->_action == "PanAwayFromParrot") {
+ unlockMouse();
+ changeView(_destination);
+ }
+
+ return true;
+}
+
+bool CMovePlayerInParrotRoom::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ lockMouse();
+ CPanningAwayFromParrotMsg awayMsg(this);
+ awayMsg.execute("PerchedParrot");
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/moves/move_player_in_parrot_room.h b/engines/titanic/moves/move_player_in_parrot_room.h
index de693fe2e2..54dc2eb992 100644
--- a/engines/titanic/moves/move_player_in_parrot_room.h
+++ b/engines/titanic/moves/move_player_in_parrot_room.h
@@ -28,6 +28,9 @@
namespace Titanic {
class CMovePlayerInParrotRoom : public CMovePlayerTo {
+ DECLARE_MESSAGE_MAP;
+ bool ActMsg(CActMsg *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
public:
CLASSDEF;
CMovePlayerInParrotRoom();
diff --git a/engines/titanic/moves/move_player_to.cpp b/engines/titanic/moves/move_player_to.cpp
index 9b6000c4f8..a91215b539 100644
--- a/engines/titanic/moves/move_player_to.cpp
+++ b/engines/titanic/moves/move_player_to.cpp
@@ -21,9 +21,15 @@
*/
#include "titanic/moves/move_player_to.h"
+#include "titanic/game_manager.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMovePlayerTo, CGameObject)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(ActMsg)
+END_MESSAGE_MAP()
+
CMovePlayerTo::CMovePlayerTo() : CGameObject() {
}
@@ -41,4 +47,17 @@ void CMovePlayerTo::load(SimpleFile *file) {
CGameObject::load(file);
}
+bool CMovePlayerTo::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ CGameManager *gameManager = getGameManager();
+ if (gameManager)
+ changeView(_destination);
+
+ return true;
+}
+
+bool CMovePlayerTo::ActMsg(CActMsg *msg) {
+ _destination = msg->_action;
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/moves/move_player_to.h b/engines/titanic/moves/move_player_to.h
index 4bfffcb0b2..822df69422 100644
--- a/engines/titanic/moves/move_player_to.h
+++ b/engines/titanic/moves/move_player_to.h
@@ -28,6 +28,9 @@
namespace Titanic {
class CMovePlayerTo : public CGameObject {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool ActMsg(CActMsg *msg);
protected:
CString _destination;
public:
diff --git a/engines/titanic/moves/move_player_to_from.cpp b/engines/titanic/moves/move_player_to_from.cpp
index 1a67dc8505..c57cc2cf51 100644
--- a/engines/titanic/moves/move_player_to_from.cpp
+++ b/engines/titanic/moves/move_player_to_from.cpp
@@ -21,10 +21,16 @@
*/
#include "titanic/moves/move_player_to_from.h"
+#include "titanic/core/view_item.h"
+#include "titanic/core/link_item.h"
namespace Titanic {
-CMovePlayerToFrom::CMovePlayerToFrom() : CGameObject() {
+BEGIN_MESSAGE_MAP(CMovePlayerToFrom, CMovePlayerTo)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
+CMovePlayerToFrom::CMovePlayerToFrom() : CMovePlayerTo() {
}
void CMovePlayerToFrom::save(SimpleFile *file, int indent) {
@@ -41,4 +47,17 @@ void CMovePlayerToFrom::load(SimpleFile *file) {
CGameObject::load(file);
}
+bool CMovePlayerToFrom::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (_string2.empty()) {
+ changeView(_destination);
+ } else {
+ CViewItem *view = parseView(_string2);
+ CViewItem *destView = parseView(_destination);
+ CLinkItem *link = view->findLink(destView);
+ changeView(_destination, link->getName());
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/moves/move_player_to_from.h b/engines/titanic/moves/move_player_to_from.h
index c9eefe532f..fde4e94ab5 100644
--- a/engines/titanic/moves/move_player_to_from.h
+++ b/engines/titanic/moves/move_player_to_from.h
@@ -23,11 +23,13 @@
#ifndef TITANIC_MOVE_PLAYER_TO_FROM_H
#define TITANIC_MOVE_PLAYER_TO_FROM_H
-#include "titanic/core/game_object.h"
+#include "titanic/moves/move_player_to.h"
namespace Titanic {
-class CMovePlayerToFrom : public CGameObject {
+class CMovePlayerToFrom : public CMovePlayerTo {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
private:
CString _string2;
public:
diff --git a/engines/titanic/moves/multi_move.cpp b/engines/titanic/moves/multi_move.cpp
index fb5570df9b..4ca4fdb8f3 100644
--- a/engines/titanic/moves/multi_move.cpp
+++ b/engines/titanic/moves/multi_move.cpp
@@ -24,29 +24,37 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CMultiMove, CMovePlayerTo)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
CMultiMove::CMultiMove() : CMovePlayerTo() {
}
void CMultiMove::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeQuotedLine(_string1, indent);
- file->writeQuotedLine(_string2, indent);
- file->writeQuotedLine(_string3, indent);
- file->writeQuotedLine(_string4, indent);
- file->writeQuotedLine(_string5, indent);
+ for (int idx = 0; idx < 5; ++idx)
+ file->writeQuotedLine(_viewNames[idx], indent);
CMovePlayerTo::save(file, indent);
}
void CMultiMove::load(SimpleFile *file) {
file->readNumber();
- _string1 = file->readString();
- _string2 = file->readString();
- _string3 = file->readString();
- _string5 = file->readString();
- _string4 = file->readString();
+ for (int idx = 0; idx < 5; ++idx)
+ _viewNames[idx] = file->readString();
CMovePlayerTo::load(file);
}
+bool CMultiMove::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ lockMouse();
+
+ for (int idx = 0; idx < 5 && _viewNames[idx] != "NULL"; ++idx)
+ changeView(_viewNames[idx]);
+
+ unlockMouse();
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/moves/multi_move.h b/engines/titanic/moves/multi_move.h
index 977afc2a20..12dd246823 100644
--- a/engines/titanic/moves/multi_move.h
+++ b/engines/titanic/moves/multi_move.h
@@ -28,12 +28,10 @@
namespace Titanic {
class CMultiMove : public CMovePlayerTo {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
private:
- CString _string1;
- CString _string2;
- CString _string3;
- CString _string4;
- CString _string5;
+ CString _viewNames[5];
public:
CLASSDEF;
CMultiMove();
diff --git a/engines/titanic/moves/pan_from_pel.cpp b/engines/titanic/moves/pan_from_pel.cpp
index fccc643ec5..ca48e888c1 100644
--- a/engines/titanic/moves/pan_from_pel.cpp
+++ b/engines/titanic/moves/pan_from_pel.cpp
@@ -24,23 +24,33 @@
namespace Titanic {
-CPanFromPel::CPanFromPel() : CMovePlayerTo(), _fieldC8(0) {
+BEGIN_MESSAGE_MAP(CPanFromPel, CMovePlayerTo)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
+CPanFromPel::CPanFromPel() : CMovePlayerTo(), _closeLeft(false) {
}
void CPanFromPel::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldC8, indent);
- file->writeQuotedLine(_string1, indent);
+ file->writeNumberLine(_closeLeft, indent);
+ file->writeQuotedLine(_target, indent);
CMovePlayerTo::save(file, indent);
}
void CPanFromPel::load(SimpleFile *file) {
file->readNumber();
- _fieldC8 = file->readNumber();
- _string1 = file->readString();
+ _closeLeft = file->readNumber();
+ _target = file->readString();
CMovePlayerTo::load(file);
}
+bool CPanFromPel::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ CActMsg actMsg(_closeLeft ? "CloseLeft" : "CloseRight");
+ actMsg.execute(_target);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/moves/pan_from_pel.h b/engines/titanic/moves/pan_from_pel.h
index c81be9f338..0a01aefea3 100644
--- a/engines/titanic/moves/pan_from_pel.h
+++ b/engines/titanic/moves/pan_from_pel.h
@@ -28,9 +28,11 @@
namespace Titanic {
class CPanFromPel : public CMovePlayerTo {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
protected:
- int _fieldC8;
- CString _string1;
+ bool _closeLeft;
+ CString _target;
public:
CLASSDEF;
CPanFromPel();
diff --git a/engines/titanic/moves/restaurant_pan_handler.cpp b/engines/titanic/moves/restaurant_pan_handler.cpp
index 92f55b46cc..d93e331254 100644
--- a/engines/titanic/moves/restaurant_pan_handler.cpp
+++ b/engines/titanic/moves/restaurant_pan_handler.cpp
@@ -24,24 +24,40 @@
namespace Titanic {
-int CRestaurantPanHandler::_v1;
+BEGIN_MESSAGE_MAP(CRestaurantPanHandler, CMovePlayerTo)
+ ON_MESSAGE(ArmPickedUpFromTableMsg)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
+bool CRestaurantPanHandler::_armPickedUp;
void CRestaurantPanHandler::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_v1, indent);
- file->writeQuotedLine(_string1, indent);
- file->writeQuotedLine(_string2, indent);
+ file->writeNumberLine(_armPickedUp, indent);
+ file->writeQuotedLine(_armlessDestination, indent);
+ file->writeQuotedLine(_armDestination, indent);
CMovePlayerTo::save(file, indent);
}
void CRestaurantPanHandler::load(SimpleFile *file) {
file->readNumber();
- _v1 = file->readNumber();
- _string1 = file->readString();
- _string2 = file->readString();
+ _armPickedUp = file->readNumber();
+ _armlessDestination = file->readString();
+ _armDestination = file->readString();
CMovePlayerTo::load(file);
}
+bool CRestaurantPanHandler::ArmPickedUpFromTableMsg(CArmPickedUpFromTableMsg *msg) {
+ _armPickedUp = true;
+ return true;
+}
+
+bool CRestaurantPanHandler::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ _destination = _armPickedUp ? _armDestination : _armlessDestination;
+ changeView(_destination);
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/moves/restaurant_pan_handler.h b/engines/titanic/moves/restaurant_pan_handler.h
index 4925aa685b..9684fd07f5 100644
--- a/engines/titanic/moves/restaurant_pan_handler.h
+++ b/engines/titanic/moves/restaurant_pan_handler.h
@@ -28,11 +28,14 @@
namespace Titanic {
class CRestaurantPanHandler : public CMovePlayerTo {
+ DECLARE_MESSAGE_MAP;
+ bool ArmPickedUpFromTableMsg(CArmPickedUpFromTableMsg *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
protected:
- static int _v1;
-
- CString _string1;
- CString _string2;
+ CString _armDestination;
+ CString _armlessDestination;
+public:
+ static bool _armPickedUp;
public:
CLASSDEF;
diff --git a/engines/titanic/moves/restricted_move.cpp b/engines/titanic/moves/restricted_move.cpp
index 5f18dab8ff..37cb1c46dc 100644
--- a/engines/titanic/moves/restricted_move.cpp
+++ b/engines/titanic/moves/restricted_move.cpp
@@ -24,21 +24,59 @@
namespace Titanic {
-CRestrictedMove::CRestrictedMove() : CMovePlayerTo(), _fieldC8(0) {
+BEGIN_MESSAGE_MAP(CRestrictedMove, CMovePlayerTo)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(EnterViewMsg)
+END_MESSAGE_MAP()
+
+CRestrictedMove::CRestrictedMove() : CMovePlayerTo(), _classNum(0) {
}
void CRestrictedMove::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_fieldC8, indent);
+ file->writeNumberLine(_classNum, indent);
CMovePlayerTo::save(file, indent);
}
void CRestrictedMove::load(SimpleFile *file) {
file->readNumber();
- _fieldC8 = file->readNumber();
+ _classNum = file->readNumber();
CMovePlayerTo::load(file);
}
+bool CRestrictedMove::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ int classNum = getPassengerClass();
+ if (classNum <= _classNum) {
+ // Okay to change to the given destination
+ changeView(_destination);
+ } else if (classNum != 4) {
+ petDisplayMessage(1, "Passengers of your class are not permitted to enter this area.");
+ } else if (compareRoomNameTo("EmbLobby")) {
+ playSound("a#17.wav");
+ petDisplayMessage(1, "Please check in at the reception desk.");
+ } else if (compareViewNameTo("Titania.Node 1.S")) {
+ playSound("z#226.wav");
+ changeView(_destination);
+ }
+
+ return true;
+}
+
+bool CRestrictedMove::EnterViewMsg(CEnterViewMsg *msg) {
+ int classNum = getPassengerClass();
+ bool flag = classNum > _classNum;
+
+ if (classNum == 4) {
+ if (compareRoomNameTo("EmbLobby"))
+ flag = false;
+ else if (compareViewNameTo("Titania.Node 1.S"))
+ flag = true;
+ }
+
+ _cursorId = flag ? CURSOR_MOVE_FORWARD : CURSOR_INVALID;
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/moves/restricted_move.h b/engines/titanic/moves/restricted_move.h
index bdf093c353..639b024701 100644
--- a/engines/titanic/moves/restricted_move.h
+++ b/engines/titanic/moves/restricted_move.h
@@ -28,8 +28,11 @@
namespace Titanic {
class CRestrictedMove : public CMovePlayerTo {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
protected:
- int _fieldC8;
+ int _classNum;
public:
CLASSDEF;
CRestrictedMove();
diff --git a/engines/titanic/moves/scraliontis_table.cpp b/engines/titanic/moves/scraliontis_table.cpp
index 77d2f9df60..8d39e2104f 100644
--- a/engines/titanic/moves/scraliontis_table.cpp
+++ b/engines/titanic/moves/scraliontis_table.cpp
@@ -24,15 +24,21 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CScraliontisTable, CRestaurantPanHandler)
+ ON_MESSAGE(MouseMoveMsg)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(MaitreDDefeatedMsg)
+END_MESSAGE_MAP()
+
CScraliontisTable::CScraliontisTable() : CRestaurantPanHandler(),
- _fieldE0(0), _fieldE4(0), _fieldE8(0), _fieldEC(0) {
+ _fieldE0(false), _counter(0), _ticks(0), _fieldEC(false) {
}
void CScraliontisTable::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
file->writeNumberLine(_fieldE0, indent);
- file->writeNumberLine(_fieldE4, indent);
- file->writeNumberLine(_fieldE8, indent);
+ file->writeNumberLine(_counter, indent);
+ file->writeNumberLine(_ticks, indent);
file->writeNumberLine(_fieldEC, indent);
CRestaurantPanHandler::save(file, indent);
@@ -41,11 +47,42 @@ void CScraliontisTable::save(SimpleFile *file, int indent) {
void CScraliontisTable::load(SimpleFile *file) {
file->readNumber();
_fieldE0 = file->readNumber();
- _fieldE4 = file->readNumber();
- _fieldE8 = file->readNumber();
+ _counter = file->readNumber();
+ _ticks = file->readNumber();
_fieldEC = file->readNumber();
CRestaurantPanHandler::load(file);
}
+bool CScraliontisTable::MouseMoveMsg(CMouseMoveMsg *msg) {
+ if (!_fieldEC && !_fieldE0) {
+ if (++_counter > 20) {
+ CTriggerNPCEvent triggerMsg;
+ triggerMsg.execute("MaitreD");
+ _fieldE0 = true;
+ }
+ }
+
+ return true;
+}
+
+bool CScraliontisTable::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (_fieldEC) {
+ changeView(_destination, _armPickedUp ? _armDestination : _armlessDestination);
+ }
+ else if (!_ticks || (getTicksCount() - _ticks) >= 5000) {
+ CTriggerNPCEvent triggerMsg(119);
+ triggerMsg.execute("MaitreD");
+ _ticks = getTicksCount();
+ }
+
+ return true;
+}
+
+bool CScraliontisTable::MaitreDDefeatedMsg(CMaitreDDefeatedMsg *msg) {
+ _cursorId = CURSOR_MOVE_FORWARD;
+ _fieldEC = true;
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/moves/scraliontis_table.h b/engines/titanic/moves/scraliontis_table.h
index 2ce3745654..b0d8c6b5af 100644
--- a/engines/titanic/moves/scraliontis_table.h
+++ b/engines/titanic/moves/scraliontis_table.h
@@ -28,11 +28,15 @@
namespace Titanic {
class CScraliontisTable : public CRestaurantPanHandler {
+ DECLARE_MESSAGE_MAP;
+ bool MouseMoveMsg(CMouseMoveMsg *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool MaitreDDefeatedMsg(CMaitreDDefeatedMsg *msg);
private:
- int _fieldE0;
- int _fieldE4;
- int _fieldE8;
- int _fieldEC;
+ bool _fieldE0;
+ int _counter;
+ uint _ticks;
+ bool _fieldEC;
public:
CLASSDEF;
CScraliontisTable();
diff --git a/engines/titanic/moves/trip_down_canal.cpp b/engines/titanic/moves/trip_down_canal.cpp
index c8051dda03..e9818fa96d 100644
--- a/engines/titanic/moves/trip_down_canal.cpp
+++ b/engines/titanic/moves/trip_down_canal.cpp
@@ -24,6 +24,10 @@
namespace Titanic {
+BEGIN_MESSAGE_MAP(CTripDownCanal, CMovePlayerTo)
+ ON_MESSAGE(MouseButtonDownMsg)
+END_MESSAGE_MAP()
+
CTripDownCanal::CTripDownCanal() : CMovePlayerTo() {
}
@@ -37,4 +41,14 @@ void CTripDownCanal::load(SimpleFile *file) {
CMovePlayerTo::load(file);
}
+bool CTripDownCanal::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (stateGetSeason() == SEASON_WINTER) {
+ petDisplayMessage("Sadly, the Grand Canal transport system is closed for the winter.");
+ } else if (getGameManager()) {
+ changeView(_destination);
+ }
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/moves/trip_down_canal.h b/engines/titanic/moves/trip_down_canal.h
index 736caf4131..f43fb05de1 100644
--- a/engines/titanic/moves/trip_down_canal.h
+++ b/engines/titanic/moves/trip_down_canal.h
@@ -28,6 +28,8 @@
namespace Titanic {
class CTripDownCanal : public CMovePlayerTo {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
public:
CLASSDEF;
CTripDownCanal();
diff --git a/engines/titanic/npcs/bellbot.cpp b/engines/titanic/npcs/bellbot.cpp
index ac6881a45c..0170491270 100644
--- a/engines/titanic/npcs/bellbot.cpp
+++ b/engines/titanic/npcs/bellbot.cpp
@@ -135,8 +135,7 @@ bool CBellBot::MovieEndMsg(CMovieEndMsg *msg) {
}
bool CBellBot::Use(CUse *msg) {
- error("TODO: Figure out what msg->_item points to");
- // msg->_item = "Bellbot";
+ dynamic_cast<CCarry *>(msg->_item)->_string1 = "Bellbot";
return true;
}
diff --git a/engines/titanic/npcs/doorbot.cpp b/engines/titanic/npcs/doorbot.cpp
index 4a5f3690c0..41ef2b2366 100644
--- a/engines/titanic/npcs/doorbot.cpp
+++ b/engines/titanic/npcs/doorbot.cpp
@@ -288,7 +288,7 @@ bool CDoorbot::TimerMsg(CTimerMsg *msg) {
case 6:
CMouseButtonDownMsg::generate();
- mouseSaveState(200, 430, 2500);
+ mouseSetPosition(Point(200, 430), 2500);
_timerId = addTimer(7, 2500, 0);
break;
@@ -476,7 +476,7 @@ bool CDoorbot::TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg)
case 10568:
mouseLockE4();
- mouseSaveState(600, 250, 2500);
+ mouseSetPosition(Point(600, 250), 2500);
_timerId = addTimer(6, 2500, 0);
break;
@@ -488,7 +488,7 @@ bool CDoorbot::TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg)
break;
case 10570:
- mouseSaveState(200, 430, 2500);
+ mouseSetPosition(Point(200, 430), 2500);
_timerId = addTimer(7, 3000, 0);
break;
diff --git a/engines/titanic/npcs/mobile.h b/engines/titanic/npcs/mobile.h
index 68e74a5afe..2ad939afa6 100644
--- a/engines/titanic/npcs/mobile.h
+++ b/engines/titanic/npcs/mobile.h
@@ -29,7 +29,7 @@ namespace Titanic {
class CMobile : public CCharacter {
DECLARE_MESSAGE_MAP;
-private:
+protected:
Point _pos1;
int _fieldDC;
public:
diff --git a/engines/titanic/npcs/true_talk_npc.cpp b/engines/titanic/npcs/true_talk_npc.cpp
index 5ba68aafbe..97913dffea 100644
--- a/engines/titanic/npcs/true_talk_npc.cpp
+++ b/engines/titanic/npcs/true_talk_npc.cpp
@@ -188,7 +188,34 @@ bool CTrueTalkNPC::TimerMsg(CTimerMsg *msg) {
}
bool CTrueTalkNPC::NPCPlayAnimationMsg(CNPCPlayAnimationMsg *msg) {
- warning("CTrueTalkNPC::NPCPlayAnimationMsg");
+// const char *const *nameP = msg->_names;
+ int count;
+ for (count = 0; msg->_names[count]; ++count)
+ ;
+
+ if (msg->_maxDuration) {
+ // Randomly pick a clip that's less than the allowed maximum
+ int tries = 10, index;
+ do {
+ index = getRandomNumber(count - 1);
+ } while (getClipDuration(msg->_names[index]) > msg->_maxDuration && --tries);
+
+ if (tries) {
+ // Sequentially go through the clips to find any below the maximum
+ index = 0;
+ for (int idx = 0; idx < count; ++idx) {
+ if (getClipDuration(msg->_names[idx]) < msg->_maxDuration) {
+ index = idx;
+ break;
+ }
+ }
+ }
+
+ playClip(msg->_names[index], MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
+ } else {
+ playClip(msg->_names[getRandomNumber(count - 1)]);
+ }
+
return true;
}
diff --git a/engines/titanic/npcs/true_talk_npc.h b/engines/titanic/npcs/true_talk_npc.h
index 1eade1966d..5254eaf9b7 100644
--- a/engines/titanic/npcs/true_talk_npc.h
+++ b/engines/titanic/npcs/true_talk_npc.h
@@ -62,15 +62,11 @@ protected:
int _fieldF4;
int _fieldF8;
int _speechTimerId;
- int _field100;
int _field104;
protected:
void processInput(CTextInputMsg *msg, CViewItem *view);
-
- /**
- * Perform an action
- */
- void performAction(bool startTalking, CViewItem *view = nullptr);
+public:
+ int _field100;
public:
CLASSDEF;
CTrueTalkNPC();
@@ -94,6 +90,11 @@ public:
* Start the talker in the given view
*/
void startTalker(CViewItem *view);
+
+ /**
+ * Perform an action
+ */
+ void performAction(bool startTalking, CViewItem *view = nullptr);
};
} // End of namespace Titanic
diff --git a/engines/titanic/pet_control/pet_control.cpp b/engines/titanic/pet_control/pet_control.cpp
index b32a7907a4..a0f8fab267 100644
--- a/engines/titanic/pet_control/pet_control.cpp
+++ b/engines/titanic/pet_control/pet_control.cpp
@@ -194,6 +194,10 @@ void CPetControl::setActiveNPC(CTrueTalkNPC *npc) {
}
}
+void CPetControl::setActiveNPC(const CString &name) {
+ _conversations.setActiveNPC(name);
+}
+
void CPetControl::refreshNPC() {
_conversations.setNPC(_activeNPCName);
}
@@ -355,7 +359,8 @@ bool CPetControl::VirtualKeyCharMsg(CVirtualKeyCharMsg *msg) {
}
bool CPetControl::TimerMsg(CTimerMsg *msg) {
- warning("TODO: CPetControl::CTimerMsg");
+ if (_timers[msg->_actionVal]._target)
+ _timers[msg->_actionVal]._target->timerExpired(msg->_actionVal);
return true;
}
@@ -660,6 +665,10 @@ void CPetControl::convResetDials(int flag) {
_conversations.resetDials(_activeNPCName);
}
+void CPetControl::resetDials0() {
+ _conversations.resetDials0();
+}
+
int CPetControl::getMailDest(const CRoomFlags &roomFlags) const {
if (!roomFlags.isSuccUBusRoomFlags())
return roomFlags.getPassengerClassNum();
diff --git a/engines/titanic/pet_control/pet_control.h b/engines/titanic/pet_control/pet_control.h
index a86d110458..439a94e2d3 100644
--- a/engines/titanic/pet_control/pet_control.h
+++ b/engines/titanic/pet_control/pet_control.h
@@ -358,9 +358,7 @@ public:
/**
* Sets the active NPC
*/
- void setActiveNPC(const CString &name) {
- _conversations.setActiveNPC(name);
- }
+ void setActiveNPC(const CString &name);
/**
* Sets the actie NPC
@@ -387,7 +385,7 @@ public:
/**
* Resets the conversation dials back to 0 position
*/
- void resetDials0() { _conversations.resetDials0(); }
+ void resetDials0();
/**
* Resets the dial display in the conversation tab to reflect new values
diff --git a/engines/titanic/pet_control/pet_conversations.h b/engines/titanic/pet_control/pet_conversations.h
index 9e8b093d62..3333bdc523 100644
--- a/engines/titanic/pet_control/pet_conversations.h
+++ b/engines/titanic/pet_control/pet_conversations.h
@@ -100,16 +100,6 @@ private:
void summonBot(const CString &name);
/**
- * Starts the NPC timer
- */
- void startNPCTimer();
-
- /**
- * Stops the NPC timer
- */
- void stopNPCTimer();
-
- /**
* Get the TrueTalk script associated with a given NPC
*/
TTnpcScript *getNPCScript(const CString &name) const;
@@ -260,6 +250,16 @@ public:
* Adds a line to the log
*/
void addLine(const CString &line);
+
+ /**
+ * Starts the NPC timer
+ */
+ void startNPCTimer();
+
+ /**
+ * Stops the NPC timer
+ */
+ void stopNPCTimer();
};
} // End of namespace Titanic
diff --git a/engines/titanic/pet_control/pet_load_save.h b/engines/titanic/pet_control/pet_load_save.h
index dd1c907ef1..26ddec0ff9 100644
--- a/engines/titanic/pet_control/pet_load_save.h
+++ b/engines/titanic/pet_control/pet_load_save.h
@@ -38,11 +38,6 @@ private:
Rect getSlotBounds(int index);
/**
- * Highlight one of the slots
- */
- void highlightSlot(int index);
-
- /**
* Called when savegame slot highlight changes or the view is reset
*/
void highlightChange();
@@ -67,6 +62,11 @@ protected:
* Reset the slot names list
*/
void resetSlots();
+
+ /**
+ * Highlight one of the slots
+ */
+ void highlightSlot(int index);
public:
/**
* Setup the glyph
diff --git a/engines/titanic/pet_control/pet_save.cpp b/engines/titanic/pet_control/pet_save.cpp
index b5e16736bc..9305759117 100644
--- a/engines/titanic/pet_control/pet_save.cpp
+++ b/engines/titanic/pet_control/pet_save.cpp
@@ -22,6 +22,7 @@
#include "titanic/pet_control/pet_save.h"
#include "titanic/pet_control/pet_control.h"
+#include "titanic/core/project_item.h"
namespace Titanic {
@@ -58,15 +59,28 @@ void CPetSave::getTooltip(CPetText *text) {
}
void CPetSave::highlightSave(int index) {
- warning("TODO: CPetSave::highlightSave");
+ if (index >= 0)
+ _slotNames[index].showCursor(-2);
}
void CPetSave::unhighlightSave(int index) {
- warning("TODO: CPetSave::unhighlightSave");
+ if (index >= 0)
+ _slotNames[index].hideCursor();
}
void CPetSave::execute() {
- warning("TODO: CPetSave::execute");
+ CPetControl *pet = getPetControl();
+ if (_savegameSlotNum >= 0) {
+ highlightSlot(-1);
+ CProjectItem *project = pet ? pet->getRoot() : nullptr;
+
+ if (project) {
+ project->saveGame(_savegameSlotNum, _slotNames[_savegameSlotNum].getText());
+ pet->displayMessage("");
+ }
+ } else if (pet) {
+ pet->displayMessage("You must select a game to save first.");
+ }
}
} // End of namespace Titanic
diff --git a/engines/titanic/sound/music_room.h b/engines/titanic/sound/music_room.h
index 15363ef392..5f0b271ab3 100644
--- a/engines/titanic/sound/music_room.h
+++ b/engines/titanic/sound/music_room.h
@@ -31,6 +31,8 @@ namespace Titanic {
class CGameManager;
class CSound;
+enum MusicControlArea { BELLS = 0, SNAKE = 1, PIANO = 2, BASS = 3 };
+
class CMusicRoom {
struct Entry {
uint _val1;
@@ -62,11 +64,11 @@ public:
*/
void destroyMusicHandler();
- void setItem1(int index, int val) { _items[index]._val1 = val; }
- void setItem2(int index, int val) { _items[index]._val2 = val; }
- void setItem3(int index, int val) { _items[index]._val3 = val; }
- void setItem4(int index, int val) { _items[index]._val4 = val; }
- void setItem5(int index, int val) { _items[index]._val5 = val; }
+ void setItem1(MusicControlArea index, int val) { _items[index]._val1 = val; }
+ void setItem2(MusicControlArea index, int val) { _items[index]._val2 = val; }
+ void setItem3(MusicControlArea index, int val) { _items[index]._val3 = val; }
+ void setItem4(MusicControlArea index, int val) { _items[index]._val4 = val; }
+ void setItem5(MusicControlArea index, int val) { _items[index]._val5 = val; }
/**
* Start playing a given music number
diff --git a/engines/titanic/sound/sound_manager.cpp b/engines/titanic/sound/sound_manager.cpp
index 4846329784..ae806feb52 100644
--- a/engines/titanic/sound/sound_manager.cpp
+++ b/engines/titanic/sound/sound_manager.cpp
@@ -33,14 +33,14 @@ CSoundManager::CSoundManager() : _musicPercent(75.0), _speechPercent(75.0),
_masterPercent(75.0), _parrotPercent(75.0), _handleCtr(1) {
}
-double CSoundManager::getModeVolume(int mode) {
+uint CSoundManager::getModeVolume(int mode) {
switch (mode) {
case -1:
- return _masterPercent;
+ return (uint)_masterPercent;
case -2:
- return _masterPercent * 30 / 100;
+ return (uint)(_masterPercent * 30 / 100);
case -3:
- return _masterPercent * 15 / 100;
+ return (uint)(_masterPercent * 15 / 100);
default:
return 0;
}
diff --git a/engines/titanic/sound/sound_manager.h b/engines/titanic/sound/sound_manager.h
index 3dfba92e9c..d1afdb4ad4 100644
--- a/engines/titanic/sound/sound_manager.h
+++ b/engines/titanic/sound/sound_manager.h
@@ -214,7 +214,7 @@ public:
/**
* Gets the volume for a given mode? value
*/
- double getModeVolume(int mode);
+ uint getModeVolume(int mode);
};
class QSoundManagerSound : public ListItem {
diff --git a/engines/titanic/sound/titania_speech.cpp b/engines/titanic/sound/titania_speech.cpp
index a07cc79334..d0ff423342 100644
--- a/engines/titanic/sound/titania_speech.cpp
+++ b/engines/titanic/sound/titania_speech.cpp
@@ -59,7 +59,7 @@ bool CTitaniaSpeech::ActMsg(CActMsg *msg) {
movieSetAudioTiming(true);
loadSound("a#12.wav");
sleep(1000);
- playMovie(0, 187, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ playMovie(0, 187, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
movieEvent(0);
break;
@@ -78,7 +78,7 @@ bool CTitaniaSpeech::ActMsg(CActMsg *msg) {
visibleMsg._visible = false;
visibleMsg.execute("TitaniaStillControl");
loadSound("a#10.wav");
- playMovie(585, 706, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ playMovie(585, 706, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
playSound("a#10.wav");
break;
@@ -86,7 +86,7 @@ bool CTitaniaSpeech::ActMsg(CActMsg *msg) {
visibleMsg._visible = false;
visibleMsg.execute("TitaniaStillControl");
loadSound("a#9.wav");
- playMovie(707, 905, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ playMovie(707, 905, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
playSound("a#9.wav");
break;
@@ -94,7 +94,7 @@ bool CTitaniaSpeech::ActMsg(CActMsg *msg) {
visibleMsg._visible = false;
visibleMsg.execute("TitaniaStillControl");
loadSound("a#8.wav");
- playMovie(906, 938, MOVIE_GAMESTATE || MOVIE_NOTIFY_OBJECT);
+ playMovie(906, 938, MOVIE_GAMESTATE | MOVIE_NOTIFY_OBJECT);
playSound("a#8.wav");
break;
diff --git a/engines/titanic/star_control/surface_fader.cpp b/engines/titanic/star_control/surface_fader.cpp
index 089ad51717..0ee03673a4 100644
--- a/engines/titanic/star_control/surface_fader.cpp
+++ b/engines/titanic/star_control/surface_fader.cpp
@@ -29,9 +29,9 @@ namespace Titanic {
CSurfaceFader::CSurfaceFader() : CSurfaceFaderBase() {
_dataP = new byte[_count];
- for (int idx = 0; idx < _count; ++idx) {
- // TODO: Setup data bytes
- }
+ for (int idx = 0; idx < _count; ++idx)
+ _dataP[idx] = (byte)(pow((double)idx / (double)_count, 1.299999952316284)
+ * (double)_count + 0.5);
}
CSurfaceFader::~CSurfaceFader() {
diff --git a/engines/titanic/support/credit_text.cpp b/engines/titanic/support/credit_text.cpp
index 0e9715aaa6..009c3f4944 100644
--- a/engines/titanic/support/credit_text.cpp
+++ b/engines/titanic/support/credit_text.cpp
@@ -28,7 +28,7 @@ namespace Titanic {
CCreditText::CCreditText() : _screenManagerP(nullptr), _field14(0),
_ticks(0), _fontHeight(1), _objectP(nullptr), _totalHeight(0),
_field40(0), _field44(0), _field48(0), _field4C(0), _field50(0),
- _field54(0), _field58(0), _field5C(0) {
+ _field54(0), _field58(0), _counter(0) {
}
void CCreditText::clear() {
@@ -52,7 +52,7 @@ void CCreditText::load(CGameObject *obj, CScreenManager *screenManager,
_field50 = 0;
_field54 = 0;
_field58 = 0;
- _field5C = 0;
+ _counter = 0;
}
void CCreditText::setup() {
@@ -87,8 +87,11 @@ void CCreditText::setup() {
}
_groups.push_back(group);
+ if (hasDots)
+ handleDots(group);
}
+ _screenManagerP->setFontNumber(oldFontNumber);
_groupIt = _groups.begin();
_lineIt = (*_groupIt)->_lines.begin();
_totalHeight = _objectP->getBounds().height() + _fontHeight * 2;
@@ -147,7 +150,108 @@ void CCreditText::handleDots(CCreditLineGroup *group) {
}
bool CCreditText::draw() {
- return false;
+ if (_groupIt == _groups.end())
+ return false;
+
+ if (++_counter > 200) {
+ _field44 += _field50;
+ _field48 += _field54;
+ _field4C += _field58;
+ _field50 = g_vm->getRandomNumber(63) + 192 - _field44;
+ _field54 = g_vm->getRandomNumber(63) + 192 - _field48;
+ _field58 = g_vm->getRandomNumber(63) + 192 - _field4C;
+ _counter = 0;
+ }
+
+ // Positioning adjustment, changing lines and/or group if necessary
+ int yDiff = (int)(g_vm->_events->getTicksCount() - _ticks) / 22 - _field40;
+ while (yDiff > 0) {
+ if (_totalHeight > 0) {
+ if (yDiff < _totalHeight) {
+ _totalHeight -= yDiff;
+ _field40 += yDiff;
+ yDiff = 0;
+ } else {
+ yDiff -= _totalHeight;
+ _field40 += _totalHeight;
+ _totalHeight = 0;
+ }
+ } else {
+ if (yDiff < _fontHeight)
+ break;
+
+ ++_lineIt;
+ yDiff -= _fontHeight;
+ _field40 += _fontHeight;
+
+ if (_lineIt == (*_groupIt)->_lines.end()) {
+ // Move to next line group
+ ++_groupIt;
+ if (_groupIt == _groups.end())
+ // Reached end of groups
+ return false;
+
+ _lineIt = (*_groupIt)->_lines.begin();
+ _totalHeight = _fontHeight * 3 / 2;
+ }
+ }
+ }
+
+ int oldFontNumber = _screenManagerP->setFontNumber(3);
+ CCreditLineGroups::iterator groupIt = _groupIt;
+ CCreditLines::iterator lineIt = _lineIt;
+
+ Point textPos;
+ for (textPos.y = _rect.top + _totalHeight; textPos.y <= _rect.bottom;
+ textPos.y += _fontHeight) {
+ int textR = _field44 + _field50 * _counter / 200;
+ int textG = _field48 + _field54 * _counter / 200;
+ int textB = _field4C + _field58 * _counter / 200;
+
+ // Single iteration loop to figure out RGB values for the line
+ do {
+ int percent = 0;
+ if (textPos.y < (_rect.top + 2 * _fontHeight)) {
+ percent = (textPos.y - _rect.top) * 100 / (_fontHeight * 2);
+ if (percent < 0)
+ percent = 0;
+ } else {
+ int bottom = _rect.bottom - 2 * _fontHeight;
+ if (textPos.y < bottom)
+ break;
+
+ percent = (_rect.bottom - textPos.y) * 100
+ / (_fontHeight * 2);
+ }
+
+ // Adjust the RGB to the specified percentage intensity
+ textR = textR * percent / 100;
+ textG = textG * percent / 100;
+ textB = textB * percent / 100;
+ } while (0);
+
+ // Write out the line
+ _screenManagerP->setFontColor(textR, textG, textB);
+ textPos.x = _rect.left + (_rect.width() - (*lineIt)->_lineWidth) / 2;
+ _screenManagerP->writeString(SURFACE_BACKBUFFER, textPos,
+ _rect, (*lineIt)->_line, (*lineIt)->_lineWidth);
+
+ // Move to next line
+ ++lineIt;
+ if (lineIt == (*groupIt)->_lines.end()) {
+ ++groupIt;
+ if (groupIt == _groups.end())
+ // Finished all lines
+ break;
+
+ lineIt = (*groupIt)->_lines.begin();
+ textPos.y += _fontHeight * 3 / 2;
+ }
+ }
+
+ _objectP->makeDirty();
+ _screenManagerP->setFontNumber(oldFontNumber);
+ return true;
}
} // End of namespace Titanic
diff --git a/engines/titanic/support/credit_text.h b/engines/titanic/support/credit_text.h
index ec8fc22cda..3e5bfca0c2 100644
--- a/engines/titanic/support/credit_text.h
+++ b/engines/titanic/support/credit_text.h
@@ -68,11 +68,11 @@ public:
int _field14;
CCreditLineGroups _groups;
uint _ticks;
- uint _fontHeight;
+ int _fontHeight;
CGameObject *_objectP;
CCreditLineGroups::iterator _groupIt;
CCreditLines::iterator _lineIt;
- uint _totalHeight;
+ int _totalHeight;
int _field40;
int _field44;
int _field48;
@@ -80,7 +80,7 @@ public:
int _field50;
int _field54;
int _field58;
- int _field5C;
+ int _counter;
public:
CCreditText();
diff --git a/engines/titanic/support/direct_draw.cpp b/engines/titanic/support/direct_draw.cpp
index 6958896077..3cec9377bb 100644
--- a/engines/titanic/support/direct_draw.cpp
+++ b/engines/titanic/support/direct_draw.cpp
@@ -75,18 +75,6 @@ void DirectDrawManager::initVideo(int width, int height, int bpp, int numBackSur
}
}
-void DirectDrawManager::setResolution() {
- // TODO
-}
-
-void DirectDrawManager::proc2() {
-
-}
-
-void DirectDrawManager::proc3() {
-
-}
-
void DirectDrawManager::initFullScreen() {
debugC(ERROR_BASIC, kDebugGraphics, "Creating surfaces");
_directDraw.setDisplayMode(_directDraw._width, _directDraw._height,
diff --git a/engines/titanic/support/direct_draw.h b/engines/titanic/support/direct_draw.h
index 85c344c600..4b5596896a 100644
--- a/engines/titanic/support/direct_draw.h
+++ b/engines/titanic/support/direct_draw.h
@@ -78,12 +78,6 @@ public:
*/
void initVideo(int width, int height, int bpp, int numBackSurfaces);
- void setResolution();
-
- void proc2();
-
- void proc3();
-
/**
* Initializes the surfaces in windowed mode
*/
diff --git a/engines/titanic/support/files_manager.cpp b/engines/titanic/support/files_manager.cpp
index 89e0a1d10e..3ee17e9769 100644
--- a/engines/titanic/support/files_manager.cpp
+++ b/engines/titanic/support/files_manager.cpp
@@ -104,8 +104,9 @@ void CFilesManager::loadDrive() {
resetView();
}
-void CFilesManager::debug(CScreenManager *screenManager) {
- warning("TODO: CFilesManager::debug");
+void CFilesManager::insertCD(CScreenManager *screenManager) {
+ // We not support running game directly from the original CDs,
+ // so this method can remain stubbed
}
void CFilesManager::resetView() {
@@ -115,10 +116,6 @@ void CFilesManager::resetView() {
}
}
-void CFilesManager::fn4(const CString &name) {
- warning("TODO: CFilesManager::fn4");
-}
-
void CFilesManager::preload(const CString &name) {
// We don't currently do any preloading of resources
}
diff --git a/engines/titanic/support/files_manager.h b/engines/titanic/support/files_manager.h
index ec0c7fc008..c530b05ece 100644
--- a/engines/titanic/support/files_manager.h
+++ b/engines/titanic/support/files_manager.h
@@ -84,15 +84,16 @@ public:
*/
void loadDrive();
- void debug(CScreenManager *screenManager);
+ /**
+ * Shows a dialog for inserting a new CD
+ */
+ void insertCD(CScreenManager *screenManager);
/**
* Resets the view being displayed
*/
void resetView();
- void fn4(const CString &name);
-
/**
* Preloads and caches a file for access shortly
*/
diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp
index 69c0efe504..e519237c3b 100644
--- a/engines/titanic/support/font.cpp
+++ b/engines/titanic/support/font.cpp
@@ -179,6 +179,67 @@ int STFont::writeString(CVideoSurface *surface, const Rect &rect1, const Rect &d
return endP ? endP - str.c_str() : 0;
}
+void STFont::writeString(CVideoSurface *surface, const Point &destPos, Rect &clipRect,
+ const CString &str, int lineWidth) {
+ if (!_fontHeight || !_dataPtr || str.empty())
+ return;
+ if (!lineWidth)
+ // No line width specified, so get in the width
+ lineWidth = stringWidth(str);
+
+ Rect textRect(0, 0, lineWidth, _fontHeight);
+ Point textPt = destPos;
+
+ // Perform clipping as necessary if the text will fall outside clipping area
+ if (textPt.y > clipRect.bottom)
+ return;
+
+ if ((textPt.y + textRect.height()) > clipRect.bottom)
+ textRect.bottom = textRect.top - textPt.y + clipRect.bottom;
+
+ if (textPt.y < clipRect.top) {
+ if ((textPt.y + textRect.height()) < clipRect.top)
+ return;
+
+ textRect.top += clipRect.top - textPt.y;
+ textPt.y = clipRect.top;
+ }
+
+ // Iterate through each character of the string
+ for (const byte *srcP = (const byte *)str.c_str(); *srcP; ++srcP) {
+ byte c = *srcP;
+ if (c == 0xE9)
+ c = '$';
+
+ // Form a rect of the area of the next character to draw
+ Rect charRect(_chars[c]._offset, textRect.top,
+ _chars[c]._offset + _chars[c]._width, textRect.bottom);
+
+ if (textPt.x < clipRect.left) {
+ // Character is either partially or entirely left off-screen
+ if ((textPt.x + charRect.width()) < clipRect.left) {
+ textPt.x += _chars[c]._width;
+ continue;
+ }
+
+ // Partially clipped on left-hand side
+ charRect.left = clipRect.left - textPt.x;
+ textPt.x = clipRect.left;
+ } else if ((textPt.x + charRect.width()) > clipRect.right) {
+ if (textPt.x > clipRect.right)
+ // Now entirely off right-hand side, so stop drawing
+ break;
+
+ // Partially clipped on right-hand side
+ charRect.right += clipRect.right - textPt.x - charRect.width();
+ }
+
+ // At this point, we know we've got to draw at least part of a character,
+ // and have figured out the area of the character to draw
+ copyRect(surface, textPt, charRect);
+ }
+}
+
WriteCharacterResult STFont::writeChar(CVideoSurface *surface, unsigned char c, const Point &pt,
const Rect &destRect, const Rect *srcRect) {
if (c == 233)
diff --git a/engines/titanic/support/font.h b/engines/titanic/support/font.h
index 591fb4661c..6c4fe8e9c3 100644
--- a/engines/titanic/support/font.h
+++ b/engines/titanic/support/font.h
@@ -99,6 +99,12 @@ public:
int yOffset, const CString &str, CTextCursor *textCursor);
/**
+ * Write a string to the specified surface
+ */
+ void writeString(CVideoSurface *surface, const Point &destPos, Rect &clipRect,
+ const CString &str, int lineWidth = 0);
+
+ /**
* Get the text area a string will fit into
* @param str String
* @param maxWidth Maximum width in pixels
diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp
index 068267cb18..d342e6cccb 100644
--- a/engines/titanic/support/mouse_cursor.cpp
+++ b/engines/titanic/support/mouse_cursor.cpp
@@ -67,7 +67,6 @@ CMouseCursor::~CMouseCursor() {
void CMouseCursor::loadCursorImages() {
const CResourceKey key("ycursors.avi");
- g_vm->_filesManager->fn4(key.getString());
// Iterate through getting each cursor
for (int idx = 0; idx < NUM_CURSORS; ++idx) {
@@ -128,8 +127,11 @@ void CMouseCursor::unlockE4() {
CScreenManager::_screenManagerPtr->_inputHandler->decLockCount();
}
-void CMouseCursor::saveState(int v1, int v2, int v3) {
- // TODO
+void CMouseCursor::setPosition(const Point &pt, double rate) {
+ assert(rate >= 0.0 && rate <= 1.0);
+
+ // TODO: Figure out use of the rate parameter
+ g_system->warpMouse(pt.x, pt.y);
}
} // End of namespace Titanic
diff --git a/engines/titanic/support/mouse_cursor.h b/engines/titanic/support/mouse_cursor.h
index 7a81ad43fa..74fb1f6113 100644
--- a/engines/titanic/support/mouse_cursor.h
+++ b/engines/titanic/support/mouse_cursor.h
@@ -24,8 +24,8 @@
#define TITANIC_MOUSE_CURSOR_H
#include "common/scummsys.h"
-#include "common/rect.h"
#include "graphics/managed_surface.h"
+#include "titanic/support/rect.h"
namespace Titanic {
@@ -105,7 +105,10 @@ public:
void lockE4();
void unlockE4();
- void saveState(int v1, int v2, int v3);
+ /**
+ * Sets the mouse to a new position
+ */
+ void setPosition(const Point &pt, double rate);
};
diff --git a/engines/titanic/support/screen_manager.cpp b/engines/titanic/support/screen_manager.cpp
index b0d852104c..bcf43fc8cb 100644
--- a/engines/titanic/support/screen_manager.cpp
+++ b/engines/titanic/support/screen_manager.cpp
@@ -239,10 +239,25 @@ int OSScreenManager::writeString(int surfaceNum, const Rect &destRect,
yOffset, str, textCursor);
}
-int OSScreenManager::writeString(int surfaceNum, const Rect &srcRect,
- const Rect &destRect, const CString &str, CTextCursor *textCursor) {
- // TODO
- return 0;
+void OSScreenManager::writeString(int surfaceNum, const Point &destPos,
+ const Rect &clipRect, const CString &str, int lineWidth) {
+ CVideoSurface *surface;
+ Rect bounds;
+
+ if (surfaceNum >= 0 && surfaceNum < (int)_backSurfaces.size()) {
+ surface = _backSurfaces[surfaceNum]._surface;
+ bounds = _backSurfaces[surfaceNum]._bounds;
+ } else if (surfaceNum == -1) {
+ surface = _frontRenderSurface;
+ bounds = Rect(0, 0, surface->getWidth(), surface->getHeight());
+ } else {
+ return;
+ }
+
+ Rect destRect = clipRect;
+ destRect.constrain(bounds);
+
+ _fonts[_fontNumber].writeString(surface, destPos, destRect, str, lineWidth);
}
void OSScreenManager::setFontColor(byte r, byte g, byte b) {
diff --git a/engines/titanic/support/screen_manager.h b/engines/titanic/support/screen_manager.h
index 0736f1393c..cad6901b02 100644
--- a/engines/titanic/support/screen_manager.h
+++ b/engines/titanic/support/screen_manager.h
@@ -140,13 +140,13 @@ public:
/**
* Write a string
* @param surfaceNum Destination surface
- * @param srcRect Drawing area
- * @param destRect Bounds of dest surface
+ * @param destPos Position to start writing text at
+ * @param clipRect Clipping area to constrain text to
* @param str Line or lines to write
- * @param textCursor Optional text cursor pointer
+ * @param maxWidth Maximum allowed line width
*/
- virtual int writeString(int surfaceNum, const Rect &srcRect,
- const Rect &destRect, const CString &str, CTextCursor *textCursor) = 0;
+ virtual void writeString(int surfaceNum, const Point &destPos,
+ const Rect &clipRect, const CString &str, int maxWidth) = 0;
/**
* Set the font color
@@ -322,13 +322,13 @@ public:
/**
* Write a string
* @param surfaceNum Destination surface
- * @param srcRect Drawing area
- * @param destRect Bounds of dest surface
+ * @param destPos Position to start writing text at
+ * @param clipRect Clipping area to constrain text to
* @param str Line or lines to write
- * @param textCursor Optional text cursor pointer
+ * @param lineWidth Width in pixels of the string, if known.
*/
- virtual int writeString(int surfaceNum, const Rect &srcRect,
- const Rect &destRect, const CString &str, CTextCursor *textCursor);
+ virtual void writeString(int surfaceNum, const Point &destPos,
+ const Rect &clipRect, const CString &str, int lineWidth = 0);
/**
* Set the font color
diff --git a/engines/titanic/support/string_parser.cpp b/engines/titanic/support/string_parser.cpp
new file mode 100644
index 0000000000..496440a973
--- /dev/null
+++ b/engines/titanic/support/string_parser.cpp
@@ -0,0 +1,97 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "titanic/support/string_parser.h"
+#include "common/util.h"
+
+namespace Titanic {
+
+void CStringParser::skipSeperators(const CString &seperatorChars) {
+ for (; _index < size(); ++_index) {
+ char c = (*this)[_index];
+ if (seperatorChars.indexOf(c) == -1)
+ break;
+ }
+}
+
+bool CStringParser::parse(CString &resultStr, const CString &seperatorChars, bool allowQuotes) {
+ if (_index >= size())
+ return false;
+
+ resultStr.clear();
+ bool quoteFlag = false;
+ while (_index < size()) {
+ char c = (*this)[_index];
+ if (!quoteFlag && seperatorChars.indexOf(c) >= 0)
+ break;
+
+ if (allowQuotes) {
+ if (quoteFlag) {
+ if (c == '"') {
+ // End of quoted string
+ ++_index;
+ break;
+ }
+ } else {
+ if (c == '"') {
+ // Start of quoted string
+ ++_index;
+ quoteFlag = true;
+ continue;
+ }
+ }
+ }
+
+ resultStr += c;
+ ++_index;
+ }
+
+ return true;
+}
+
+uint CStringParser::readInt() {
+ // Get digits from the string
+ CString numStr;
+ while (Common::isDigit(currentChar()))
+ numStr += getNextChar();
+
+ // Throw a wobbly if there wasn't a number
+ if (numStr.empty())
+ error("ReadInt(): No number to read");
+
+ return atoi(numStr.c_str());
+}
+
+char CStringParser::currentChar() const {
+ return (_index >= size()) ? '\0' : (*this)[_index];
+}
+
+char CStringParser::getNextChar() {
+ return (_index >= size()) ? '\0' : (*this)[_index++];
+}
+
+void CStringParser::skipSpaces() {
+ while (_index < size() && Common::isSpace(currentChar()))
+ ++_index;
+}
+
+} // End of namespace Titanic
diff --git a/engines/titanic/support/string_parser.h b/engines/titanic/support/string_parser.h
new file mode 100644
index 0000000000..f89caacfb5
--- /dev/null
+++ b/engines/titanic/support/string_parser.h
@@ -0,0 +1,76 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TITANIC_STRING_PARSER_H
+#define TITANIC_STRING_PARSER_H
+
+#include "titanic/support/string.h"
+
+namespace Titanic {
+
+class CStringParser : public CString {
+private:
+ uint _index;
+private:
+ /**
+ * Gets the character at the current index
+ */
+ char currentChar() const;
+
+ /**
+ * Gets the next character, and increments the parsing index
+ */
+ char getNextChar();
+
+ /**
+ * Skips over any spaces
+ */
+ void skipSpaces();
+public:
+ CStringParser() : CString(), _index(0) {}
+ CStringParser(const CString &str) : CString(str), _index(0) {}
+
+ /**
+ * Skips over any specified seperator characters in our string
+ * at the current index
+ */
+ void skipSeperators(const CString &seperatorChars);
+
+ /**
+ * Parses out a string from a source string at the current index
+ * @param resultStr String to hold the resulting sring
+ * @param seperatorChras List of characters that seperate string values
+ * @param allowQuotes If true, handles double-quoted substrings
+ * @returns True if a string entry was extracted
+ */
+ bool parse(CString &resultStr, const CString &seperatorChars, bool allowQuotes = false);
+
+ /**
+ * Reads an integer from the string
+ */
+ uint readInt();
+
+};
+
+} // End of namespace Titanic
+
+#endif /* TITANIC_STRING_PARSER_H */
diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp
index 594f660937..b5f668793a 100644
--- a/engines/titanic/support/video_surface.cpp
+++ b/engines/titanic/support/video_surface.cpp
@@ -163,7 +163,19 @@ void CVideoSurface::blitRect2(const Rect &srcRect, const Rect &destRect, CVideoS
}
void CVideoSurface::movieBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) {
- // TODO
+ if (lock()) {
+ if (src->lock()) {
+ Graphics::ManagedSurface *srcSurface = src->_rawSurface;
+ Graphics::ManagedSurface *destSurface = _rawSurface;
+
+ // TODO: Handle the transparency mode correctly
+ destSurface->blitFrom(*srcSurface, srcRect, Point(srcRect.left, srcRect.top));
+
+ src->unlock();
+ }
+
+ unlock();
+ }
}
uint CVideoSurface::getTransparencyColor() {
diff --git a/engines/titanic/true_talk/title_engine.cpp b/engines/titanic/true_talk/title_engine.cpp
index 4dd45ba335..363cc3454c 100644
--- a/engines/titanic/true_talk/title_engine.cpp
+++ b/engines/titanic/true_talk/title_engine.cpp
@@ -66,10 +66,6 @@ int STtitleEngine::setResponse(TTscriptBase *script, TTresponse *response) {
return 0;
}
-void STtitleEngine::dump(int val1, int val2) {
- // TODO
-}
-
SimpleFile *STtitleEngine::open(const CString &name) {
Common::SeekableReadStream *stream = g_vm->_filesManager->getResource(
CString::format("TEXT/%s", name.c_str()));
diff --git a/engines/titanic/true_talk/title_engine.h b/engines/titanic/true_talk/title_engine.h
index afd2d3b92f..a980e52215 100644
--- a/engines/titanic/true_talk/title_engine.h
+++ b/engines/titanic/true_talk/title_engine.h
@@ -57,12 +57,6 @@ public:
* Sets a conversation reponse
*/
virtual int setResponse(TTscriptBase *script, TTresponse *response) { return SS_4; }
-
- virtual int proc4(int unused) const = 0;
- virtual int proc5(int64 unused) const = 0;
- virtual int proc6(int64 unused) const = 0;
- virtual int proc7(int64 unused) const = 0;
- virtual int proc8() const = 0;
/**
* Open a designated file
@@ -94,14 +88,6 @@ public:
*/
virtual int setResponse(TTscriptBase *script, TTresponse *response);
- virtual void dump(int val1, int val2);
-
- virtual int proc4(int unused) const { return 0; }
- virtual int proc5(int64 unused) const { return 0; }
- virtual int proc6(int64 unused) const { return 0; }
- virtual int proc7(int64 unused) const { return 0; }
- virtual int proc8() const { return 0; }
-
/**
* Open a designated file
*/
diff --git a/engines/titanic/true_talk/true_talk_manager.cpp b/engines/titanic/true_talk/true_talk_manager.cpp
index 19beee9796..c5fd43ebfd 100644
--- a/engines/titanic/true_talk/true_talk_manager.cpp
+++ b/engines/titanic/true_talk/true_talk_manager.cpp
@@ -219,10 +219,6 @@ void CTrueTalkManager::removeCompleted() {
}
}
-void CTrueTalkManager::update2() {
- //warning("CTrueTalkManager::update2");
-}
-
void CTrueTalkManager::start(CTrueTalkNPC *npc, uint id, CViewItem *view) {
TTnpcScript *npcScript = getNpcScript(npc);
TTroomScript *roomScript = getRoomScript();
@@ -589,9 +585,9 @@ int CTrueTalkManager::getPassengerClass() const {
return gameState ? gameState->_passengerClass : 4;
}
-int CTrueTalkManager::getState14() const {
+Season CTrueTalkManager::getCurrentSeason() const {
CGameState *gameState = getGameState();
- return gameState ? gameState->_field14 : 0;
+ return gameState ? gameState->_seasonNum : SEASON_SUMMER;
}
} // End of namespace Titanic
diff --git a/engines/titanic/true_talk/true_talk_manager.h b/engines/titanic/true_talk/true_talk_manager.h
index 8a8895917a..e891f6112a 100644
--- a/engines/titanic/true_talk/true_talk_manager.h
+++ b/engines/titanic/true_talk/true_talk_manager.h
@@ -31,6 +31,7 @@
#include "titanic/true_talk/tt_quotes_tree.h"
#include "titanic/true_talk/tt_scripts.h"
#include "titanic/true_talk/tt_talker.h"
+#include "titanic/game_state.h"
namespace Titanic {
@@ -200,8 +201,6 @@ public:
*/
CGameManager *getGameManager() const;
- void update2();
-
/**
* Start a TrueTalk conversation
*/
@@ -237,7 +236,7 @@ public:
*/
int getPassengerClass() const;
- int getState14() const;
+ Season getCurrentSeason() const;
};
} // End of namespace Titanic
diff --git a/engines/titanic/true_talk/tt_npc_script.cpp b/engines/titanic/true_talk/tt_npc_script.cpp
index 61c3b0e00c..280894c05a 100644
--- a/engines/titanic/true_talk/tt_npc_script.cpp
+++ b/engines/titanic/true_talk/tt_npc_script.cpp
@@ -579,14 +579,14 @@ int TTnpcScript::getValue(int testNum) const {
case 4:
if (g_vm->_trueTalkManager) {
- switch (g_vm->_trueTalkManager->getState14()) {
- case 1:
+ switch (g_vm->_trueTalkManager->getCurrentSeason()) {
+ case SEASON_AUTUMN:
CTrueTalkManager::_v6 = 3;
break;
- case 2:
+ case SEASON_WINTER:
CTrueTalkManager::_v6 = 0;
break;
- case 3:
+ case SEASON_SPRING:
CTrueTalkManager::_v6 = 1;
break;
default:
diff --git a/engines/wage/design.cpp b/engines/wage/design.cpp
index 86b325e2b9..fd2a67b81e 100644
--- a/engines/wage/design.cpp
+++ b/engines/wage/design.cpp
@@ -235,9 +235,9 @@ void drawPixel(int x, int y, int color, void *data) {
color : kColorWhite;
}
} else {
- int x1 = x;
+ int x1 = x - p->thickness / 2;
int x2 = x1 + p->thickness;
- int y1 = y;
+ int y1 = y - p->thickness / 2;
int y2 = y1 + p->thickness;
for (y = y1; y < y2; y++)
diff --git a/graphics/primitives.cpp b/graphics/primitives.cpp
index ac1c58b1d8..8663a61606 100644
--- a/graphics/primitives.cpp
+++ b/graphics/primitives.cpp
@@ -108,15 +108,13 @@ void drawThickLine2(int x1, int y1, int x2, int y2, int thick, int color, void (
int dy = abs(y2 - y1);
if (dx == 0) {
- if (y1 > y2)
- SWAP(y1, y2);
- Common::Rect r(x1, y1, x1 + thick - 1, y2);
+ int xn = x1 - thick / 2;
+ Common::Rect r(xn, MIN(y1, y2), xn + thick - 1, MAX(y1, y2));
drawFilledRect(r, color, plotProc, data);
return;
} else if (dy == 0) {
- if (x1 > x2)
- SWAP(x1, x2);
- Common::Rect r(x1, y1, x2, y1 + thick - 1);
+ int yn = y1 - thick / 2;
+ Common::Rect r(MIN(x1, x2), yn, MAX(x1, x2), yn + thick - 1);
drawFilledRect(r, color, plotProc, data);
return;
}