2014-05-16 21:58:49 +02:00
/* 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 "bladerunner/bladerunner.h"
2015-05-02 22:31:07 +02:00
# include "bladerunner/actor.h"
2018-01-14 12:12:06 +01:00
# include "bladerunner/actor_dialogue_queue.h"
2015-02-06 15:31:43 +01:00
# include "bladerunner/ambient_sounds.h"
2017-08-24 23:43:47 +02:00
# include "bladerunner/audio_mixer.h"
2015-02-06 15:31:43 +01:00
# include "bladerunner/audio_player.h"
2015-02-10 19:33:35 +01:00
# include "bladerunner/audio_speech.h"
2014-05-16 21:58:49 +02:00
# include "bladerunner/chapters.h"
2016-09-10 18:16:17 +02:00
# include "bladerunner/combat.h"
2016-10-06 00:59:11 +02:00
# include "bladerunner/crimes_database.h"
2018-02-25 19:31:52 +01:00
# include "bladerunner/debugger.h"
2017-08-22 18:57:50 +02:00
# include "bladerunner/dialogue_menu.h"
2016-10-06 21:23:46 +02:00
# include "bladerunner/font.h"
2018-01-14 12:12:06 +01:00
# include "bladerunner/game_flags.h"
# include "bladerunner/game_info.h"
2014-05-16 21:58:49 +02:00
# include "bladerunner/image.h"
2016-10-08 21:06:22 +02:00
# include "bladerunner/item_pickup.h"
2016-09-10 18:16:17 +02:00
# include "bladerunner/items.h"
# include "bladerunner/lights.h"
2015-05-01 09:43:04 +02:00
# include "bladerunner/mouse.h"
2017-09-10 20:19:02 +02:00
# include "bladerunner/music.h"
2014-05-17 17:13:49 +02:00
# include "bladerunner/outtake.h"
2016-10-04 02:21:08 +02:00
# include "bladerunner/obstacles.h"
2017-08-27 22:39:36 +02:00
# include "bladerunner/overlays.h"
2017-08-24 23:43:47 +02:00
# include "bladerunner/regions.h"
2018-03-17 16:14:48 +01:00
# include "bladerunner/savefile.h"
2014-05-25 15:01:06 +02:00
# include "bladerunner/scene.h"
2015-09-13 01:48:13 +02:00
# include "bladerunner/scene_objects.h"
2017-09-10 20:19:02 +02:00
# include "bladerunner/screen_effects.h"
2018-01-14 12:12:06 +01:00
# include "bladerunner/set.h"
2018-02-10 20:34:28 +01:00
# include "bladerunner/script/ai_script.h"
# include "bladerunner/script/init_script.h"
# include "bladerunner/script/kia_script.h"
2018-03-24 02:42:51 +01:00
# include "bladerunner/script/police_maze.h"
2018-02-10 20:34:28 +01:00
# include "bladerunner/script/scene_script.h"
2014-05-16 21:58:49 +02:00
# include "bladerunner/settings.h"
2015-05-01 09:43:04 +02:00
# include "bladerunner/shape.h"
2014-06-05 23:49:57 +02:00
# include "bladerunner/slice_animations.h"
# include "bladerunner/slice_renderer.h"
2018-06-18 14:10:00 +03:00
# if SUBTITLES_SUPPORT
# include "bladerunner/subtitles.h"
# endif // SUBTITLES_SUPPORT
2017-08-24 23:43:47 +02:00
# include "bladerunner/suspects_database.h"
2015-02-07 17:08:08 +01:00
# include "bladerunner/text_resource.h"
2018-03-23 23:14:34 +01:00
# include "bladerunner/time.h"
2018-01-14 12:12:06 +01:00
# include "bladerunner/ui/elevator.h"
2018-03-27 18:43:27 +02:00
# include "bladerunner/ui/end_credits.h"
2018-01-31 00:37:19 +01:00
# include "bladerunner/ui/esper.h"
2018-01-14 12:12:06 +01:00
# include "bladerunner/ui/kia.h"
2018-03-25 16:52:48 +02:00
# include "bladerunner/ui/scores.h"
2018-01-14 12:12:06 +01:00
# include "bladerunner/ui/spinner.h"
2018-02-10 20:34:28 +01:00
# include "bladerunner/ui/vk.h"
2014-05-16 21:58:49 +02:00
# include "bladerunner/vqa_decoder.h"
2015-09-15 20:26:46 +02:00
# include "bladerunner/waypoints.h"
2017-03-28 17:50:04 +02:00
# include "bladerunner/zbuffer.h"
2014-05-16 21:58:49 +02:00
2015-05-01 09:43:04 +02:00
# include "common/array.h"
2018-04-03 22:04:20 +02:00
# include "common/config-manager.h"
2014-05-16 21:58:49 +02:00
# include "common/error.h"
# include "common/events.h"
2018-03-17 16:14:48 +01:00
# include "common/savefile.h"
2014-05-16 21:58:49 +02:00
# include "common/system.h"
# include "engines/util.h"
2018-01-14 13:33:45 +01:00
# include "engines/advancedDetector.h"
2014-05-16 21:58:49 +02:00
# include "graphics/pixelformat.h"
2017-08-24 23:43:47 +02:00
2014-05-16 21:58:49 +02:00
namespace BladeRunner {
2018-01-14 13:33:45 +01:00
BladeRunnerEngine : : BladeRunnerEngine ( OSystem * syst , const ADGameDescription * desc )
2016-10-12 23:00:33 +02:00
: Engine ( syst ) ,
_rnd ( " bladerunner " ) {
2018-01-14 12:12:06 +01:00
2014-05-16 21:58:49 +02:00
_windowIsActive = true ;
2018-02-12 20:53:13 +01:00
_gameIsRunning = true ;
2018-03-27 23:43:38 +02:00
_vqaIsPlaying = false ;
_vqaStopIsRequested = false ;
2015-05-01 10:13:30 +02:00
_playerLosesControlCounter = 0 ;
2014-05-16 21:58:49 +02:00
2016-10-22 18:30:46 +02:00
_playerActorIdle = false ;
2018-02-12 20:53:13 +01:00
_playerDead = false ;
_speechSkipped = false ;
_gameOver = false ;
_gameAutoSave = 0 ;
_gameIsLoading = false ;
_sceneIsLoading = false ;
2018-02-18 22:18:41 +01:00
_runningActorId = - 1 ;
2018-02-12 20:53:13 +01:00
_isWalkingInterruptible = false ;
_interruptWalking = false ;
_walkSoundId = - 1 ;
_walkSoundVolume = 0 ;
2016-09-29 22:30:50 +02:00
_walkSoundBalance = 0 ;
2018-01-14 13:33:45 +01:00
2018-01-14 12:12:06 +01:00
_crimesDatabase = nullptr ;
2018-01-14 13:33:45 +01:00
switch ( desc - > language ) {
2018-02-05 18:46:09 +01:00
case Common : : EN_ANY :
2018-02-13 23:08:37 +01:00
_languageCode = " E " ;
2018-02-05 18:46:09 +01:00
break ;
case Common : : DE_DEU :
2018-02-13 23:08:37 +01:00
_languageCode = " G " ;
2018-02-05 18:46:09 +01:00
break ;
case Common : : FR_FRA :
2018-02-13 23:08:37 +01:00
_languageCode = " F " ;
2018-02-05 18:46:09 +01:00
break ;
case Common : : IT_ITA :
2018-02-13 23:08:37 +01:00
_languageCode = " I " ;
2018-02-05 18:46:09 +01:00
break ;
case Common : : RU_RUS :
2018-02-13 23:08:37 +01:00
_languageCode = " R " ;
2018-02-05 18:46:09 +01:00
break ;
case Common : : ES_ESP :
2018-02-13 23:08:37 +01:00
_languageCode = " S " ;
2018-02-05 18:46:09 +01:00
break ;
default :
2018-02-13 23:08:37 +01:00
_languageCode = " E " ;
2018-01-14 13:33:45 +01:00
}
2018-02-01 20:40:49 +01:00
_screenEffects = nullptr ;
_combat = nullptr ;
_actorDialogueQueue = nullptr ;
_settings = nullptr ;
_itemPickup = nullptr ;
_lights = nullptr ;
_obstacles = nullptr ;
_sceneScript = nullptr ;
2018-12-15 22:40:07 +01:00
_time = nullptr ;
2018-02-01 20:40:49 +01:00
_gameInfo = nullptr ;
_waypoints = nullptr ;
_gameVars = nullptr ;
_view = nullptr ;
_sceneObjects = nullptr ;
_gameFlags = nullptr ;
_items = nullptr ;
_audioMixer = nullptr ;
_audioPlayer = nullptr ;
_music = nullptr ;
_audioSpeech = nullptr ;
_ambientSounds = nullptr ;
_chapters = nullptr ;
_overlays = nullptr ;
_zbuffer = nullptr ;
_playerActor = nullptr ;
_textActorNames = nullptr ;
_textCrimes = nullptr ;
_textClueTypes = nullptr ;
_textKIA = nullptr ;
_textSpinnerDestinations = nullptr ;
_textVK = nullptr ;
_textOptions = nullptr ;
_dialogueMenu = nullptr ;
_suspectsDatabase = nullptr ;
_kia = nullptr ;
2018-03-27 18:43:27 +02:00
_endCredits = nullptr ;
2018-02-01 20:40:49 +01:00
_spinner = nullptr ;
2018-03-27 18:47:22 +02:00
_scores = nullptr ;
2018-02-01 20:40:49 +01:00
_elevator = nullptr ;
_mainFont = nullptr ;
2018-06-18 14:10:00 +03:00
# if SUBTITLES_SUPPORT
_subtitles = nullptr ;
# endif // SUBTITLES_SUPPORT
2018-02-12 20:53:13 +01:00
_esper = nullptr ;
_vk = nullptr ;
2018-03-28 23:41:29 +02:00
_policeMaze = nullptr ;
2018-02-01 20:40:49 +01:00
_mouse = nullptr ;
_sliceAnimations = nullptr ;
_sliceRenderer = nullptr ;
_crimesDatabase = nullptr ;
_scene = nullptr ;
_aiScripts = nullptr ;
for ( int i = 0 ; i ! = kActorCount ; + + i ) {
2018-02-25 19:31:52 +01:00
_actors [ i ] = nullptr ;
2018-02-01 20:40:49 +01:00
}
2018-02-25 19:31:52 +01:00
_debugger = nullptr ;
2018-02-18 22:18:41 +01:00
walkingReset ( ) ;
2018-02-25 19:31:52 +01:00
_actorUpdateCounter = 0 ;
2014-05-16 21:58:49 +02:00
}
2014-05-30 13:52:59 -07:00
BladeRunnerEngine : : ~ BladeRunnerEngine ( ) {
}
2014-05-16 21:58:49 +02:00
bool BladeRunnerEngine : : hasFeature ( EngineFeature f ) const {
2018-11-21 23:16:15 +01:00
return
f = = kSupportsRTL | |
f = = kSupportsLoadingDuringRuntime | |
f = = kSupportsSavingDuringRuntime ;
}
bool BladeRunnerEngine : : canLoadGameStateCurrently ( ) {
return
playerHasControl ( ) & &
! _sceneScript - > isInsideScript ( ) & &
! _aiScripts - > isInsideScript ( ) & &
! _kia - > isOpen ( ) & &
! _spinner - > isOpen ( ) & &
! _vk - > isOpen ( ) & &
! _elevator - > isOpen ( ) ;
}
Common : : Error BladeRunnerEngine : : loadGameState ( int slot ) {
2018-12-05 18:18:13 +01:00
Common : : InSaveFile * saveFile = BladeRunner : : SaveFileManager : : openForLoading ( _targetName , slot ) ;
2018-11-21 23:16:15 +01:00
if ( saveFile = = nullptr | | saveFile - > err ( ) ) {
delete saveFile ;
return Common : : kReadingFailed ;
}
BladeRunner : : SaveFileHeader header ;
2018-11-25 21:47:00 +01:00
if ( ! BladeRunner : : SaveFileManager : : readHeader ( * saveFile , header ) ) {
2018-11-21 23:16:15 +01:00
error ( " Invalid savegame " ) ;
}
loadGame ( * saveFile ) ;
delete saveFile ;
return Common : : kNoError ;
}
bool BladeRunnerEngine : : canSaveGameStateCurrently ( ) {
return
playerHasControl ( ) & &
! _sceneScript - > isInsideScript ( ) & &
! _aiScripts - > isInsideScript ( ) & &
! _kia - > isOpen ( ) & &
! _spinner - > isOpen ( ) & &
! _vk - > isOpen ( ) & &
! _elevator - > isOpen ( ) ;
}
Common : : Error BladeRunnerEngine : : saveGameState ( int slot , const Common : : String & desc ) {
2018-12-05 18:18:13 +01:00
Common : : OutSaveFile * saveFile = BladeRunner : : SaveFileManager : : openForSaving ( _targetName , slot ) ;
2018-11-21 23:16:15 +01:00
if ( saveFile = = nullptr | | saveFile - > err ( ) ) {
delete saveFile ;
return Common : : kReadingFailed ;
}
2018-11-25 21:47:00 +01:00
Graphics : : Surface thumbnail = generateThumbnail ( ) ;
2018-11-21 23:16:15 +01:00
BladeRunner : : SaveFileHeader header ;
header . _name = desc ;
2018-11-25 21:47:00 +01:00
BladeRunner : : SaveFileManager : : writeHeader ( * saveFile , header ) ;
2018-11-21 23:16:15 +01:00
saveGame ( * saveFile , thumbnail ) ;
saveFile - > finalize ( ) ;
2018-11-25 21:47:00 +01:00
thumbnail . free ( ) ;
2018-11-21 23:16:15 +01:00
delete saveFile ;
return Common : : kNoError ;
2014-05-16 21:58:49 +02:00
}
Common : : Error BladeRunnerEngine : : run ( ) {
2014-05-30 12:45:01 -07:00
Graphics : : PixelFormat format = createRGB555 ( ) ;
2017-10-01 00:56:01 -05:00
initGraphics ( 640 , 480 , & format ) ;
2014-05-16 21:58:49 +02:00
2015-02-06 15:31:43 +01:00
_system - > showMouse ( true ) ;
2018-11-25 21:47:00 +01:00
bool hasSavegames = ! SaveFileManager : : list ( _targetName ) . empty ( ) ;
if ( ! startup ( hasSavegames ) ) {
2015-02-10 21:09:12 +01:00
shutdown ( ) ;
2014-05-30 10:24:24 -07:00
return Common : : Error ( Common : : kUnknownError , " Failed to initialize resources " ) ;
2015-02-10 21:09:12 +01:00
}
2014-05-16 21:58:49 +02:00
2018-11-25 21:47:00 +01:00
2018-01-28 20:59:12 +01:00
# if BLADERUNNER_DEBUG_GAME
{
# else
2014-05-20 11:30:16 +02:00
if ( warnUserAboutUnsupportedGame ( ) ) {
2018-01-28 20:59:12 +01:00
# endif
2018-11-25 21:47:00 +01:00
if ( hasSavegames ) {
_kia - > _forceOpen = true ;
_kia - > open ( kKIASectionLoad ) ;
}
// TODO: why is game starting new game here when everything is done in startup?
// else {
// newGame(1);
// }
2014-05-16 21:58:49 +02:00
2014-05-20 11:30:16 +02:00
gameLoop ( ) ;
2018-03-27 18:43:27 +02:00
_mouse - > disable ( ) ;
if ( _gameOver ) {
// autoSaveGame(4, 1); // TODO
_endCredits - > show ( ) ;
}
2014-05-20 11:30:16 +02:00
}
2014-05-16 21:58:49 +02:00
shutdown ( ) ;
return Common : : kNoError ;
}
2015-05-02 12:01:47 +02:00
bool BladeRunnerEngine : : startup ( bool hasSavegames ) {
2018-01-14 12:12:06 +01:00
// These are static objects in original game
_screenEffects = new ScreenEffects ( this , 0x8000 ) ;
2018-03-27 18:43:27 +02:00
_endCredits = new EndCredits ( this ) ;
2018-01-14 12:12:06 +01:00
_actorDialogueQueue = new ActorDialogueQueue ( this ) ;
_settings = new Settings ( this ) ;
_itemPickup = new ItemPickup ( this ) ;
_lights = new Lights ( this ) ;
// TODO: outtake player - but this is done bit differently
2018-03-23 18:47:04 +01:00
_policeMaze = new PoliceMaze ( this ) ;
2018-01-14 12:12:06 +01:00
_obstacles = new Obstacles ( this ) ;
_sceneScript = new SceneScript ( this ) ;
2018-02-25 19:31:52 +01:00
_debugger = new Debugger ( this ) ;
2018-01-14 12:12:06 +01:00
// This is the original startup in the game
2014-05-16 21:58:49 +02:00
bool r ;
2018-01-14 12:12:06 +01:00
_surfaceFront . create ( 640 , 480 , createRGB555 ( ) ) ;
_surfaceBack . create ( 640 , 480 , createRGB555 ( ) ) ;
2017-07-30 22:34:21 +02:00
_surface4 . create ( 640 , 480 , createRGB555 ( ) ) ;
2014-05-16 21:58:49 +02:00
2018-12-15 22:40:07 +01:00
_time = new Time ( this ) ;
2018-03-23 23:14:34 +01:00
2014-05-16 21:58:49 +02:00
r = openArchive ( " STARTUP.MIX " ) ;
if ( ! r )
return false ;
_gameInfo = new GameInfo ( this ) ;
if ( ! _gameInfo )
return false ;
r = _gameInfo - > open ( " GAMEINFO.DAT " ) ;
2018-03-17 16:40:33 +01:00
if ( ! r ) {
2014-05-16 21:58:49 +02:00
return false ;
2018-03-17 16:40:33 +01:00
}
2014-05-16 21:58:49 +02:00
2016-10-08 21:06:22 +02:00
// TODO: Create datetime - not used
2015-05-02 12:01:47 +02:00
// TODO: Create graphics surfaces 1-4
// TODO: Allocate audio cache
if ( hasSavegames ) {
if ( ! loadSplash ( ) ) {
return false ;
}
}
2015-09-15 20:26:46 +02:00
_waypoints = new Waypoints ( this , _gameInfo - > getWaypointCount ( ) ) ;
2015-05-02 12:01:47 +02:00
2018-11-25 21:47:00 +01:00
_combat = new Combat ( this ) ;
2015-02-06 15:31:43 +01:00
2018-03-17 16:14:48 +01:00
_gameVars = new int [ _gameInfo - > getGlobalVarCount ( ) ] ( ) ;
2015-02-06 15:31:43 +01:00
2018-11-25 21:47:00 +01:00
// TODO: Init Actor AI Update counter
2015-05-02 12:01:47 +02:00
// Seed rand
// TODO: Sine and cosine lookup tables for intervals of 1.0, 4.0, and 12.0
2018-11-21 23:16:15 +01:00
_cosTable1024 = new Common : : CosineTable ( 1024 ) ; // 10-bits = 1024 points for 2*PI;
_sinTable1024 = new Common : : SineTable ( 1024 ) ;
2015-05-02 12:01:47 +02:00
2016-09-10 18:16:17 +02:00
_view = new View ( ) ;
2015-05-02 12:01:47 +02:00
2015-09-13 01:48:13 +02:00
_sceneObjects = new SceneObjects ( this , _view ) ;
2015-05-02 12:01:47 +02:00
_gameFlags = new GameFlags ( ) ;
_gameFlags - > setFlagCount ( _gameInfo - > getFlagCount ( ) ) ;
2018-06-18 14:10:00 +03:00
# if BLADERUNNER_RESTORED_CONTENT_GAME
// EDS flags
_extraGameFlagsForRestoredContent = new GameFlags ( ) ; //aux flags - custom
_extraGameFlagsForRestoredContent - > setFlagCount ( RESTORED_CONTENT_EXTRA_FLAGS + 1 ) ; // aux flags - custom // +1 since we don't assign something to 0 enum value
# if SUBTITLES_SUPPORT
# if SUBTITLES_ENABLED_BY_DEFAULT
// subtitles enable by default:
_extraGameFlagsForRestoredContent - > set ( kEDSFlagSubtitlesEnable ) ;
# else
_extraGameFlagsForRestoredContent - > reset ( kEDSFlagSubtitlesEnable ) ;
# endif // SUBTITLES_ENABLED_BY_DEFAULT
# endif // SUBTITLES_SUPPORT
# endif // BLADERUNNER_RESTORED_CONTENT_GAME
2015-05-02 12:01:47 +02:00
2015-09-15 20:26:46 +02:00
_items = new Items ( this ) ;
2015-05-02 12:01:47 +02:00
2017-08-24 23:43:47 +02:00
_audioMixer = new AudioMixer ( this ) ;
2015-05-02 12:01:47 +02:00
_audioPlayer = new AudioPlayer ( this ) ;
2017-09-10 20:19:02 +02:00
_music = new Music ( this ) ;
2015-05-02 12:01:47 +02:00
_audioSpeech = new AudioSpeech ( this ) ;
_ambientSounds = new AmbientSounds ( this ) ;
// TODO: Read BLADE.INI
2014-05-16 21:58:49 +02:00
_chapters = new Chapters ( this ) ;
if ( ! _chapters )
return false ;
2015-05-02 12:01:47 +02:00
if ( ! openArchive ( " MUSIC.MIX " ) )
2014-05-16 21:58:49 +02:00
return false ;
2015-05-02 12:01:47 +02:00
if ( ! openArchive ( " SFX.MIX " ) )
2014-05-16 21:58:49 +02:00
return false ;
2015-05-02 12:01:47 +02:00
if ( ! openArchive ( " SPCHSFX.TLK " ) )
return false ;
2017-08-27 22:39:36 +02:00
_overlays = new Overlays ( this ) ;
_overlays - > init ( ) ;
2015-05-02 12:01:47 +02:00
2017-03-28 17:50:04 +02:00
_zbuffer = new ZBuffer ( ) ;
_zbuffer - > init ( 640 , 480 ) ;
2015-05-02 12:01:47 +02:00
2015-05-02 22:31:07 +02:00
int actorCount = ( int ) _gameInfo - > getActorCount ( ) ;
2018-01-14 12:12:06 +01:00
assert ( actorCount < kActorCount ) ;
2015-05-02 22:31:07 +02:00
for ( int i = 0 ; i ! = actorCount ; + + i ) {
_actors [ i ] = new Actor ( this , i ) ;
2016-09-10 18:16:17 +02:00
_actors [ i ] - > setup ( i ) ;
2015-05-02 22:31:07 +02:00
}
2018-01-14 12:12:06 +01:00
_actors [ kActorVoiceOver ] = new Actor ( this , kActorVoiceOver ) ;
2015-05-02 22:31:07 +02:00
_playerActor = _actors [ _gameInfo - > getPlayerId ( ) ] ;
2015-05-02 12:01:47 +02:00
2016-09-10 18:16:17 +02:00
_playerActor - > setFPS ( 15 ) ;
2018-02-18 22:18:41 +01:00
_playerActor - > timerStart ( 6 , 200 ) ;
2015-05-02 12:01:47 +02:00
// TODO: Set actor ids (redundant?)
2018-03-17 16:14:48 +01:00
_policeMaze = new PoliceMaze ( this ) ;
2015-05-02 12:01:47 +02:00
_textActorNames = new TextResource ( this ) ;
if ( ! _textActorNames - > open ( " ACTORS " ) )
return false ;
_textCrimes = new TextResource ( this ) ;
if ( ! _textCrimes - > open ( " CRIMES " ) )
return false ;
2018-01-14 12:12:06 +01:00
_textClueTypes = new TextResource ( this ) ;
if ( ! _textClueTypes - > open ( " CLUETYPE " ) )
2015-05-02 12:01:47 +02:00
return false ;
_textKIA = new TextResource ( this ) ;
if ( ! _textKIA - > open ( " KIA " ) )
return false ;
2017-03-29 01:50:47 +02:00
_textSpinnerDestinations = new TextResource ( this ) ;
if ( ! _textSpinnerDestinations - > open ( " SPINDEST " ) )
2014-05-16 21:58:49 +02:00
return false ;
2015-05-02 12:01:47 +02:00
_textVK = new TextResource ( this ) ;
if ( ! _textVK - > open ( " VK " ) )
return false ;
_textOptions = new TextResource ( this ) ;
if ( ! _textOptions - > open ( " OPTIONS " ) )
return false ;
2017-08-22 18:57:50 +02:00
_dialogueMenu = new DialogueMenu ( this ) ;
if ( ! _dialogueMenu - > loadText ( " DLGMENU " ) )
return false ;
2015-05-02 12:01:47 +02:00
2018-01-14 12:12:06 +01:00
_suspectsDatabase = new SuspectsDatabase ( this , _gameInfo - > getSuspectCount ( ) ) ;
2015-05-02 12:01:47 +02:00
2018-01-14 12:12:06 +01:00
_kia = new KIA ( this ) ;
2015-05-02 12:01:47 +02:00
2017-07-31 00:11:00 +02:00
_spinner = new Spinner ( this ) ;
2015-05-02 12:01:47 +02:00
2017-08-24 22:34:40 +02:00
_elevator = new Elevator ( this ) ;
2015-05-02 12:01:47 +02:00
2018-03-25 16:52:48 +02:00
_scores = new Scores ( this ) ;
2015-05-02 12:01:47 +02:00
2016-10-06 21:23:46 +02:00
_mainFont = new Font ( this ) ;
_mainFont - > open ( " KIA6PT.FON " , 640 , 480 , - 1 , 0 , 0x252D ) ;
2016-10-12 23:00:33 +02:00
_mainFont - > setSpacing ( 1 , 0 ) ;
2018-06-18 14:10:00 +03:00
# if SUBTITLES_SUPPORT
_subtitles = new Subtitles ( this ) ;
# endif // SUBTITLES_SUPPORT
2015-05-02 12:01:47 +02:00
2015-05-01 09:43:04 +02:00
for ( int i = 0 ; i ! = 43 ; + + i ) {
Shape * shape = new Shape ( this ) ;
2018-01-31 00:37:19 +01:00
shape - > open ( " SHAPES.SHP " , i ) ;
2015-05-01 09:43:04 +02:00
_shapes . push_back ( shape ) ;
}
2015-05-02 12:01:47 +02:00
2018-01-31 00:37:19 +01:00
_esper = new ESPER ( this ) ;
2015-05-02 12:01:47 +02:00
2018-02-10 20:34:28 +01:00
_vk = new VK ( this ) ;
2015-05-02 12:01:47 +02:00
_mouse = new Mouse ( this ) ;
// _mouse->setCursorPosition(320, 240);
2015-05-01 09:43:04 +02:00
_mouse - > setCursor ( 0 ) ;
2015-05-02 12:01:47 +02:00
_sliceAnimations = new SliceAnimations ( this ) ;
2014-06-05 23:49:57 +02:00
r = _sliceAnimations - > open ( " INDEX.DAT " ) ;
if ( ! r )
return false ;
2015-05-02 12:01:47 +02:00
r = _sliceAnimations - > openCoreAnim ( ) ;
2017-08-26 21:27:54 +02:00
if ( ! r ) {
2015-05-02 12:01:47 +02:00
return false ;
2017-08-26 21:27:54 +02:00
}
2015-02-06 15:31:43 +01:00
2015-05-02 12:01:47 +02:00
_sliceRenderer = new SliceRenderer ( this ) ;
2017-09-10 20:19:02 +02:00
_sliceRenderer - > setScreenEffects ( _screenEffects ) ;
2015-02-07 17:08:08 +01:00
2016-10-06 00:59:11 +02:00
_crimesDatabase = new CrimesDatabase ( this , " CLUES " , _gameInfo - > getClueCount ( ) ) ;
2015-02-07 17:08:08 +01:00
2015-05-02 12:01:47 +02:00
// TODO: Scene
_scene = new Scene ( this ) ;
// Load INIT.DLL
2018-02-10 20:34:28 +01:00
InitScript initScript ( this ) ;
2015-02-07 11:41:52 +01:00
initScript . SCRIPT_Initialize_Game ( ) ;
2015-05-02 12:01:47 +02:00
// TODO: Load AI-ACT1.DLL
2017-03-20 22:55:31 +01:00
_aiScripts = new AIScripts ( this , actorCount ) ;
2015-05-02 12:01:47 +02:00
2014-05-25 15:01:06 +02:00
initChapterAndScene ( ) ;
2014-05-16 21:58:49 +02:00
return true ;
}
2014-05-25 15:01:06 +02:00
void BladeRunnerEngine : : initChapterAndScene ( ) {
2014-05-16 21:58:49 +02:00
// TODO: Init actors...
2017-03-23 16:20:10 +01:00
for ( int i = 0 , end = _gameInfo - > getActorCount ( ) ; i ! = end ; + + i ) {
2018-02-10 20:34:28 +01:00
_aiScripts - > initialize ( i ) ;
2017-03-23 16:20:10 +01:00
}
2016-09-10 18:16:17 +02:00
2017-03-23 16:20:10 +01:00
for ( int i = 0 , end = _gameInfo - > getActorCount ( ) ; i ! = end ; + + i ) {
2017-03-29 01:50:47 +02:00
_actors [ i ] - > changeAnimationMode ( kAnimationModeIdle ) ;
2017-03-23 16:20:10 +01:00
}
for ( int i = 1 , end = _gameInfo - > getActorCount ( ) ; i ! = end ; + + i ) { // skip first actor, probably player
_actors [ i ] - > movementTrackNext ( true ) ;
}
2014-05-16 21:58:49 +02:00
2018-04-03 22:04:20 +02:00
if ( ConfMan . hasKey ( " boot_param " ) ) {
int param = ConfMan . getInt ( " boot_param " ) ; // CTTTSSS
int chapter = param / 1000000 ;
param - = chapter * 1000000 ;
int set = param / 1000 ;
param - = set * 1000 ;
int scene = param ;
_settings - > setChapter ( chapter ) ;
_settings - > setNewSetAndScene ( set , scene ) ;
} else {
_settings - > setChapter ( 1 ) ;
_settings - > setNewSetAndScene ( _gameInfo - > getInitialSetId ( ) , _gameInfo - > getInitialSceneId ( ) ) ;
}
2014-05-16 21:58:49 +02:00
}
void BladeRunnerEngine : : shutdown ( ) {
2015-02-06 15:31:43 +01:00
_mixer - > stopAll ( ) ;
2015-05-02 12:01:47 +02:00
// TODO: Write BLADE.INI
2018-02-10 20:34:28 +01:00
delete _vk ;
_vk = nullptr ;
2015-05-02 12:01:47 +02:00
2018-01-31 00:37:19 +01:00
delete _esper ;
_esper = nullptr ;
2015-05-02 12:01:47 +02:00
delete _mouse ;
2016-10-02 02:47:12 +02:00
_mouse = nullptr ;
2015-05-02 12:01:47 +02:00
for ( uint i = 0 ; i ! = _shapes . size ( ) ; + + i ) {
delete _shapes [ i ] ;
}
_shapes . clear ( ) ;
// TODO: Shutdown Scene
delete _scene ;
2014-05-16 21:58:49 +02:00
if ( _chapters ) {
if ( _chapters - > hasOpenResources ( ) )
_chapters - > closeResources ( ) ;
delete _chapters ;
2016-10-02 02:47:12 +02:00
_chapters = nullptr ;
2014-05-16 21:58:49 +02:00
}
2016-10-06 00:59:11 +02:00
delete _crimesDatabase ;
_crimesDatabase = nullptr ;
2015-05-02 12:01:47 +02:00
delete _sliceRenderer ;
2016-10-02 02:47:12 +02:00
_sliceRenderer = nullptr ;
2015-05-02 12:01:47 +02:00
delete _sliceAnimations ;
2016-10-02 02:47:12 +02:00
_sliceAnimations = nullptr ;
2015-05-02 12:01:47 +02:00
delete _textActorNames ;
2016-10-02 02:47:12 +02:00
_textActorNames = nullptr ;
2015-05-02 12:01:47 +02:00
delete _textCrimes ;
2016-10-02 02:47:12 +02:00
_textCrimes = nullptr ;
2015-05-02 12:01:47 +02:00
2018-01-14 12:12:06 +01:00
delete _textClueTypes ;
_textClueTypes = nullptr ;
2015-05-02 12:01:47 +02:00
delete _textKIA ;
2016-10-02 02:47:12 +02:00
_textKIA = nullptr ;
2015-05-02 12:01:47 +02:00
2017-03-29 01:50:47 +02:00
delete _textSpinnerDestinations ;
_textSpinnerDestinations = nullptr ;
2015-05-02 12:01:47 +02:00
delete _textVK ;
2016-10-02 02:47:12 +02:00
_textVK = nullptr ;
2015-05-02 12:01:47 +02:00
delete _textOptions ;
2016-10-02 02:47:12 +02:00
_textOptions = nullptr ;
2015-05-02 12:01:47 +02:00
2017-09-10 20:19:02 +02:00
delete _dialogueMenu ;
_dialogueMenu = nullptr ;
2015-05-02 12:01:47 +02:00
delete _ambientSounds ;
2017-09-10 20:19:02 +02:00
_ambientSounds = nullptr ;
2015-05-02 12:01:47 +02:00
2017-08-27 22:39:36 +02:00
delete _overlays ;
_overlays = nullptr ;
2015-05-02 12:01:47 +02:00
delete _audioSpeech ;
2017-09-10 20:19:02 +02:00
_audioSpeech = nullptr ;
2015-05-02 12:01:47 +02:00
2017-09-10 20:19:02 +02:00
delete _music ;
_music = nullptr ;
2015-05-02 12:01:47 +02:00
delete _audioPlayer ;
2017-09-10 20:19:02 +02:00
_audioPlayer = nullptr ;
2015-05-02 12:01:47 +02:00
2017-08-24 23:43:47 +02:00
delete _audioMixer ;
2017-09-10 20:19:02 +02:00
_audioMixer = nullptr ;
2015-05-02 12:01:47 +02:00
2017-09-10 20:19:02 +02:00
if ( isArchiveOpen ( " MUSIC.MIX " ) ) {
2014-05-16 21:58:49 +02:00
closeArchive ( " MUSIC.MIX " ) ;
2017-09-10 20:19:02 +02:00
}
2014-05-16 21:58:49 +02:00
2017-09-10 20:19:02 +02:00
if ( isArchiveOpen ( " SFX.MIX " ) ) {
2014-05-16 21:58:49 +02:00
closeArchive ( " SFX.MIX " ) ;
2017-09-10 20:19:02 +02:00
}
2014-05-16 21:58:49 +02:00
2017-09-10 20:19:02 +02:00
if ( isArchiveOpen ( " SPCHSFX.TLK " ) ) {
2014-05-16 21:58:49 +02:00
closeArchive ( " SPCHSFX.TLK " ) ;
2017-09-10 20:19:02 +02:00
}
2014-05-16 21:58:49 +02:00
2016-10-12 23:00:33 +02:00
if ( _mainFont ) {
2016-10-06 21:23:46 +02:00
_mainFont - > close ( ) ;
delete _mainFont ;
_mainFont = nullptr ;
}
2015-05-02 12:01:47 +02:00
2018-06-18 14:10:00 +03:00
# if SUBTITLES_SUPPORT
if ( _subtitles ) {
delete _subtitles ;
_subtitles = nullptr ;
}
# endif // SUBTITLES_SUPPORT//
2015-09-19 01:43:38 +02:00
delete _items ;
2016-10-02 02:47:12 +02:00
_items = nullptr ;
2015-05-02 12:01:47 +02:00
delete _gameFlags ;
2016-10-02 02:47:12 +02:00
_gameFlags = nullptr ;
2015-05-02 12:01:47 +02:00
2015-09-13 01:48:13 +02:00
delete _view ;
2016-10-02 02:47:12 +02:00
_view = nullptr ;
2015-05-02 12:01:47 +02:00
2015-09-13 01:48:13 +02:00
delete _sceneObjects ;
2016-10-02 02:47:12 +02:00
_sceneObjects = nullptr ;
2015-05-02 12:01:47 +02:00
2018-06-23 21:34:38 -07:00
delete _cosTable1024 ;
delete _sinTable1024 ;
2015-05-02 12:01:47 +02:00
2016-10-28 22:34:04 +02:00
delete _aiScripts ;
_aiScripts = nullptr ;
2015-05-02 12:01:47 +02:00
delete [ ] _gameVars ;
2016-10-02 02:47:12 +02:00
_gameVars = nullptr ;
2015-05-02 12:01:47 +02:00
2016-09-10 18:16:17 +02:00
delete _waypoints ;
2016-10-02 02:47:12 +02:00
_waypoints = nullptr ;
2015-05-02 12:01:47 +02:00
// TODO: Delete Cover waypoints
// TODO: Delete Flee waypoints
2018-03-25 16:52:48 +02:00
delete _scores ;
_scores = nullptr ;
2015-05-02 12:01:47 +02:00
2018-03-27 18:43:27 +02:00
delete _endCredits ;
_endCredits = nullptr ;
2018-02-10 20:34:28 +01:00
delete _elevator ;
_elevator = nullptr ;
2015-05-02 12:01:47 +02:00
2017-08-24 23:43:47 +02:00
delete _spinner ;
_spinner = nullptr ;
2015-05-02 12:01:47 +02:00
2018-01-14 12:12:06 +01:00
delete _kia ;
_kia = nullptr ;
2015-05-02 12:01:47 +02:00
2016-10-08 21:06:22 +02:00
delete _suspectsDatabase ;
_suspectsDatabase = nullptr ;
2015-05-02 12:01:47 +02:00
2016-10-08 21:06:22 +02:00
// TODO: Delete datetime - not used
2015-05-02 12:01:47 +02:00
2016-10-28 22:34:04 +02:00
int actorCount = ( int ) _gameInfo - > getActorCount ( ) ;
for ( int i = 0 ; i ! = actorCount ; + + i ) {
delete _actors [ i ] ;
_actors [ i ] = nullptr ;
}
2018-01-14 12:12:06 +01:00
delete _actors [ kActorVoiceOver ] ;
_actors [ kActorVoiceOver ] = nullptr ;
2017-03-23 00:25:38 +01:00
2016-10-28 22:34:04 +02:00
_playerActor = nullptr ;
2015-05-02 12:01:47 +02:00
delete _gameInfo ;
2016-10-02 02:47:12 +02:00
_gameInfo = nullptr ;
2015-05-02 12:01:47 +02:00
// TODO: Delete graphics surfaces here
2017-07-30 22:34:21 +02:00
_surface4 . free ( ) ;
2018-01-14 12:12:06 +01:00
_surfaceBack . free ( ) ;
_surfaceFront . free ( ) ;
2015-05-02 12:01:47 +02:00
2017-09-10 20:19:02 +02:00
if ( isArchiveOpen ( " STARTUP.MIX " ) ) {
2014-05-16 21:58:49 +02:00
closeArchive ( " STARTUP.MIX " ) ;
2017-09-10 20:19:02 +02:00
}
2015-05-02 12:01:47 +02:00
// TODO: Delete MIXArchives here
2018-12-15 22:40:07 +01:00
delete _time ;
_time = nullptr ;
2018-01-14 12:12:06 +01:00
// These are static objects in original game
2018-02-25 19:31:52 +01:00
delete _debugger ;
_debugger = nullptr ;
2018-01-14 12:12:06 +01:00
delete _zbuffer ;
_zbuffer = nullptr ;
delete _itemPickup ;
_itemPickup = nullptr ;
2018-03-23 18:47:04 +01:00
delete _policeMaze ;
_policeMaze = nullptr ;
2018-01-14 12:12:06 +01:00
delete _obstacles ;
_obstacles = nullptr ;
delete _actorDialogueQueue ;
_actorDialogueQueue = nullptr ;
delete _combat ;
_combat = nullptr ;
delete _screenEffects ;
_screenEffects = nullptr ;
delete _lights ;
_lights = nullptr ;
delete _settings ;
_settings = nullptr ;
delete _sceneScript ;
_sceneScript = nullptr ;
2014-05-16 21:58:49 +02:00
}
2015-05-02 12:01:47 +02:00
bool BladeRunnerEngine : : loadSplash ( ) {
2014-05-16 21:58:49 +02:00
Image img ( this ) ;
2017-09-10 20:19:02 +02:00
if ( ! img . open ( " SPLASH.IMG " ) ) {
2015-05-02 12:01:47 +02:00
return false ;
2017-09-10 20:19:02 +02:00
}
2014-05-16 21:58:49 +02:00
2018-01-14 12:12:06 +01:00
img . copyToSurface ( & _surfaceFront ) ;
2014-05-16 21:58:49 +02:00
2018-01-14 12:12:06 +01:00
blitToScreen ( _surfaceFront ) ;
2015-05-02 12:01:47 +02:00
2016-10-22 18:30:46 +02:00
return true ;
2014-05-16 21:58:49 +02:00
}
2018-01-14 12:12:06 +01:00
Common : : Point BladeRunnerEngine : : getMousePos ( ) const {
2018-01-29 21:48:48 +01:00
Common : : Point p = _eventMan - > getMousePos ( ) ;
p . x = CLIP ( p . x , int16 ( 0 ) , int16 ( 639 ) ) ;
p . y = CLIP ( p . y , int16 ( 0 ) , int16 ( 479 ) ) ;
return p ;
2017-07-31 00:11:00 +02:00
}
2018-02-10 20:34:28 +01:00
bool BladeRunnerEngine : : isMouseButtonDown ( ) const {
return _eventMan - > getButtonState ( ) ! = 0 ;
}
2014-05-16 21:58:49 +02:00
void BladeRunnerEngine : : gameLoop ( ) {
_gameIsRunning = true ;
do {
/* TODO: check player death */
gameTick ( ) ;
2016-09-10 18:16:17 +02:00
} while ( _gameIsRunning ) ;
2014-05-16 21:58:49 +02:00
}
void BladeRunnerEngine : : gameTick ( ) {
handleEvents ( ) ;
if ( _gameIsRunning & & _windowIsActive ) {
2018-11-25 21:47:00 +01:00
if ( ! _kia - > isOpen ( ) & & ! _sceneScript - > isInsideScript ( ) & & ! _aiScripts - > isInsideScript ( ) ) {
2017-08-24 23:43:47 +02:00
_settings - > openNewScene ( ) ;
}
2014-05-16 21:58:49 +02:00
// TODO: Autosave
2017-08-24 23:43:47 +02:00
//probably not needed, this version of tick is just loading data from buffer
//_audioMixer->tick();
2018-01-31 00:37:19 +01:00
if ( _kia - > isOpen ( ) ) {
2018-01-14 12:12:06 +01:00
_kia - > tick ( ) ;
return ;
}
2017-07-31 00:11:00 +02:00
if ( _spinner - > isOpen ( ) ) {
_spinner - > tick ( ) ;
_ambientSounds - > tick ( ) ;
return ;
}
2018-01-31 00:37:19 +01:00
if ( _esper - > isOpen ( ) ) {
_esper - > tick ( ) ;
return ;
}
2018-02-10 20:34:28 +01:00
if ( _vk - > isOpen ( ) ) {
_vk - > tick ( ) ;
_ambientSounds - > tick ( ) ;
return ;
}
2017-08-24 22:34:40 +02:00
if ( _elevator - > isOpen ( ) ) {
_elevator - > tick ( ) ;
_ambientSounds - > tick ( ) ;
return ;
}
2018-03-25 16:52:48 +02:00
if ( _scores - > isOpen ( ) ) {
_scores - > tick ( ) ;
_ambientSounds - > tick ( ) ;
return ;
}
2016-10-03 11:24:13 +02:00
2018-01-14 12:12:06 +01:00
_actorDialogueQueue - > tick ( ) ;
2016-09-10 18:16:17 +02:00
if ( _scene - > didPlayerWalkIn ( ) ) {
2018-02-10 20:34:28 +01:00
_sceneScript - > playerWalkedIn ( ) ;
2016-09-10 18:16:17 +02:00
}
2017-08-22 18:57:50 +02:00
bool inDialogueMenu = _dialogueMenu - > isVisible ( ) ;
2018-03-17 16:40:33 +01:00
if ( ! inDialogueMenu ) {
for ( int i = 0 ; i < ( int ) _gameInfo - > getActorCount ( ) ; + + i ) {
_actors [ i ] - > tickCombat ( ) ;
}
2017-08-22 18:57:50 +02:00
}
2017-03-28 17:50:04 +02:00
2018-03-23 18:47:04 +01:00
_policeMaze - > tick ( ) ;
2017-08-22 18:57:50 +02:00
// TODO: Gun range announcements
2017-03-28 17:50:04 +02:00
_zbuffer - > clean ( ) ;
2015-02-06 15:31:43 +01:00
_ambientSounds - > tick ( ) ;
2014-05-16 21:58:49 +02:00
2014-05-25 15:01:06 +02:00
bool backgroundChanged = false ;
2017-07-30 22:34:21 +02:00
int frame = _scene - > advanceFrame ( ) ;
2014-05-25 15:01:06 +02:00
if ( frame > = 0 ) {
2018-02-10 20:34:28 +01:00
_sceneScript - > sceneFrameAdvanced ( frame ) ;
2014-05-25 15:01:06 +02:00
backgroundChanged = true ;
}
2015-02-06 15:31:43 +01:00
( void ) backgroundChanged ;
2018-01-14 12:12:06 +01:00
blit ( _surfaceBack , _surfaceFront ) ;
2017-08-27 22:39:36 +02:00
_overlays - > tick ( ) ;
2014-05-16 21:58:49 +02:00
2017-08-22 18:57:50 +02:00
if ( ! inDialogueMenu ) {
2017-03-20 22:55:31 +01:00
actorsUpdate ( ) ;
2017-08-22 18:57:50 +02:00
}
2017-03-20 22:55:31 +01:00
2018-02-10 20:34:28 +01:00
if ( _settings - > getNewScene ( ) = = - 1 | | _sceneScript - > isInsideScript ( ) | | _aiScripts - > isInsideScript ( ) ) {
2018-02-12 20:53:13 +01:00
_sliceRenderer - > setView ( _view ) ;
2014-06-05 23:49:57 +02:00
2016-09-10 18:16:17 +02:00
// Tick and draw all actors in current set
2017-03-20 22:55:31 +01:00
int setId = _scene - > getSetId ( ) ;
2016-09-10 18:16:17 +02:00
for ( int i = 0 , end = _gameInfo - > getActorCount ( ) ; i ! = end ; + + i ) {
2017-03-20 22:55:31 +01:00
if ( _actors [ i ] - > getSetId ( ) = = setId ) {
2018-02-25 19:31:52 +01:00
Common : : Rect screenRect ;
if ( _actors [ i ] - > tick ( backgroundChanged , & screenRect ) ) {
_zbuffer - > mark ( screenRect ) ;
2017-03-20 22:55:31 +01:00
}
2016-09-12 00:54:40 +02:00
}
2016-09-10 18:16:17 +02:00
}
2014-06-05 23:49:57 +02:00
2016-10-02 00:20:56 +02:00
_items - > tick ( ) ;
2016-10-03 11:24:13 +02:00
2016-10-08 21:06:22 +02:00
_itemPickup - > tick ( ) ;
_itemPickup - > draw ( ) ;
2017-07-31 00:11:00 +02:00
Common : : Point p = getMousePos ( ) ;
2017-08-22 18:57:50 +02:00
if ( _dialogueMenu - > isVisible ( ) ) {
_dialogueMenu - > tick ( p . x , p . y ) ;
2018-01-14 12:12:06 +01:00
_dialogueMenu - > draw ( _surfaceFront ) ;
2017-08-22 18:57:50 +02:00
}
2018-02-25 19:31:52 +01:00
if ( _debugger - > _viewZBuffer ) {
_surfaceFront . copyRectToSurface ( _zbuffer - > getData ( ) , 1280 , 0 , 0 , 640 , 480 ) ;
}
2018-02-19 22:04:44 +01:00
2015-09-15 20:26:46 +02:00
_mouse - > tick ( p . x , p . y ) ;
2018-01-14 12:12:06 +01:00
_mouse - > draw ( _surfaceFront , p . x , p . y ) ;
2015-05-01 09:43:04 +02:00
2016-09-10 18:16:17 +02:00
// TODO: Process AUD
2014-05-16 21:58:49 +02:00
2016-10-03 12:38:43 +02:00
if ( _walkSoundId > = 0 ) {
2018-03-24 17:20:27 +01:00
_audioPlayer - > playAud ( _gameInfo - > getSfxTrack ( _walkSoundId ) , _walkSoundVolume , _walkSoundBalance , _walkSoundBalance , 50 , 0 ) ;
2016-09-20 00:33:06 +02:00
_walkSoundId = - 1 ;
}
2018-02-25 19:31:52 +01:00
if ( _debugger - > _viewSceneObjects ) {
_debugger - > drawSceneObjects ( ) ;
2017-04-02 18:17:43 +02:00
}
2018-05-07 19:17:13 +02:00
if ( _debugger - > _viewObstacles ) {
_obstacles - > draw ( ) ;
}
2018-06-18 14:10:00 +03:00
# if SUBTITLES_SUPPORT
_subtitles - > tick ( _surfaceFront ) ;
# endif // SUBTITLES_SUPPORT
2018-01-14 12:12:06 +01:00
blitToScreen ( _surfaceFront ) ;
2014-05-25 15:01:06 +02:00
_system - > delayMillis ( 10 ) ;
2014-05-16 21:58:49 +02:00
}
}
}
2017-03-20 22:55:31 +01:00
void BladeRunnerEngine : : actorsUpdate ( ) {
int actorCount = ( int ) _gameInfo - > getActorCount ( ) ;
int setId = _scene - > getSetId ( ) ;
2018-02-13 23:08:37 +01:00
if ( setId ! = kSetUG18 | | _gameVars [ kVariableChapter ] ! = 4 | | ! _gameFlags - > query ( 670 ) | | ! _aiScripts - > isInsideScript ( ) ) {
2017-03-20 22:55:31 +01:00
for ( int i = 0 ; i < actorCount ; i + + ) {
Actor * actor = _actors [ i ] ;
2018-02-25 19:31:52 +01:00
if ( actor - > getSetId ( ) = = setId | | i = = _actorUpdateCounter ) {
2018-02-10 20:34:28 +01:00
_aiScripts - > update ( i ) ;
2018-02-18 22:18:41 +01:00
actor - > timersUpdate ( ) ;
2017-03-20 22:55:31 +01:00
}
}
2018-02-25 19:31:52 +01:00
+ + _actorUpdateCounter ;
if ( _actorUpdateCounter > = actorCount ) {
_actorUpdateCounter = 0 ;
}
2017-03-20 22:55:31 +01:00
}
}
2018-02-18 22:18:41 +01:00
void BladeRunnerEngine : : walkingReset ( ) {
_mouseClickTimeLast = 0 ;
_mouseClickTimeDiff = 0 ;
_walkingToExitId = - 1 ;
_isInsideScriptExit = false ;
_walkingToRegionId = - 1 ;
_isInsideScriptRegion = false ;
_walkingToObjectId = - 1 ;
_isInsideScriptObject = false ;
_walkingToItemId = - 1 ;
_isInsideScriptItem = false ;
_walkingToEmpty = false ;
_walkingToEmptyX = 0 ;
_walkingToEmptyY = 0 ;
_isInsideScriptEmpty = false ;
_walkingToActorId = - 1 ;
_isInsideScriptActor = false ;
}
2014-05-16 21:58:49 +02:00
void BladeRunnerEngine : : handleEvents ( ) {
2016-09-10 18:16:17 +02:00
if ( shouldQuit ( ) ) {
_gameIsRunning = false ;
return ;
}
2014-05-16 21:58:49 +02:00
Common : : Event event ;
Common : : EventManager * eventMan = _system - > getEventManager ( ) ;
while ( eventMan - > pollEvent ( event ) ) {
2016-09-10 18:16:17 +02:00
switch ( event . type ) {
2017-08-24 23:43:47 +02:00
case Common : : EVENT_KEYUP :
handleKeyUp ( event ) ;
break ;
case Common : : EVENT_KEYDOWN :
handleKeyDown ( event ) ;
break ;
case Common : : EVENT_LBUTTONUP :
handleMouseAction ( event . mouse . x , event . mouse . y , true , false ) ;
break ;
case Common : : EVENT_RBUTTONUP :
case Common : : EVENT_MBUTTONUP :
handleMouseAction ( event . mouse . x , event . mouse . y , false , false ) ;
break ;
2016-10-03 12:38:43 +02:00
case Common : : EVENT_LBUTTONDOWN :
2017-08-24 23:43:47 +02:00
handleMouseAction ( event . mouse . x , event . mouse . y , true , true ) ;
break ;
2016-10-03 12:38:43 +02:00
case Common : : EVENT_RBUTTONDOWN :
2017-08-24 23:43:47 +02:00
case Common : : EVENT_MBUTTONDOWN :
handleMouseAction ( event . mouse . x , event . mouse . y , false , true ) ;
break ;
2016-10-03 12:38:43 +02:00
default :
2017-08-24 23:43:47 +02:00
; // nothing to do
2016-09-10 18:16:17 +02:00
}
2014-05-16 21:58:49 +02:00
}
}
2017-08-24 23:43:47 +02:00
void BladeRunnerEngine : : handleKeyUp ( Common : : Event & event ) {
if ( event . kbd . keycode = = Common : : KEYCODE_RETURN ) {
_speechSkipped = true ;
}
2018-01-14 12:12:06 +01:00
2018-03-27 23:43:38 +02:00
if ( _vqaIsPlaying ) {
_vqaStopIsRequested = true ;
_vqaIsPlaying = false ;
return ;
}
2018-01-31 00:37:19 +01:00
// TODO:
2018-01-14 12:12:06 +01:00
if ( ! playerHasControl ( ) /*|| ActorInWalkingLoop*/ ) {
return ;
}
2018-01-31 00:37:19 +01:00
if ( _kia - > isOpen ( ) ) {
2018-01-14 12:12:06 +01:00
_kia - > handleKeyUp ( event . kbd ) ;
return ;
}
2018-01-31 00:37:19 +01:00
if ( _spinner - > isOpen ( ) ) {
return ;
}
if ( _elevator - > isOpen ( ) ) {
return ;
}
if ( _esper - > isOpen ( ) ) {
return ;
}
2018-02-10 20:34:28 +01:00
if ( _vk - > isOpen ( ) ) {
return ;
}
2018-01-31 00:37:19 +01:00
if ( _dialogueMenu - > isOpen ( ) ) {
return ;
}
2018-03-25 16:52:48 +02:00
if ( _scores - > isOpen ( ) ) {
return ;
}
2018-01-31 00:37:19 +01:00
switch ( event . kbd . keycode ) {
case Common : : KEYCODE_TAB :
_kia - > openLastOpened ( ) ;
break ;
case Common : : KEYCODE_ESCAPE :
_kia - > open ( kKIASectionSettings ) ;
break ;
case Common : : KEYCODE_SPACE :
// TODO: combat::switchCombatMode(&Combat);
break ;
default :
break ;
2018-01-14 12:12:06 +01:00
}
2017-08-24 23:43:47 +02:00
}
void BladeRunnerEngine : : handleKeyDown ( Common : : Event & event ) {
2018-02-25 19:31:52 +01:00
if ( ( event . kbd . keycode = = Common : : KEYCODE_d ) & & ( event . kbd . flags & Common : : KBD_CTRL ) ) {
getDebugger ( ) - > attach ( ) ;
getDebugger ( ) - > onFrame ( ) ;
return ;
}
2018-01-31 00:37:19 +01:00
//TODO:
2018-02-10 20:34:28 +01:00
if ( ! playerHasControl ( ) /* || ActorWalkingLoop || ActorSpeaking || VqaIsPlaying */ ) {
2018-01-31 00:37:19 +01:00
return ;
}
if ( _kia - > isOpen ( ) ) {
2018-01-14 12:12:06 +01:00
_kia - > handleKeyDown ( event . kbd ) ;
2018-12-05 18:18:13 +01:00
return ;
2018-01-14 12:12:06 +01:00
}
2018-01-31 00:37:19 +01:00
if ( _spinner - > isOpen ( ) ) {
return ;
}
if ( _elevator - > isOpen ( ) ) {
return ;
}
if ( _esper - > isOpen ( ) ) {
return ;
}
if ( _dialogueMenu - > isOpen ( ) ) {
return ;
}
2018-03-25 16:52:48 +02:00
if ( _scores - > isOpen ( ) ) {
2018-03-26 00:38:58 +02:00
_scores - > handleKeyDown ( event . kbd ) ;
2018-03-25 16:52:48 +02:00
return ;
}
2018-01-31 00:37:19 +01:00
switch ( event . kbd . keycode ) {
case Common : : KEYCODE_F1 :
_kia - > open ( kKIASectionHelp ) ;
break ;
case Common : : KEYCODE_F2 :
_kia - > open ( kKIASectionSave ) ;
break ;
case Common : : KEYCODE_F3 :
_kia - > open ( kKIASectionLoad ) ;
break ;
case Common : : KEYCODE_F4 :
_kia - > open ( kKIASectionCrimes ) ;
break ;
case Common : : KEYCODE_F5 :
_kia - > open ( kKIASectionSuspects ) ;
break ;
case Common : : KEYCODE_F6 :
_kia - > open ( kKIASectionClues ) ;
break ;
case Common : : KEYCODE_F10 :
_kia - > open ( kKIASectionQuit ) ;
break ;
default :
break ;
}
2017-08-24 23:43:47 +02:00
}
2018-02-18 22:18:41 +01:00
void BladeRunnerEngine : : handleMouseAction ( int x , int y , bool mainButton , bool buttonDown ) {
2018-03-06 00:07:42 +01:00
x = CLIP ( x , 0 , 639 ) ;
y = CLIP ( y , 0 , 479 ) ;
2018-12-15 22:40:07 +01:00
int timeNow = _time - > current ( ) ;
2018-02-18 22:18:41 +01:00
if ( buttonDown ) {
_mouseClickTimeDiff = timeNow - _mouseClickTimeLast ;
_mouseClickTimeLast = timeNow ;
}
2018-01-14 12:12:06 +01:00
if ( ! playerHasControl ( ) | | _mouse - > isDisabled ( ) ) {
2016-09-10 18:16:17 +02:00
return ;
2018-01-14 12:12:06 +01:00
}
2018-01-31 00:37:19 +01:00
if ( _kia - > isOpen ( ) ) {
2018-01-14 12:12:06 +01:00
if ( buttonDown ) {
2018-02-18 22:18:41 +01:00
_kia - > handleMouseDown ( x , y , mainButton ) ;
2018-01-14 12:12:06 +01:00
} else {
2018-02-18 22:18:41 +01:00
_kia - > handleMouseUp ( x , y , mainButton ) ;
2018-01-14 12:12:06 +01:00
}
return ;
}
2016-09-10 18:16:17 +02:00
2017-07-31 00:11:00 +02:00
if ( _spinner - > isOpen ( ) ) {
if ( buttonDown ) {
_spinner - > handleMouseDown ( x , y ) ;
} else {
_spinner - > handleMouseUp ( x , y ) ;
2018-01-31 00:37:19 +01:00
}
return ;
}
if ( _esper - > isOpen ( ) ) {
if ( buttonDown ) {
2018-02-18 22:18:41 +01:00
_esper - > handleMouseDown ( x , y , mainButton ) ;
2018-01-31 00:37:19 +01:00
} else {
2018-02-18 22:18:41 +01:00
_esper - > handleMouseUp ( x , y , mainButton ) ;
2017-07-31 00:11:00 +02:00
}
return ;
}
2018-02-10 20:34:28 +01:00
if ( _vk - > isOpen ( ) ) {
if ( buttonDown ) {
2018-02-18 22:18:41 +01:00
_vk - > handleMouseDown ( x , y , mainButton ) ;
2018-02-10 20:34:28 +01:00
} else {
2018-02-18 22:18:41 +01:00
_vk - > handleMouseUp ( x , y , mainButton ) ;
2018-02-10 20:34:28 +01:00
}
return ;
}
2017-08-24 22:34:40 +02:00
if ( _elevator - > isOpen ( ) ) {
if ( buttonDown ) {
_elevator - > handleMouseDown ( x , y ) ;
} else {
_elevator - > handleMouseUp ( x , y ) ;
}
return ;
}
2018-03-26 00:09:01 +02:00
if ( _scores - > isOpen ( ) ) {
if ( buttonDown ) {
_scores - > handleMouseDown ( x , y ) ;
} else {
_scores - > handleMouseUp ( x , y ) ;
}
return ;
}
2017-08-22 18:57:50 +02:00
if ( _dialogueMenu - > waitingForInput ( ) ) {
2018-02-18 22:18:41 +01:00
if ( mainButton & & ! buttonDown ) {
2017-08-22 18:57:50 +02:00
_dialogueMenu - > mouseUp ( ) ;
}
return ;
}
2018-02-18 22:18:41 +01:00
if ( mainButton ) {
2017-09-10 20:19:02 +02:00
Vector3 scenePosition = _mouse - > getXYZ ( x , y ) ;
2016-09-10 18:16:17 +02:00
2018-02-05 18:46:09 +01:00
bool isClickable ;
bool isObstacle ;
bool isTarget ;
2016-09-10 18:16:17 +02:00
2018-02-18 22:18:41 +01:00
int sceneObjectId = _sceneObjects - > findByXYZ ( & isClickable , & isObstacle , & isTarget , scenePosition , true , false , true ) ;
2017-08-24 23:43:47 +02:00
int exitIndex = _scene - > _exits - > getRegionAtXY ( x , y ) ;
2018-02-18 22:18:41 +01:00
int regionIndex = _scene - > _regions - > getRegionAtXY ( x , y ) ;
2016-09-10 18:16:17 +02:00
2018-05-06 11:19:38 +02:00
if ( ( sceneObjectId < kSceneObjectOffsetActors | | sceneObjectId > = kSceneObjectOffsetItems ) & & exitIndex > = 0 ) {
2018-02-18 22:18:41 +01:00
handleMouseClickExit ( exitIndex , x , y , buttonDown ) ;
} else if ( regionIndex > = 0 ) {
handleMouseClickRegion ( regionIndex , x , y , buttonDown ) ;
} else if ( sceneObjectId = = - 1 ) {
handleMouseClickEmpty ( x , y , scenePosition , buttonDown ) ;
} else if ( sceneObjectId > = kSceneObjectOffsetActors & & sceneObjectId < kSceneObjectOffsetItems ) {
handleMouseClickActor ( sceneObjectId - kSceneObjectOffsetActors , mainButton , buttonDown , scenePosition , x , y ) ;
} else if ( sceneObjectId > = kSceneObjectOffsetItems & & sceneObjectId < kSceneObjectOffsetObjects ) {
handleMouseClickItem ( sceneObjectId - kSceneObjectOffsetItems , buttonDown ) ;
} else if ( sceneObjectId > = kSceneObjectOffsetObjects & & sceneObjectId < = 293 ) {
handleMouseClick3DObject ( sceneObjectId - kSceneObjectOffsetObjects , buttonDown , isClickable , isTarget ) ;
2017-08-24 23:43:47 +02:00
}
2018-02-18 22:18:41 +01:00
} else if ( buttonDown ) {
if ( _playerActor - > inWalkLoop ( ) ) {
_playerActor - > stopWalking ( false ) ;
2017-08-24 23:43:47 +02:00
}
2018-02-18 22:18:41 +01:00
_combat - > change ( ) ;
}
}
2016-09-10 18:16:17 +02:00
2018-02-18 22:18:41 +01:00
void BladeRunnerEngine : : handleMouseClickExit ( int exitId , int x , int y , bool buttonDown ) {
debug ( " clicked on exit %d %d %d " , exitId , x , y ) ;
if ( _isWalkingInterruptible & & exitId ! = _walkingToExitId ) {
_isWalkingInterruptible = false ;
_interruptWalking = true ;
walkingReset ( ) ;
_walkingToExitId = exitId ;
return ;
2016-09-10 18:16:17 +02:00
}
2018-02-18 22:18:41 +01:00
if ( buttonDown ) {
return ;
2017-09-10 20:19:02 +02:00
}
2018-02-18 22:18:41 +01:00
if ( _isInsideScriptExit & & exitId = = _walkingToExitId ) {
_playerActor - > run ( ) ;
if ( _mouseClickTimeDiff < = 10000 ) {
_playerActor - > increaseFPS ( ) ;
}
} else {
_walkingToExitId = exitId ;
_walkingToRegionId = - 1 ;
_walkingToObjectId = - 1 ;
_walkingToItemId = - 1 ;
_walkingToEmpty = false ;
_walkingToActorId = - 1 ;
_isInsideScriptExit = true ;
_sceneScript - > clickedOnExit ( exitId ) ;
_isInsideScriptExit = false ;
}
2016-09-10 18:33:04 +02:00
}
2018-02-18 22:18:41 +01:00
void BladeRunnerEngine : : handleMouseClickRegion ( int regionId , int x , int y , bool buttonDown ) {
debug ( " clicked on region %d %d %d " , regionId , x , y ) ;
if ( _isWalkingInterruptible & & regionId ! = _walkingToRegionId ) {
_isWalkingInterruptible = false ;
_interruptWalking = true ;
walkingReset ( ) ;
_walkingToRegionId = regionId ;
return ;
}
2016-09-10 18:33:04 +02:00
2018-02-18 22:18:41 +01:00
if ( buttonDown | | _mouse - > isInactive ( ) ) {
return ;
}
if ( _isInsideScriptRegion & & regionId = = _walkingToRegionId ) {
_playerActor - > run ( ) ;
if ( _mouseClickTimeDiff < = 10000 ) {
_playerActor - > increaseFPS ( ) ;
}
} else {
_walkingToExitId = - 1 ;
_walkingToRegionId = regionId ;
_walkingToObjectId = - 1 ;
_walkingToItemId = - 1 ;
_walkingToEmpty = false ;
_walkingToActorId = - 1 ;
_isInsideScriptRegion = true ;
_sceneScript - > clickedOn2DRegion ( regionId ) ;
_isInsideScriptRegion = false ;
}
2016-09-10 18:33:04 +02:00
}
2018-02-18 22:18:41 +01:00
void BladeRunnerEngine : : handleMouseClick3DObject ( int objectId , bool buttonDown , bool isClickable , bool isTarget ) {
2018-03-24 17:20:27 +01:00
const Common : : String & objectName = _scene - > objectGetName ( objectId ) ;
debug ( " Clicked on object %s " , objectName . c_str ( ) ) ;
2018-02-18 22:18:41 +01:00
if ( _isWalkingInterruptible & & objectId ! = _walkingToObjectId ) {
_isWalkingInterruptible = false ;
_interruptWalking = true ;
walkingReset ( ) ;
_walkingToObjectId = objectId ;
return ;
}
if ( _mouse - > isInactive ( ) ) {
return ;
}
if ( ! _combat - > isActive ( ) ) {
if ( buttonDown | | ! isClickable ) {
return ;
}
if ( _isInsideScriptObject & & objectId = = _walkingToObjectId ) {
_playerActor - > run ( ) ;
if ( _mouseClickTimeDiff < = 10000 ) {
_playerActor - > increaseFPS ( ) ;
}
} else {
_walkingToExitId = - 1 ;
_walkingToRegionId = - 1 ;
_walkingToObjectId = objectId ;
_walkingToItemId = - 1 ;
_walkingToEmpty = false ;
_walkingToActorId = - 1 ;
_isInsideScriptObject = true ;
2018-03-24 17:20:27 +01:00
_sceneScript - > clickedOn3DObject ( objectName . c_str ( ) , false ) ;
2018-02-18 22:18:41 +01:00
_isInsideScriptObject = false ;
}
} else {
if ( ! buttonDown | | ! isTarget ) {
return ;
}
_playerActor - > stopWalking ( false ) ;
_playerActor - > faceObject ( objectName , false ) ;
2018-03-17 16:40:33 +01:00
_playerActor - > changeAnimationMode ( kAnimationModeCombatAttack , false ) ;
2018-02-18 22:18:41 +01:00
_settings - > decreaseAmmo ( ) ;
_audioPlayer - > playAud ( _gameInfo - > getSfxTrack ( _combat - > getHitSound ( ) ) , 100 , 0 , 0 , 90 , 0 ) ;
2018-03-25 03:02:56 +02:00
_mouse - > setMouseJitterUp ( ) ;
2018-02-18 22:18:41 +01:00
_isInsideScriptObject = true ;
2018-03-24 17:20:27 +01:00
_sceneScript - > clickedOn3DObject ( objectName . c_str ( ) , true ) ;
2018-02-18 22:18:41 +01:00
_isInsideScriptObject = false ;
}
2016-09-10 18:33:04 +02:00
}
2018-02-18 22:18:41 +01:00
void BladeRunnerEngine : : handleMouseClickEmpty ( int x , int y , Vector3 & scenePosition , bool buttonDown ) {
debug ( " Clicked on nothing %f, %f, %f " , scenePosition . x , scenePosition . y , scenePosition . z ) ;
if ( _isWalkingInterruptible ) {
_isWalkingInterruptible = false ;
_interruptWalking = true ;
walkingReset ( ) ;
_walkingToEmpty = false ;
return ;
}
_isInsideScriptEmpty = true ;
2018-02-10 20:34:28 +01:00
bool sceneMouseClick = _sceneScript - > mouseClick ( x , y ) ;
2018-02-18 22:18:41 +01:00
_isInsideScriptEmpty = false ;
2017-09-10 20:19:02 +02:00
if ( sceneMouseClick ) {
return ;
}
2018-02-18 22:18:41 +01:00
int actorId = Actor : : findTargetUnderMouse ( this , x , y ) ;
int itemId = _items - > findTargetUnderMouse ( x , y ) ;
2018-02-19 22:04:44 +01:00
if ( _combat - > isActive ( ) & & buttonDown & & ( actorId > 0 | | itemId > 0 ) ) {
2018-02-18 22:18:41 +01:00
_playerActor - > stopWalking ( false ) ;
if ( actorId > 0 ) {
_playerActor - > faceActor ( actorId , false ) ;
} else {
_playerActor - > faceItem ( itemId , false ) ;
}
2018-03-17 16:40:33 +01:00
_playerActor - > changeAnimationMode ( kAnimationModeCombatAttack , false ) ;
2018-02-18 22:18:41 +01:00
_settings - > decreaseAmmo ( ) ;
_audioPlayer - > playAud ( _gameInfo - > getSfxTrack ( _combat - > getMissSound ( ) ) , 100 , 0 , 0 , 90 , 0 ) ;
2018-03-25 03:02:56 +02:00
_mouse - > setMouseJitterUp ( ) ;
2018-02-18 22:18:41 +01:00
2018-02-25 19:31:52 +01:00
if ( actorId > 0 ) {
2018-02-18 22:18:41 +01:00
_aiScripts - > shotAtAndMissed ( actorId ) ;
}
} else {
if ( buttonDown ) {
return ;
}
_walkingToExitId = - 1 ;
_walkingToRegionId = - 1 ;
_walkingToObjectId = - 1 ;
_walkingToItemId = - 1 ;
_walkingToEmpty = true ;
_walkingToActorId = - 1 ;
if ( _combat - > isActive ( ) & & ( actorId > 0 | | itemId > 0 ) ) {
return ;
}
int xDist = abs ( _walkingToEmptyX - x ) ;
int yDist = abs ( _walkingToEmptyY - y ) ;
_walkingToEmptyX = x ;
_walkingToEmptyY = y ;
bool inWalkbox = false ;
float altitude = _scene - > _set - > getAltitudeAtXZ ( scenePosition . x , scenePosition . z , & inWalkbox ) ;
if ( ! inWalkbox | | scenePosition . y > = altitude + 6.0f ) {
return ;
}
2018-02-18 22:44:28 +01:00
bool shouldRun = _playerActor - > isRunning ( ) ;
2018-02-18 22:18:41 +01:00
if ( _mouseClickTimeDiff < = 10000 & & xDist < 10 & & yDist < 10 ) {
2018-02-18 22:44:28 +01:00
shouldRun = true ;
2018-02-18 22:18:41 +01:00
}
2018-02-18 22:44:28 +01:00
_playerActor - > walkTo ( shouldRun , scenePosition , false ) ;
2018-02-18 22:18:41 +01:00
2018-02-18 22:44:28 +01:00
if ( shouldRun & & _playerActor - > isWalking ( ) ) {
2018-02-18 22:18:41 +01:00
_playerActor - > increaseFPS ( ) ;
}
}
2017-09-10 20:19:02 +02:00
}
2018-02-18 22:18:41 +01:00
void BladeRunnerEngine : : handleMouseClickItem ( int itemId , bool buttonDown ) {
2016-09-10 18:33:04 +02:00
debug ( " Clicked on item %d " , itemId ) ;
2018-02-18 22:18:41 +01:00
if ( _isWalkingInterruptible & & itemId ! = _walkingToItemId ) {
_isWalkingInterruptible = false ;
_interruptWalking = true ;
walkingReset ( ) ;
_walkingToItemId = itemId ;
return ;
}
if ( _mouse - > isInactive ( ) ) {
return ;
}
if ( ! _combat - > isActive ( ) ) {
if ( buttonDown ) {
return ;
}
if ( _isInsideScriptItem & & itemId = = _walkingToItemId ) {
_playerActor - > run ( ) ;
if ( _mouseClickTimeDiff < = 10000 ) {
_playerActor - > increaseFPS ( ) ;
}
} else {
_walkingToExitId = - 1 ;
_walkingToRegionId = - 1 ;
_walkingToObjectId = - 1 ;
_walkingToItemId = itemId ;
_walkingToEmpty = false ;
_walkingToActorId = - 1 ;
_isInsideScriptItem = true ;
_sceneScript - > clickedOnItem ( itemId , false ) ;
_isInsideScriptItem = false ;
}
} else {
if ( ! buttonDown | | ! _items - > isTarget ( itemId ) /* || _mouse->isRandomized() */ ) {
return ;
}
_playerActor - > stopWalking ( false ) ;
_playerActor - > faceItem ( itemId , false ) ;
2018-03-17 16:40:33 +01:00
_playerActor - > changeAnimationMode ( kAnimationModeCombatAttack , false ) ;
2018-02-18 22:18:41 +01:00
_settings - > decreaseAmmo ( ) ;
_audioPlayer - > playAud ( _gameInfo - > getSfxTrack ( _combat - > getHitSound ( ) ) , 100 , 0 , 0 , 90 , 0 ) ;
2018-03-25 03:02:56 +02:00
_mouse - > setMouseJitterUp ( ) ;
2018-02-18 22:18:41 +01:00
_isInsideScriptItem = true ;
_sceneScript - > clickedOnItem ( itemId , true ) ;
_isInsideScriptItem = false ;
}
2016-09-10 18:33:04 +02:00
}
2016-09-10 18:16:17 +02:00
2018-02-18 22:18:41 +01:00
void BladeRunnerEngine : : handleMouseClickActor ( int actorId , bool mainButton , bool buttonDown , Vector3 & scenePosition , int x , int y ) {
2016-09-10 18:33:04 +02:00
debug ( " Clicked on actor %d " , actorId ) ;
2018-02-18 22:18:41 +01:00
if ( _isWalkingInterruptible & & actorId ! = _walkingToActorId ) {
_isWalkingInterruptible = false ;
_interruptWalking = true ;
walkingReset ( ) ;
_walkingToActorId = actorId ;
return ;
}
if ( _mouse - > isInactive ( ) ) {
return ;
}
if ( ! buttonDown ) {
if ( actorId = = kActorMcCoy ) {
if ( mainButton ) {
if ( ! _combat - > isActive ( ) ) {
_kia - > openLastOpened ( ) ;
}
} else if ( ! _playerActor - > inWalkLoop ( ) ) {
_combat - > change ( ) ;
}
return ;
}
if ( _isInsideScriptActor & & actorId = = _walkingToActorId ) {
_playerActor - > run ( ) ;
if ( _mouseClickTimeDiff < = 10000 ) {
_playerActor - > increaseFPS ( ) ;
}
} else {
_walkingToExitId = - 1 ;
_walkingToRegionId = - 1 ;
_walkingToObjectId = - 1 ;
_walkingToItemId = - 1 ;
_walkingToEmpty = false ;
_walkingToActorId = actorId ;
_isInsideScriptActor = true ;
bool processedBySceneScript = _sceneScript - > clickedOnActor ( actorId ) ;
_isInsideScriptActor = false ;
if ( ! _combat - > isActive ( ) & & ! processedBySceneScript ) {
_aiScripts - > clickedByPlayer ( actorId ) ;
}
}
} else {
2018-03-17 16:40:33 +01:00
Actor * actor = _actors [ actorId ] ;
if ( ! _combat - > isActive ( ) | | actorId = = kActorMcCoy | | ! actor - > isTarget ( ) | | actor - > isRetired ( ) /*|| _mouse->isRandomized()*/ ) {
2018-02-18 22:18:41 +01:00
return ;
}
_playerActor - > stopWalking ( false ) ;
_playerActor - > faceActor ( actorId , false ) ;
2018-03-17 16:40:33 +01:00
_playerActor - > changeAnimationMode ( kAnimationModeCombatAttack , false ) ;
2018-02-18 22:18:41 +01:00
_settings - > decreaseAmmo ( ) ;
2018-03-17 16:40:33 +01:00
bool missed = _playerActor - > isObstacleBetween ( actor - > getXYZ ( ) ) ;
2018-02-18 22:18:41 +01:00
_audioPlayer - > playAud ( _gameInfo - > getSfxTrack ( missed ? _combat - > getMissSound ( ) : _combat - > getHitSound ( ) ) , 100 , 0 , 0 , 90 , 0 ) ;
2018-03-25 03:02:56 +02:00
_mouse - > setMouseJitterUp ( ) ;
2018-02-18 22:18:41 +01:00
if ( missed ) {
_aiScripts - > shotAtAndMissed ( actorId ) ;
} else {
_isInsideScriptActor = true ;
bool canShoot = _aiScripts - > shotAtAndHit ( actorId ) ;
_isInsideScriptActor = false ;
if ( ! canShoot ) {
_combat - > shoot ( actorId , scenePosition , x ) ;
}
}
2017-09-10 20:19:02 +02:00
}
2016-09-10 18:16:17 +02:00
}
2015-09-19 01:43:38 +02:00
void BladeRunnerEngine : : gameWaitForActive ( ) {
2016-10-12 23:00:33 +02:00
while ( ! _windowIsActive ) {
2015-09-19 01:43:38 +02:00
handleEvents ( ) ;
}
}
2015-02-10 19:33:35 +01:00
void BladeRunnerEngine : : loopActorSpeaking ( ) {
2017-08-24 23:43:47 +02:00
if ( ! _audioSpeech - > isPlaying ( ) ) {
2015-02-10 19:33:35 +01:00
return ;
2017-08-24 23:43:47 +02:00
}
2015-02-10 19:33:35 +01:00
2015-05-01 10:13:30 +02:00
playerLosesControl ( ) ;
2015-02-10 19:33:35 +01:00
do {
gameTick ( ) ;
2016-09-10 18:16:17 +02:00
} while ( _gameIsRunning & & _audioSpeech - > isPlaying ( ) ) ;
2015-02-10 19:33:35 +01:00
2015-05-01 10:13:30 +02:00
playerGainsControl ( ) ;
2015-02-10 19:33:35 +01:00
}
2014-05-17 17:13:49 +02:00
void BladeRunnerEngine : : outtakePlay ( int id , bool noLocalization , int container ) {
2014-05-16 21:58:49 +02:00
Common : : String name = _gameInfo - > getOuttake ( id ) ;
2014-05-17 17:13:49 +02:00
OuttakePlayer player ( this ) ;
2014-05-16 21:58:49 +02:00
2015-02-06 15:31:43 +01:00
player . play ( name , noLocalization , container ) ;
2014-05-16 21:58:49 +02:00
}
bool BladeRunnerEngine : : openArchive ( const Common : : String & name ) {
2018-01-28 11:14:29 +01:00
int i ;
2014-05-16 21:58:49 +02:00
// If archive is already open, return true
for ( i = 0 ; i ! = kArchiveCount ; + + i ) {
2018-01-14 12:12:06 +01:00
if ( _archives [ i ] . isOpen ( ) & & _archives [ i ] . getName ( ) = = name ) {
2014-05-16 21:58:49 +02:00
return true ;
2018-01-14 12:12:06 +01:00
}
2014-05-16 21:58:49 +02:00
}
// Find first available slot
for ( i = 0 ; i ! = kArchiveCount ; + + i ) {
2018-01-14 12:12:06 +01:00
if ( ! _archives [ i ] . isOpen ( ) ) {
2014-05-16 21:58:49 +02:00
break ;
2018-01-14 12:12:06 +01:00
}
2014-05-16 21:58:49 +02:00
}
if ( i = = kArchiveCount ) {
/* TODO: BLADE.EXE retires the least recently used
* archive when it runs out of slots . */
error ( " openArchive: No more archive slots " ) ;
}
_archives [ i ] . open ( name ) ;
return _archives [ i ] . isOpen ( ) ;
}
bool BladeRunnerEngine : : closeArchive ( const Common : : String & name ) {
2018-01-28 11:14:29 +01:00
for ( int i = 0 ; i ! = kArchiveCount ; + + i ) {
2016-10-12 23:00:33 +02:00
if ( _archives [ i ] . isOpen ( ) & & _archives [ i ] . getName ( ) = = name ) {
2014-05-16 21:58:49 +02:00
_archives [ i ] . close ( ) ;
return true ;
}
}
debug ( " closeArchive: Archive %s not open. " , name . c_str ( ) ) ;
return false ;
}
2018-01-14 12:12:06 +01:00
bool BladeRunnerEngine : : isArchiveOpen ( const Common : : String & name ) const {
2018-01-28 11:14:29 +01:00
for ( int i = 0 ; i ! = kArchiveCount ; + + i ) {
2016-10-12 23:00:33 +02:00
if ( _archives [ i ] . isOpen ( ) & & _archives [ i ] . getName ( ) = = name )
2014-05-16 21:58:49 +02:00
return true ;
}
return false ;
}
Common : : SeekableReadStream * BladeRunnerEngine : : getResourceStream ( const Common : : String & name ) {
2018-01-28 11:14:29 +01:00
for ( int i = 0 ; i ! = kArchiveCount ; + + i ) {
2017-09-10 20:19:02 +02:00
if ( ! _archives [ i ] . isOpen ( ) ) {
2014-05-16 21:58:49 +02:00
continue ;
2017-09-10 20:19:02 +02:00
}
2018-04-07 22:22:21 +02:00
2017-09-10 20:19:02 +02:00
if ( false ) {
2014-05-16 21:58:49 +02:00
debug ( " getResource: Searching archive %s for %s. " , _archives [ i ] . getName ( ) . c_str ( ) , name . c_str ( ) ) ;
2017-09-10 20:19:02 +02:00
}
2018-04-07 22:22:21 +02:00
2014-05-16 21:58:49 +02:00
Common : : SeekableReadStream * stream = _archives [ i ] . createReadStreamForMember ( name ) ;
2017-09-10 20:19:02 +02:00
if ( stream ) {
2014-05-16 21:58:49 +02:00
return stream ;
2017-09-10 20:19:02 +02:00
}
2014-05-16 21:58:49 +02:00
}
2018-03-06 00:07:42 +01:00
warning ( " getResource: Resource %s not found " , name . c_str ( ) ) ;
2017-08-24 23:43:47 +02:00
return nullptr ;
2014-05-16 21:58:49 +02:00
}
2015-05-01 10:13:30 +02:00
bool BladeRunnerEngine : : playerHasControl ( ) {
return _playerLosesControlCounter = = 0 ;
}
void BladeRunnerEngine : : playerLosesControl ( ) {
if ( + + _playerLosesControlCounter = = 1 ) {
_mouse - > disable ( ) ;
}
2016-09-10 18:16:17 +02:00
// debug("Player Lost Control (%d)", _playerLosesControlCounter);
2015-05-01 10:13:30 +02:00
}
void BladeRunnerEngine : : playerGainsControl ( ) {
if ( _playerLosesControlCounter = = 0 ) {
warning ( " Unbalanced call to BladeRunnerEngine::playerGainsControl " ) ;
}
if ( _playerLosesControlCounter > 0 )
- - _playerLosesControlCounter ;
2016-09-10 18:16:17 +02:00
// debug("Player Gained Control (%d)", _playerLosesControlCounter);
2015-05-01 10:13:30 +02:00
if ( _playerLosesControlCounter = = 0 ) {
_mouse - > enable ( ) ;
}
}
2018-11-25 21:47:00 +01:00
bool BladeRunnerEngine : : saveGame ( Common : : WriteStream & stream , const Graphics : : Surface & thumbnail ) {
2018-03-17 16:14:48 +01:00
if ( ! playerHasControl ( ) | | _sceneScript - > isInsideScript ( ) | | _aiScripts - > isInsideScript ( ) ) {
return false ;
}
2018-11-24 08:55:21 +01:00
Common : : MemoryWriteStreamDynamic memoryStream ( DisposeAfterUse : : YES ) ;
2018-11-21 23:16:15 +01:00
SaveFileWriteStream s ( memoryStream ) ;
2018-03-17 16:14:48 +01:00
2018-11-25 21:47:00 +01:00
s . write ( thumbnail . getPixels ( ) , SaveFileManager : : kThumbnailSize ) ;
2018-11-21 23:16:15 +01:00
s . writeFloat ( 1.0f ) ;
2018-03-17 16:14:48 +01:00
_settings - > save ( s ) ;
_scene - > save ( s ) ;
_scene - > _exits - > save ( s ) ;
_scene - > _regions - > save ( s ) ;
_scene - > _set - > save ( s ) ;
for ( uint i = 0 ; i ! = _gameInfo - > getGlobalVarCount ( ) ; + + i ) {
2018-03-24 17:20:27 +01:00
s . writeInt ( _gameVars [ i ] ) ;
2018-03-17 16:14:48 +01:00
}
2018-03-24 17:20:27 +01:00
_music - > save ( s ) ;
2018-03-17 16:14:48 +01:00
// _audioPlayer->save(s) // zero func
// _audioSpeech->save(s) // zero func
_combat - > save ( s ) ;
_gameFlags - > save ( s ) ;
_items - > save ( s ) ;
_sceneObjects - > save ( s ) ;
_ambientSounds - > save ( s ) ;
_overlays - > save ( s ) ;
_spinner - > save ( s ) ;
2018-03-25 16:52:48 +02:00
_scores - > save ( s ) ;
2018-03-17 16:14:48 +01:00
_dialogueMenu - > save ( s ) ;
_obstacles - > save ( s ) ;
_actorDialogueQueue - > save ( s ) ;
_waypoints - > save ( s ) ;
for ( uint i = 0 ; i ! = _gameInfo - > getActorCount ( ) ; + + i ) {
_actors [ i ] - > save ( s ) ;
2018-03-24 17:20:27 +01:00
int animationState , animationFrame , animationStateNext , nextAnimation ;
_aiScripts - > queryAnimationState ( i , & animationState , & animationFrame , & animationStateNext , & nextAnimation ) ;
s . writeInt ( animationState ) ;
s . writeInt ( animationFrame ) ;
s . writeInt ( animationStateNext ) ;
s . writeInt ( nextAnimation ) ;
2018-03-17 16:14:48 +01:00
}
_actors [ kActorVoiceOver ] - > save ( s ) ;
_policeMaze - > save ( s ) ;
_crimesDatabase - > save ( s ) ;
s . finalize ( ) ;
2018-11-21 23:16:15 +01:00
stream . writeUint32LE ( memoryStream . size ( ) + 4 ) ;
stream . write ( memoryStream . getData ( ) , memoryStream . size ( ) ) ;
stream . flush ( ) ;
2018-03-24 17:20:27 +01:00
2018-11-21 23:16:15 +01:00
return true ;
2018-03-17 16:14:48 +01:00
}
2018-11-21 23:16:15 +01:00
bool BladeRunnerEngine : : loadGame ( Common : : SeekableReadStream & stream ) {
2018-03-24 17:20:27 +01:00
if ( ! playerHasControl ( ) | | _sceneScript - > isInsideScript ( ) | | _aiScripts - > isInsideScript ( ) ) {
2018-11-21 23:16:15 +01:00
return false ;
2018-03-24 17:20:27 +01:00
}
2018-11-21 23:16:15 +01:00
SaveFileReadStream s ( stream ) ;
2018-03-24 17:20:27 +01:00
_ambientSounds - > removeAllNonLoopingSounds ( true ) ;
_ambientSounds - > removeAllLoopingSounds ( 1 ) ;
_music - > stop ( 2 ) ;
_audioSpeech - > stopSpeech ( ) ;
_actorDialogueQueue - > flush ( true , false ) ;
2018-11-21 23:16:15 +01:00
_screenEffects - > _entries . clear ( ) ;
2018-03-24 17:20:27 +01:00
int size = s . readInt ( ) ;
2018-11-21 23:16:15 +01:00
if ( size ! = s . size ( ) - s . pos ( ) + 4 ) {
_gameIsLoading = false ;
return false ;
2018-03-24 17:20:27 +01:00
}
2018-11-21 23:16:15 +01:00
_gameIsLoading = true ;
_settings - > setLoadingGame ( ) ;
2018-11-25 21:47:00 +01:00
s . skip ( SaveFileManager : : kThumbnailSize ) ; // skip the thumbnail
2018-11-21 23:16:15 +01:00
s . skip ( 4 ) ; // always float 1.0, but never used
2018-03-24 17:20:27 +01:00
_settings - > load ( s ) ;
_scene - > load ( s ) ;
_scene - > _exits - > load ( s ) ;
_scene - > _regions - > load ( s ) ;
_scene - > _set - > load ( s ) ;
for ( uint i = 0 ; i ! = _gameInfo - > getGlobalVarCount ( ) ; + + i ) {
_gameVars [ i ] = s . readInt ( ) ;
}
_music - > load ( s ) ;
// _audioPlayer->load(s) // zero func
// _audioSpeech->load(s) // zero func
_combat - > load ( s ) ;
_gameFlags - > load ( s ) ;
_items - > load ( s ) ;
_sceneObjects - > load ( s ) ;
_ambientSounds - > load ( s ) ;
_overlays - > load ( s ) ;
_spinner - > load ( s ) ;
2018-03-25 16:52:48 +02:00
_scores - > load ( s ) ;
2018-03-24 17:20:27 +01:00
_dialogueMenu - > load ( s ) ;
_obstacles - > load ( s ) ;
_actorDialogueQueue - > load ( s ) ;
_waypoints - > load ( s ) ;
for ( uint i = 0 ; i ! = _gameInfo - > getActorCount ( ) ; + + i ) {
_actors [ i ] - > load ( s ) ;
int animationState = s . readInt ( ) ;
int animationFrame = s . readInt ( ) ;
int animationStateNext = s . readInt ( ) ;
int nextAnimation = s . readInt ( ) ;
_aiScripts - > setAnimationState ( i , animationState , animationFrame , animationStateNext , nextAnimation ) ;
}
_actors [ kActorVoiceOver ] - > load ( s ) ;
_policeMaze - > load ( s ) ;
_crimesDatabase - > load ( s ) ;
2018-11-21 23:16:15 +01:00
_gameIsLoading = false ;
2018-03-24 17:20:27 +01:00
_settings - > setNewSetAndScene ( _settings - > getSet ( ) , _settings - > getScene ( ) ) ;
_settings - > setChapter ( _settings - > getChapter ( ) ) ;
2018-11-21 23:16:15 +01:00
return true ;
}
void BladeRunnerEngine : : newGame ( int difficulty ) {
_settings - > reset ( ) ;
_combat - > reset ( ) ;
for ( uint i = 0 ; i < _gameInfo - > getActorCount ( ) ; + + i ) {
_actors [ i ] - > setup ( i ) ;
}
_actors [ kActorVoiceOver ] - > setup ( 99 ) ;
for ( uint i = 0 ; i < _gameInfo - > getSuspectCount ( ) ; + + i ) {
_suspectsDatabase - > get ( i ) - > reset ( ) ;
}
_gameFlags - > clear ( ) ;
_gameInfo - > getGlobalVarCount ( ) ;
for ( uint i = 0 ; i < _gameInfo - > getGlobalVarCount ( ) ; + + i ) {
_gameVars [ i ] = 0 ;
}
_items - > reset ( ) ;
_scores - > reset ( ) ;
_kia - > reset ( ) ;
_dialogueMenu - > clear ( ) ;
_scene - > _exits - > enable ( ) ;
if ( difficulty > = 0 & & difficulty < 3 ) {
_settings - > setDifficulty ( difficulty ) ;
}
2018-11-25 21:47:00 +01:00
InitScript initScript ( this ) ;
initScript . SCRIPT_Initialize_Game ( ) ;
initChapterAndScene ( ) ;
2018-11-21 23:16:15 +01:00
_settings - > setStartingGame ( ) ;
2018-03-24 17:20:27 +01:00
}
void BladeRunnerEngine : : ISez ( const Common : : String & str ) {
debug ( " \t %s " , str . c_str ( ) ) ;
2014-05-25 19:56:03 +02:00
}
2018-11-21 23:16:15 +01:00
void BladeRunnerEngine : : blitToScreen ( const Graphics : : Surface & src ) const {
2017-08-04 21:40:09 +02:00
_system - > copyRectToScreen ( src . getPixels ( ) , src . pitch , 0 , 0 , src . w , src . h ) ;
_system - > updateScreen ( ) ;
}
2018-11-25 21:47:00 +01:00
Graphics : : Surface BladeRunnerEngine : : generateThumbnail ( ) const {
Graphics : : Surface thumbnail ;
thumbnail . create ( 640 / 8 , 480 / 8 , createRGB555 ( ) ) ;
for ( int y = 0 ; y < thumbnail . h ; + + y ) {
for ( int x = 0 ; x < thumbnail . w ; + + x ) {
uint16 * dstPixel = ( uint16 * ) thumbnail . getBasePtr ( x , y ) ;
const uint16 * srcPixel = ( const uint16 * ) _surfaceFront . getBasePtr ( x * 8 , y * 8 ) ;
2018-11-21 23:16:15 +01:00
2018-11-25 21:47:00 +01:00
* dstPixel = * srcPixel ;
2018-11-21 23:16:15 +01:00
}
}
2018-11-25 21:47:00 +01:00
return thumbnail ;
2018-11-21 23:16:15 +01:00
}
2018-02-25 19:31:52 +01:00
GUI : : Debugger * BladeRunnerEngine : : getDebugger ( ) {
return _debugger ;
}
2018-11-25 21:47:00 +01:00
Common : : String BladeRunnerEngine : : getTargetName ( ) const {
return _targetName ;
}
2017-08-04 21:40:09 +02:00
void blit ( const Graphics : : Surface & src , Graphics : : Surface & dst ) {
dst . copyRectToSurface ( src . getPixels ( ) , src . pitch , 0 , 0 , src . w , src . h ) ;
}
2014-05-16 21:58:49 +02:00
} // End of namespace BladeRunner