summaryrefslogtreecommitdiffstats
path: root/game/code/presentation
diff options
context:
space:
mode:
authorSvxy <aidan61605@gmail.com>2023-05-31 23:31:32 +0200
committerSvxy <aidan61605@gmail.com>2023-05-31 23:31:32 +0200
commiteb4b3404aa00220d659e532151dab13d642c17a3 (patch)
tree7e1107c4995489a26c4007e41b53ea8d00ab2134 /game/code/presentation
downloadThe-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar.gz
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar.bz2
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar.lz
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar.xz
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.tar.zst
The-Simpsons-Hit-and-Run-eb4b3404aa00220d659e532151dab13d642c17a3.zip
Diffstat (limited to 'game/code/presentation')
-rw-r--r--game/code/presentation/allpresentation.cpp12
-rw-r--r--game/code/presentation/animplayer.cpp356
-rw-r--r--game/code/presentation/animplayer.h135
-rw-r--r--game/code/presentation/blinker.cpp243
-rw-r--r--game/code/presentation/blinker.h68
-rw-r--r--game/code/presentation/cameraplayer.cpp111
-rw-r--r--game/code/presentation/cameraplayer.h55
-rw-r--r--game/code/presentation/fmvplayer/allfmvplayergc.cpp2
-rw-r--r--game/code/presentation/fmvplayer/allfmvplayerps2.cpp2
-rw-r--r--game/code/presentation/fmvplayer/fmvplayer.cpp526
-rw-r--r--game/code/presentation/fmvplayer/fmvplayer.h108
-rw-r--r--game/code/presentation/fmvplayer/fmvuserinputhandler.cpp257
-rw-r--r--game/code/presentation/fmvplayer/fmvuserinputhandler.h91
-rw-r--r--game/code/presentation/gui/allgui.cpp13
-rw-r--r--game/code/presentation/gui/backend/allbackend.cpp4
-rw-r--r--game/code/presentation/gui/backend/guiloadingbar.h61
-rw-r--r--game/code/presentation/gui/backend/guimanagerbackend.cpp296
-rw-r--r--game/code/presentation/gui/backend/guimanagerbackend.h69
-rw-r--r--game/code/presentation/gui/backend/guiscreendemo.cpp210
-rw-r--r--game/code/presentation/gui/backend/guiscreendemo.h52
-rw-r--r--game/code/presentation/gui/backend/guiscreenloading.cpp624
-rw-r--r--game/code/presentation/gui/backend/guiscreenloading.h84
-rw-r--r--game/code/presentation/gui/backend/guiscreenloadingfe.cpp566
-rw-r--r--game/code/presentation/gui/backend/guiscreenloadingfe.h79
-rw-r--r--game/code/presentation/gui/bootup/allbootup.cpp5
-rw-r--r--game/code/presentation/gui/bootup/guimanagerbootup.cpp403
-rw-r--r--game/code/presentation/gui/bootup/guimanagerbootup.h66
-rw-r--r--game/code/presentation/gui/bootup/guimanagerlanguage.cpp287
-rw-r--r--game/code/presentation/gui/bootup/guimanagerlanguage.h60
-rw-r--r--game/code/presentation/gui/bootup/guiscreenbootupload.cpp200
-rw-r--r--game/code/presentation/gui/bootup/guiscreenbootupload.h52
-rw-r--r--game/code/presentation/gui/bootup/guiscreenlanguage.cpp224
-rw-r--r--game/code/presentation/gui/bootup/guiscreenlanguage.h55
-rw-r--r--game/code/presentation/gui/bootup/guiscreenlicense.cpp202
-rw-r--r--game/code/presentation/gui/bootup/guiscreenlicense.h48
-rw-r--r--game/code/presentation/gui/frontend/allfrontend.cpp19
-rw-r--r--game/code/presentation/gui/frontend/guimanagerfrontend.cpp829
-rw-r--r--game/code/presentation/gui/frontend/guimanagerfrontend.h82
-rw-r--r--game/code/presentation/gui/frontend/guiscreencardgallery.cpp767
-rw-r--r--game/code/presentation/gui/frontend/guiscreencardgallery.h104
-rw-r--r--game/code/presentation/gui/frontend/guiscreencontroller.cpp401
-rw-r--r--game/code/presentation/gui/frontend/guiscreencontroller.h65
-rw-r--r--game/code/presentation/gui/frontend/guiscreencontrollerWin32.cpp1200
-rw-r--r--game/code/presentation/gui/frontend/guiscreencontrollerWin32.h163
-rw-r--r--game/code/presentation/gui/frontend/guiscreencontrollerWin32old.cpp867
-rw-r--r--game/code/presentation/gui/frontend/guiscreencontrollerWin32old.h147
-rw-r--r--game/code/presentation/gui/frontend/guiscreendisplay.cpp346
-rw-r--r--game/code/presentation/gui/frontend/guiscreendisplay.h68
-rw-r--r--game/code/presentation/gui/frontend/guiscreenloadgame.cpp1034
-rw-r--r--game/code/presentation/gui/frontend/guiscreenloadgame.h92
-rw-r--r--game/code/presentation/gui/frontend/guiscreenmainmenu.cpp1649
-rw-r--r--game/code/presentation/gui/frontend/guiscreenmainmenu.h157
-rw-r--r--game/code/presentation/gui/frontend/guiscreenmissiongallery.cpp860
-rw-r--r--game/code/presentation/gui/frontend/guiscreenmissiongallery.h108
-rw-r--r--game/code/presentation/gui/frontend/guiscreenmultichoosechar.cpp349
-rw-r--r--game/code/presentation/gui/frontend/guiscreenmultichoosechar.h62
-rw-r--r--game/code/presentation/gui/frontend/guiscreenmultisetup.cpp235
-rw-r--r--game/code/presentation/gui/frontend/guiscreenmultisetup.h58
-rw-r--r--game/code/presentation/gui/frontend/guiscreenoptions.cpp609
-rw-r--r--game/code/presentation/gui/frontend/guiscreenoptions.h82
-rw-r--r--game/code/presentation/gui/frontend/guiscreenplaymovie.cpp460
-rw-r--r--game/code/presentation/gui/frontend/guiscreenplaymovie.h70
-rw-r--r--game/code/presentation/gui/frontend/guiscreenscrapbook.cpp266
-rw-r--r--game/code/presentation/gui/frontend/guiscreenscrapbook.h64
-rw-r--r--game/code/presentation/gui/frontend/guiscreenscrapbookcontents.cpp674
-rw-r--r--game/code/presentation/gui/frontend/guiscreenscrapbookcontents.h97
-rw-r--r--game/code/presentation/gui/frontend/guiscreenscrapbookstats.cpp284
-rw-r--r--game/code/presentation/gui/frontend/guiscreenscrapbookstats.h67
-rw-r--r--game/code/presentation/gui/frontend/guiscreenskingallery.cpp785
-rw-r--r--game/code/presentation/gui/frontend/guiscreenskingallery.h100
-rw-r--r--game/code/presentation/gui/frontend/guiscreensound.cpp541
-rw-r--r--game/code/presentation/gui/frontend/guiscreensound.h94
-rw-r--r--game/code/presentation/gui/frontend/guiscreensplash.cpp344
-rw-r--r--game/code/presentation/gui/frontend/guiscreensplash.h73
-rw-r--r--game/code/presentation/gui/frontend/guiscreenvehiclegallery.cpp837
-rw-r--r--game/code/presentation/gui/frontend/guiscreenvehiclegallery.h100
-rw-r--r--game/code/presentation/gui/frontend/guiscreenviewcredits.cpp503
-rw-r--r--game/code/presentation/gui/frontend/guiscreenviewcredits.h74
-rw-r--r--game/code/presentation/gui/frontend/guiscreenviewmovies.cpp287
-rw-r--r--game/code/presentation/gui/frontend/guiscreenviewmovies.h53
-rw-r--r--game/code/presentation/gui/guientity.cpp61
-rw-r--r--game/code/presentation/gui/guientity.h184
-rw-r--r--game/code/presentation/gui/guimanager.cpp650
-rw-r--r--game/code/presentation/gui/guimanager.h207
-rw-r--r--game/code/presentation/gui/guimenu.cpp1367
-rw-r--r--game/code/presentation/gui/guimenu.h251
-rw-r--r--game/code/presentation/gui/guimenuitem.cpp318
-rw-r--r--game/code/presentation/gui/guimenuitem.h164
-rw-r--r--game/code/presentation/gui/guiscreen.cpp1314
-rw-r--r--game/code/presentation/gui/guiscreen.h234
-rw-r--r--game/code/presentation/gui/guiscreenmemcardcheck.cpp518
-rw-r--r--game/code/presentation/gui/guiscreenmemcardcheck.h74
-rw-r--r--game/code/presentation/gui/guiscreenmemorycard.cpp920
-rw-r--r--game/code/presentation/gui/guiscreenmemorycard.h206
-rw-r--r--game/code/presentation/gui/guiscreenmessage.cpp629
-rw-r--r--game/code/presentation/gui/guiscreenmessage.h114
-rw-r--r--game/code/presentation/gui/guiscreenprompt.cpp498
-rw-r--r--game/code/presentation/gui/guiscreenprompt.h166
-rw-r--r--game/code/presentation/gui/guisystem.cpp1845
-rw-r--r--game/code/presentation/gui/guisystem.h320
-rw-r--r--game/code/presentation/gui/guitextbible.cpp89
-rw-r--r--game/code/presentation/gui/guitextbible.h86
-rw-r--r--game/code/presentation/gui/guiuserinputhandler.cpp938
-rw-r--r--game/code/presentation/gui/guiuserinputhandler.h162
-rw-r--r--game/code/presentation/gui/guiwindow.cpp241
-rw-r--r--game/code/presentation/gui/guiwindow.h188
-rw-r--r--game/code/presentation/gui/ingame/allingame.cpp27
-rw-r--r--game/code/presentation/gui/ingame/guihudtextbox.h41
-rw-r--r--game/code/presentation/gui/ingame/guimanageringame.cpp1646
-rw-r--r--game/code/presentation/gui/ingame/guimanageringame.h231
-rw-r--r--game/code/presentation/gui/ingame/guiscreencreditspostfmv.cpp267
-rw-r--r--game/code/presentation/gui/ingame/guiscreencreditspostfmv.h54
-rw-r--r--game/code/presentation/gui/ingame/guiscreenhastransitions.cpp213
-rw-r--r--game/code/presentation/gui/ingame/guiscreenhastransitions.h54
-rw-r--r--game/code/presentation/gui/ingame/guiscreenhud.cpp2106
-rw-r--r--game/code/presentation/gui/ingame/guiscreenhud.h271
-rw-r--r--game/code/presentation/gui/ingame/guiscreenhudmap.cpp279
-rw-r--r--game/code/presentation/gui/ingame/guiscreenhudmap.h59
-rw-r--r--game/code/presentation/gui/ingame/guiscreeniriswipe.cpp366
-rw-r--r--game/code/presentation/gui/ingame/guiscreeniriswipe.h70
-rw-r--r--game/code/presentation/gui/ingame/guiscreenletterbox.cpp688
-rw-r--r--game/code/presentation/gui/ingame/guiscreenletterbox.h101
-rw-r--r--game/code/presentation/gui/ingame/guiscreenlevelend.cpp202
-rw-r--r--game/code/presentation/gui/ingame/guiscreenlevelend.h48
-rw-r--r--game/code/presentation/gui/ingame/guiscreenlevelstats.cpp270
-rw-r--r--game/code/presentation/gui/ingame/guiscreenlevelstats.h71
-rw-r--r--game/code/presentation/gui/ingame/guiscreenmissionbase.cpp1419
-rw-r--r--game/code/presentation/gui/ingame/guiscreenmissionbase.h132
-rw-r--r--game/code/presentation/gui/ingame/guiscreenmissionload.cpp511
-rw-r--r--game/code/presentation/gui/ingame/guiscreenmissionload.h73
-rw-r--r--game/code/presentation/gui/ingame/guiscreenmissionover.cpp450
-rw-r--r--game/code/presentation/gui/ingame/guiscreenmissionover.h72
-rw-r--r--game/code/presentation/gui/ingame/guiscreenmissionselect.cpp493
-rw-r--r--game/code/presentation/gui/ingame/guiscreenmissionselect.h83
-rw-r--r--game/code/presentation/gui/ingame/guiscreenmissionsuccess.cpp211
-rw-r--r--game/code/presentation/gui/ingame/guiscreenmissionsuccess.h47
-rw-r--r--game/code/presentation/gui/ingame/guiscreenmultihud.cpp825
-rw-r--r--game/code/presentation/gui/ingame/guiscreenmultihud.h91
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpause.cpp646
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpause.h83
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpausecontroller.cpp224
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpausecontroller.h52
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpausedisplay.cpp164
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpausedisplay.h44
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpausemission.cpp366
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpausemission.h50
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpauseoptions.cpp315
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpauseoptions.h59
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpausesettings.cpp557
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpausesettings.h81
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpausesound.cpp173
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpausesound.h48
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpausesunday.cpp331
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpausesunday.h50
-rw-r--r--game/code/presentation/gui/ingame/guiscreenphonebooth.cpp1104
-rw-r--r--game/code/presentation/gui/ingame/guiscreenphonebooth.h94
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpurchaserewards.cpp1078
-rw-r--r--game/code/presentation/gui/ingame/guiscreenpurchaserewards.h87
-rw-r--r--game/code/presentation/gui/ingame/guiscreenrewards.cpp854
-rw-r--r--game/code/presentation/gui/ingame/guiscreenrewards.h171
-rw-r--r--game/code/presentation/gui/ingame/guiscreensavegame.cpp1011
-rw-r--r--game/code/presentation/gui/ingame/guiscreensavegame.h72
-rw-r--r--game/code/presentation/gui/ingame/guiscreentutorial.cpp373
-rw-r--r--game/code/presentation/gui/ingame/guiscreentutorial.h58
-rw-r--r--game/code/presentation/gui/ingame/guiscreenviewcards.cpp213
-rw-r--r--game/code/presentation/gui/ingame/guiscreenviewcards.h52
-rw-r--r--game/code/presentation/gui/ingame/hudevents/allhudevents.cpp9
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudcardcollected.cpp429
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudcardcollected.h100
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudcoincollected.cpp324
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudcoincollected.h84
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudcountdown.cpp233
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudcountdown.h69
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudeventhandler.cpp77
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudeventhandler.h69
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudhitnrun.cpp297
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudhitnrun.h81
-rw-r--r--game/code/presentation/gui/ingame/hudevents/huditemdropped.cpp217
-rw-r--r--game/code/presentation/gui/ingame/hudevents/huditemdropped.h61
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudmissionobjective.cpp255
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudmissionobjective.h84
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudmissionprogress.cpp83
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudmissionprogress.h50
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudwaspdestroyed.cpp184
-rw-r--r--game/code/presentation/gui/ingame/hudevents/hudwaspdestroyed.h72
-rw-r--r--game/code/presentation/gui/minigame/allminigame.cpp5
-rw-r--r--game/code/presentation/gui/minigame/guimanagerminigame.cpp491
-rw-r--r--game/code/presentation/gui/minigame/guimanagerminigame.h71
-rw-r--r--game/code/presentation/gui/minigame/guiscreenminihud.cpp217
-rw-r--r--game/code/presentation/gui/minigame/guiscreenminihud.h52
-rw-r--r--game/code/presentation/gui/minigame/guiscreenminimenu.cpp1633
-rw-r--r--game/code/presentation/gui/minigame/guiscreenminimenu.h210
-rw-r--r--game/code/presentation/gui/minigame/guiscreenminipause.cpp297
-rw-r--r--game/code/presentation/gui/minigame/guiscreenminipause.h66
-rw-r--r--game/code/presentation/gui/minigame/guiscreenminisummary.cpp539
-rw-r--r--game/code/presentation/gui/minigame/guiscreenminisummary.h87
-rw-r--r--game/code/presentation/gui/utility/allutility.cpp8
-rw-r--r--game/code/presentation/gui/utility/colourutility.h63
-rw-r--r--game/code/presentation/gui/utility/hudmap.cpp1914
-rw-r--r--game/code/presentation/gui/utility/hudmap.h240
-rw-r--r--game/code/presentation/gui/utility/hudmapcam.cpp113
-rw-r--r--game/code/presentation/gui/utility/hudmapcam.h40
-rw-r--r--game/code/presentation/gui/utility/numerictext.cpp27
-rw-r--r--game/code/presentation/gui/utility/numerictext.h197
-rw-r--r--game/code/presentation/gui/utility/scrollingtext.cpp280
-rw-r--r--game/code/presentation/gui/utility/scrollingtext.h110
-rw-r--r--game/code/presentation/gui/utility/slider.cpp246
-rw-r--r--game/code/presentation/gui/utility/slider.h94
-rw-r--r--game/code/presentation/gui/utility/specialfx.cpp401
-rw-r--r--game/code/presentation/gui/utility/specialfx.h166
-rw-r--r--game/code/presentation/gui/utility/teletypetext.cpp318
-rw-r--r--game/code/presentation/gui/utility/teletypetext.h120
-rw-r--r--game/code/presentation/gui/utility/transitions.cpp2911
-rw-r--r--game/code/presentation/gui/utility/transitions.h592
-rw-r--r--game/code/presentation/language.cpp181
-rw-r--r--game/code/presentation/language.h43
-rw-r--r--game/code/presentation/mouthflapper.cpp565
-rw-r--r--game/code/presentation/mouthflapper.h107
-rw-r--r--game/code/presentation/nisplayer.cpp163
-rw-r--r--game/code/presentation/nisplayer.h59
-rw-r--r--game/code/presentation/playerdrawable.cpp90
-rw-r--r--game/code/presentation/playerdrawable.h58
-rw-r--r--game/code/presentation/presentation.cpp1466
-rw-r--r--game/code/presentation/presentation.h217
-rw-r--r--game/code/presentation/presentationanimator.cpp367
-rw-r--r--game/code/presentation/presentationanimator.h70
-rw-r--r--game/code/presentation/presevents/allpresevents.cpp4
-rw-r--r--game/code/presentation/presevents/fmvevent.cpp74
-rw-r--r--game/code/presentation/presevents/fmvevent.h62
-rw-r--r--game/code/presentation/presevents/nisevent.cpp229
-rw-r--r--game/code/presentation/presevents/nisevent.h66
-rw-r--r--game/code/presentation/presevents/presentationevent.cpp180
-rw-r--r--game/code/presentation/presevents/presentationevent.h107
-rw-r--r--game/code/presentation/presevents/transevent.cpp77
-rw-r--r--game/code/presentation/presevents/transevent.h44
-rw-r--r--game/code/presentation/simpleanimationplayer.cpp300
-rw-r--r--game/code/presentation/simpleanimationplayer.h89
-rw-r--r--game/code/presentation/transitionplayer.cpp161
-rw-r--r--game/code/presentation/transitionplayer.h82
-rw-r--r--game/code/presentation/tutorialmanager.cpp745
-rw-r--r--game/code/presentation/tutorialmanager.h127
-rw-r--r--game/code/presentation/tutorialmode.h61
242 files changed, 73457 insertions, 0 deletions
diff --git a/game/code/presentation/allpresentation.cpp b/game/code/presentation/allpresentation.cpp
new file mode 100644
index 0000000..94e3a71
--- /dev/null
+++ b/game/code/presentation/allpresentation.cpp
@@ -0,0 +1,12 @@
+#include <presentation/animplayer.cpp>
+#include <presentation/blinker.cpp>
+#include <presentation/cameraplayer.cpp>
+#include <presentation/language.cpp>
+#include <presentation/mouthflapper.cpp>
+#include <presentation/nisplayer.cpp>
+#include <presentation/playerdrawable.cpp>
+#include <presentation/presentation.cpp>
+#include <presentation/presentationanimator.cpp>
+#include <presentation/simpleanimationplayer.cpp>
+#include <presentation/transitionplayer.cpp>
+#include <presentation/tutorialmanager.cpp> \ No newline at end of file
diff --git a/game/code/presentation/animplayer.cpp b/game/code/presentation/animplayer.cpp
new file mode 100644
index 0000000..3c1e244
--- /dev/null
+++ b/game/code/presentation/animplayer.cpp
@@ -0,0 +1,356 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: animplayer.cpp
+//
+// Description: Implement AnimationPlayer
+//
+// History: 22/04/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+#include <p3d/utility.hpp>
+
+//========================================
+// Project Includes
+//========================================
+
+#include <memory/srrmemory.h>
+
+#include <presentation/animplayer.h>
+#include <interiors/interiormanager.h>
+#include <render/rendermanager/rendermanager.h>
+#include <render/RenderManager/RenderLayer.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// AnimationPlayer::AnimationPlayer
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+AnimationPlayer::AnimationPlayer() :
+ mState( ANIM_IDLE ),
+ mbPlayAfterLoad( true ),
+ mbExclusive( true ),
+ mbShowAlways ( false ),
+ mbKeepLayersFrozen( false ),
+ mbIsSkippable(true),
+ mpLoadDataCallback( NULL )
+{
+}
+
+//==============================================================================
+// AnimationPlayer::~AnimationPlayer
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+AnimationPlayer::~AnimationPlayer()
+{
+}
+
+
+//==============================================================================
+// AnimationPlayer::LoadData
+//==============================================================================
+//
+// Description:
+//
+// Parameters:
+//
+// Return:
+//
+//==============================================================================
+void AnimationPlayer::LoadData
+(
+ const char* fileName,
+ bool bInInventory,
+ void* pUserData
+)
+{
+ if( mState == ANIM_IDLE )
+ {
+ mState = ANIM_LOADING;
+
+ if( bInInventory )
+ {
+ OnProcessRequestsComplete( NULL );
+ mSection = 0;
+ }
+ else
+ {
+ if(!GetInteriorManager()->IsInside())
+ {
+ GetLoadingManager()->AddRequest( FILEHANDLER_ANIMATION,
+ fileName,
+ GMA_CHARS_AND_GAGS,
+ fileName,
+ "Animation Player",
+ this );
+ }
+ else
+ {
+ GetLoadingManager()->AddRequest( FILEHANDLER_ANIMATION,
+ fileName,
+ GMA_DEFAULT,
+ fileName,
+ "Animation Player",
+ this );
+ }
+
+ mSection = tEntity::MakeUID(fileName);
+ }
+ }
+}
+
+
+//=============================================================================
+// AnimationPlayer::LoadData
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( const char* fileName )
+//
+// Return: void
+//
+//=============================================================================
+void AnimationPlayer::LoadData
+(
+ const char* fileName,
+ LoadDataCallBack* pCallback,
+ bool bInInventory,
+ void* pUserData
+)
+{
+ mpLoadDataCallback = pCallback;
+
+ this->LoadData( fileName, bInInventory, pUserData );
+}
+
+//=============================================================================
+// AnimationPlayer::OnProcessRequestsComplete
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( void* pUserData )
+//
+// Return: void
+//
+//=============================================================================
+void AnimationPlayer::OnProcessRequestsComplete( void* pUserData )
+{
+ p3d::inventory->PushSection();
+
+ p3d::inventory->SelectSection( mSection );
+ bool currentOnly = p3d::inventory->GetCurrentSectionOnly( );
+ p3d::inventory->SetCurrentSectionOnly( true );
+
+ mState = ANIM_LOADED;
+
+ this->DoLoaded();
+
+ if( mpLoadDataCallback != NULL )
+ {
+ mpLoadDataCallback->OnLoadDataComplete();
+ }
+
+ if( mbPlayAfterLoad )
+ {
+ Play();
+ }
+
+ p3d::inventory->SetCurrentSectionOnly( currentOnly );
+
+ p3d::inventory->PopSection();
+}
+
+//=============================================================================
+// AnimationPlayer::Play
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void AnimationPlayer::Play()
+{
+ if( mState == ANIM_STOPPED )
+ {
+ mState = ANIM_PLAYING;
+ }
+
+ if( mState == ANIM_LOADED )
+ {
+ mState = ANIM_PLAYING;
+
+ if( mbExclusive )
+ {
+ EnterExclusive();
+ }
+ }
+/* DARWIN TODO: Why was this necessary?
+ else
+ {
+ mbPlayAfterLoad = true;
+ }
+*/
+}
+
+
+/*
+//=============================================================================
+// AnimationPlayer::StopAndCleanUp
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void AnimationPlayer::StopAndCleanUp()
+{
+ Stop();
+}
+*/
+
+
+//=============================================================================
+// AnimationPlayer::Render
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void AnimationPlayer::Render()
+{
+ if( (mState == ANIM_PLAYING) || mbShowAlways )
+ {
+ DoRender();
+ }
+}
+
+//=============================================================================
+// AnimationPlayer::Stop
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void AnimationPlayer::Stop()
+{
+ if( mbExclusive )
+ {
+ LeaveExclusive();
+ }
+
+ //
+ // Hope this makes sense. Calling Stop() after ClearData() was causing
+ // the player to be stuck in the stopped state, since LoadData() wouldn't
+ // do anything. Added check for idle state. -- DE
+ //
+ if( mState != ANIM_IDLE )
+ {
+ mState = ANIM_STOPPED;
+ }
+}
+
+//=============================================================================
+// AnimationPlayer::ClearData
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void AnimationPlayer::ClearData()
+{
+ mState = ANIM_IDLE;
+ p3d::inventory->DeleteSection( mSection );
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// AnimationPlayer::EnterExclusive
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void AnimationPlayer::EnterExclusive()
+{
+ GetRenderManager()->FreezeForPresentation();
+
+ RenderLayer* pLayer = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot );
+
+ if ( pLayer->IsDead() )
+ {
+ pLayer->Resurrect();
+ }
+ pLayer->Thaw();
+}
+
+//=============================================================================
+// AnimationPlayer::LeaveExclusive
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void AnimationPlayer::LeaveExclusive()
+{
+ if( !mbKeepLayersFrozen )
+ {
+ GetRenderManager()->ThawFromPresentation();
+
+ RenderLayer* pLayer = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot );
+
+ pLayer->Freeze();
+ }
+}
diff --git a/game/code/presentation/animplayer.h b/game/code/presentation/animplayer.h
new file mode 100644
index 0000000..f9d4088
--- /dev/null
+++ b/game/code/presentation/animplayer.h
@@ -0,0 +1,135 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: .h
+//
+// Description: Blahblahblah
+//
+// History: 22/04/2002 + Created -- NAME
+//
+//=============================================================================
+
+#ifndef ANIMPLAYER_H
+#define ANIMPLAYER_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <p3d/p3dtypes.hpp>
+#include <loading/loadingmanager.h>
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: Base class for all presentation players. A player is something
+// that keeps an non-interactive animation going.
+//
+//=============================================================================
+
+class AnimationPlayer : public LoadingManager::ProcessRequestsCallback
+{
+ public:
+ AnimationPlayer();
+ virtual ~AnimationPlayer();
+
+
+ // Loads the data for this animation and sits on it
+ // Set bInInventory to true if the data is already loaded and
+ // in the p3d inventory.
+ // Clients must implement the callback if they want notification when
+ // the load is complete.
+ struct LoadDataCallBack
+ {
+ virtual void OnLoadDataComplete() = 0;
+ };
+ virtual void LoadData( const char* fileName,
+ LoadDataCallBack* pCallback,
+ bool bInInventory,
+ void* pUserData );
+
+ virtual void LoadData( const char* fileName,
+ bool bInInventory,
+ void* pUserData );
+
+ // Tells it to start playing right away once it's done loading
+ void SetPlayAfterLoad( bool bPlay ) { mbPlayAfterLoad = bPlay; }
+
+ void SetShowAlways(bool b) { mbShowAlways = b; }
+
+ // Whee!
+ virtual void Play();
+ virtual void Stop();
+
+ // TC: This just calls Stop(), so why do we need another function??
+ //
+// void StopAndCleanUp();
+
+ // Tells the player to enter "Exclusive Mode", which sets the
+ // Render Level to Presentation and should stop everything else
+ // in the game.
+ void SetExclusive( bool bIsExclusive ) { mbExclusive = bIsExclusive; }
+
+ bool IsPlaying() { return((( mState != ANIM_IDLE ) && (mState != ANIM_STOPPED ))); }
+ bool IsFinished() { return mState == ANIM_STOPPED; }
+ virtual void Update( unsigned int elapsedTime ) = 0;
+ void Render();
+
+ virtual void ClearData();
+ void Reset() { mState = ANIM_IDLE; }
+
+ void OnProcessRequestsComplete( void* pUserData );
+ bool GetKeepLayersFrozen( void ) const { return mbKeepLayersFrozen; }
+ void SetKeepLayersFrozen( bool IsKeepFrozen ) { mbKeepLayersFrozen = IsKeepFrozen; }
+ bool GetSkippable(void) const {return mbIsSkippable;}
+ void SetSkippable(bool IsSkippable) {mbIsSkippable = IsSkippable;}
+
+ protected:
+
+ enum AnimState
+ {
+ ANIM_IDLE,
+ ANIM_LOADING,
+ ANIM_LOADED,
+ ANIM_PLAYING,
+ ANIM_STOPPED,
+ NUM_STATES
+ };
+
+ AnimState GetState() { return( mState ); }
+ void SetState( AnimState state ) { mState = state; }
+
+ // A sub-class must implement these
+ // DoLoaded is called once the data is ready (in the case on p3d
+ // stuff, this means it is in the inventory)
+ virtual void DoLoaded() = 0;
+
+ // A sub-class should draw stuff here
+ virtual void DoRender() = 0;
+
+ void EnterExclusive();
+ void LeaveExclusive();
+ private:
+
+ //Prevent wasteful constructor creation.
+ AnimationPlayer( const AnimationPlayer& animPlayer );
+ AnimationPlayer& operator=( const AnimationPlayer& animPlayer );
+
+ AnimState mState;
+
+ bool mbPlayAfterLoad : 1;
+ bool mbExclusive : 1;
+ bool mbShowAlways : 1;
+ bool mbKeepLayersFrozen : 1;
+ bool mbIsSkippable : 1;
+
+ tUID mSection;
+
+ LoadDataCallBack* mpLoadDataCallback;
+};
+
+
+#endif //ANIMPLAYER_H_H
+
diff --git a/game/code/presentation/blinker.cpp b/game/code/presentation/blinker.cpp
new file mode 100644
index 0000000..3ed4577
--- /dev/null
+++ b/game/code/presentation/blinker.cpp
@@ -0,0 +1,243 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: Blinker.cpp
+//
+// Description: Implement Blinker
+//
+// History: 9/24/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+#include <p3d/anim/multicontroller.hpp>
+#include <p3d/anim/textureanimation.hpp>
+#include <stdlib.h>
+
+//========================================
+// Project Includes
+//========================================
+
+#include <memory/srrmemory.h>
+#include <presentation/blinker.h>
+#include <worldsim/character/character.h>
+#include <worldsim/character/charactermanager.h>
+#include <main/game.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+static const int MIN_TIME = 2000;
+static const int MAX_TIME = 4000;
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// Blinker::Blinker
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+Blinker::Blinker():
+ mCharacter( NULL ),
+ mController( NULL ) ,
+ mState( STATE_BLINKING )
+{
+}
+
+//==============================================================================
+// Blinker::~Blinker
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+Blinker::~Blinker()
+{
+ if( mController != NULL )
+ {
+ mController->Release();
+ }
+}
+
+//=============================================================================
+// Blinker:SetCharacter
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( Character* pCharacter )
+//
+// Return: void
+//
+//=============================================================================
+void Blinker::SetCharacter( Character* pCharacter )
+{
+// if( mCharacter == pCharacter )
+// {
+// return;
+// }
+ mCharacter = pCharacter;
+
+ if (pCharacter == 0)
+ {
+ if (mController)
+ {
+ mController->Release ();
+ mController = 0;
+ }
+ }
+ else
+ {
+ const char* modelName = GetCharacterManager()->GetModelName( mCharacter );
+ tMultiController* multicontroller = 0;
+ if( tName::MakeUID( modelName ) != tName::MakeUID( "npd" ) )
+ {
+ multicontroller = p3d::find< tMultiController >( modelName );
+ }
+ tRefCounted::Assign( mController, multicontroller );
+ }
+
+ if( mController == NULL )
+ {
+ return;
+ }
+
+ mController->SetCycleMode( FORCE_NON_CYCLIC );
+}
+
+//=============================================================================
+// Blinker::Update
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( int elapsedTime )
+//
+// Return: void
+//
+//=============================================================================
+void Blinker::Update( int elapsedTime )
+{
+ mTimeSinceBlink += elapsedTime;
+
+ if( mController == NULL )
+ {
+ if( (mCharacter->GetActiveFrame() & 0xf) == (GetGame()->GetFrameCount() & 0xf))
+ {
+ mTimeSinceBlink = 0;
+ const char* modelName = GetCharacterManager()->GetModelName( mCharacter );
+ tMultiController* multicontroller = 0;
+ if(tName::MakeUID(modelName) != tName::MakeUID("npd"))
+ {
+ multicontroller = p3d::find< tMultiController >( modelName );
+ }
+ if( multicontroller != NULL )
+ {
+ tRefCounted::Assign( mController, multicontroller );
+ }
+ else
+ {
+ return;
+ }
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ switch( mState )
+ {
+ case STATE_WAITING:
+ {
+ rAssert( mController != NULL );
+ if( mTimeSinceBlink >= mTimeTarget )
+ {
+ mController->Reset();
+ mState = STATE_BLINKING;
+ }
+
+ break;
+ }
+ case STATE_BLINKING:
+ {
+ rAssert( mController != NULL );
+
+ mController->Advance( static_cast<float>( elapsedTime ), true );
+
+ float frames = mController->GetNumFrames();
+ float frame = mController->GetFrame();
+ if( frame >= frames )
+ {
+ mTimeTarget = MIN_TIME + (MAX_TIME - MIN_TIME) * rand() / RAND_MAX;
+ mTimeSinceBlink = 0;
+ mState = STATE_WAITING;
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+//=============================================================================
+// Blinker::StartBlinking
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void Blinker::StartBlinking()
+{
+ if( mState == STATE_INVALID )
+ {
+ mState = STATE_BLINKING;
+ }
+}
+
+//=============================================================================
+// Blinker::StopBlinking
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void Blinker::StopBlinking()
+{
+ if( mState != STATE_INVALID )
+ {
+ mState = STATE_INVALID;
+ }
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
diff --git a/game/code/presentation/blinker.h b/game/code/presentation/blinker.h
new file mode 100644
index 0000000..ecefb82
--- /dev/null
+++ b/game/code/presentation/blinker.h
@@ -0,0 +1,68 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: blinker.h
+//
+// Description: Blahblahblah
+//
+// History: 9/24/2002 + Created -- NAME
+//
+//=============================================================================
+
+#ifndef BLINKER_H
+#define BLINKER_H
+
+//========================================
+// Nested Includes
+//========================================
+
+//========================================
+// Forward References
+//========================================
+
+class Character;
+class tMultiController;
+
+//=============================================================================
+//
+// Synopsis: Blahblahblah
+//
+//=============================================================================
+
+class Blinker
+{
+public:
+ Blinker();
+ virtual ~Blinker();
+
+ void SetCharacter( Character* pCharacter );
+
+ void Update( int elapsedTime );
+
+ void StartBlinking();
+ void StopBlinking();
+
+private:
+
+ //Prevent wasteful constructor creation.
+ Blinker( const Blinker& blinker );
+ Blinker& operator=( const Blinker& blinker );
+
+ Character* mCharacter;
+ tMultiController* mController;
+
+ int mTimeSinceBlink;
+ int mTimeTarget;
+
+ enum BlinkState
+ {
+ STATE_INVALID,
+ STATE_WAITING,
+ STATE_BLINKING
+ };
+
+ BlinkState mState;
+};
+
+
+#endif //BLINKER_H
diff --git a/game/code/presentation/cameraplayer.cpp b/game/code/presentation/cameraplayer.cpp
new file mode 100644
index 0000000..7abf052
--- /dev/null
+++ b/game/code/presentation/cameraplayer.cpp
@@ -0,0 +1,111 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: cameraplayer.cpp
+//
+// Description: Implement CameraPlayer
+//
+// History: 22/04/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+#include <p3d/utility.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include <presentation/cameraplayer.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// CameraPlayer::CameraPlayer
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+CameraPlayer::CameraPlayer() :
+ mpAnimation( NULL )
+{
+ SetExclusive( false );
+}
+
+//==============================================================================
+// CameraPlayer::~CameraPlayer
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+CameraPlayer::~CameraPlayer()
+{
+}
+
+//=============================================================================
+// CameraPlayer::ClearData
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void CameraPlayer::ClearData()
+{
+ SimpleAnimationPlayer::ClearData();
+
+ if( mpAnimation != NULL )
+ {
+ mpAnimation->Release();
+ mpAnimation = NULL;
+ }
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// CameraPlayer::DoLoaded
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void CameraPlayer::DoLoaded()
+{
+ SimpleAnimationPlayer::DoLoaded();
+
+ mpAnimation = p3d::find<tAnimation>( GetAnimationName() );
+ rAssert( mpAnimation );
+ mpAnimation->AddRef();
+}
+
diff --git a/game/code/presentation/cameraplayer.h b/game/code/presentation/cameraplayer.h
new file mode 100644
index 0000000..24a8f82
--- /dev/null
+++ b/game/code/presentation/cameraplayer.h
@@ -0,0 +1,55 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: .h
+//
+// Description: Blahblahblah
+//
+// History: 22/04/2002 + Created -- NAME
+//
+//=============================================================================
+
+#ifndef CAMERAPLAYER_H
+#define CAMERAPLAYER_H
+
+//========================================
+// Nested Includes
+//========================================
+
+#include <presentation/simpleanimationplayer.h>
+
+//========================================
+// Forward References
+//========================================
+
+class tAnimation;
+
+//=============================================================================
+//
+// Synopsis: Blahblahblah
+//
+//=============================================================================
+
+class CameraPlayer : public SimpleAnimationPlayer
+{
+ public:
+ CameraPlayer();
+ virtual ~CameraPlayer();
+
+ virtual void ClearData();
+
+ protected:
+ virtual void DoLoaded();
+
+ private:
+
+ //Prevent wasteful constructor creation.
+ CameraPlayer( const CameraPlayer& cameraPlayer );
+ CameraPlayer& operator=( const CameraPlayer& cameraPlayer );
+
+ tAnimation* mpAnimation;
+};
+
+
+#endif //CAMERAPLAYER_H
+
diff --git a/game/code/presentation/fmvplayer/allfmvplayergc.cpp b/game/code/presentation/fmvplayer/allfmvplayergc.cpp
new file mode 100644
index 0000000..e753799
--- /dev/null
+++ b/game/code/presentation/fmvplayer/allfmvplayergc.cpp
@@ -0,0 +1,2 @@
+#include <presentation/fmvplayer/fmvplayer.cpp>
+#include <presentation/fmvplayer/fmvuserinputhandler.cpp>
diff --git a/game/code/presentation/fmvplayer/allfmvplayerps2.cpp b/game/code/presentation/fmvplayer/allfmvplayerps2.cpp
new file mode 100644
index 0000000..e753799
--- /dev/null
+++ b/game/code/presentation/fmvplayer/allfmvplayerps2.cpp
@@ -0,0 +1,2 @@
+#include <presentation/fmvplayer/fmvplayer.cpp>
+#include <presentation/fmvplayer/fmvuserinputhandler.cpp>
diff --git a/game/code/presentation/fmvplayer/fmvplayer.cpp b/game/code/presentation/fmvplayer/fmvplayer.cpp
new file mode 100644
index 0000000..4db5dc7
--- /dev/null
+++ b/game/code/presentation/fmvplayer/fmvplayer.cpp
@@ -0,0 +1,526 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: fmvplayer.cpp
+//
+// Description: Implement FMVPlayer
+//
+// History: 17/04/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+
+#include <radplatform.hpp>
+#include <radsound.hpp>
+#include <raddebug.hpp>
+#include <radmovie2.hpp>
+#include <radcontroller.hpp>
+#include <radfile.hpp>
+#include <radmemory.hpp>
+//========================================
+// Project Includes
+//========================================
+#include <main/game.h>
+#include <main/platform.h>
+#include <gameflow/gameflow.h>
+#include <presentation/fmvplayer/FMVplayer.h>
+#include <input/inputmanager.h>
+#include <sound/soundmanager.h>
+#include <memory/srrmemory.h>
+#include <contexts/bootupcontext.h>
+#include <presentation/fmvplayer/fmvplayer.h>
+#include <presentation/fmvplayer/fmvuserinputhandler.h>
+#include <presentation/presevents/fmvevent.h>
+#include <presentation/gui/guitextbible.h>
+#include <events/eventmanager.h>
+
+#include <render/RenderManager/RenderManager.h>
+#include <p3d/utility.hpp>
+#include <p3d/matrixstack.hpp>
+#include <p3d/context.hpp>
+#include <radmemory.hpp>
+#include <radmemorymonitor.hpp>
+#include <pddi/pddi.hpp>
+
+#include <string.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+#define MOVIE_MAX_WIDTH 640
+#ifdef PAL
+ #define MOVIE_MAX_HEIGHT 512
+#else
+ #define MOVIE_MAX_HEIGHT 480
+#endif
+#define MOVIE_ENCODED_VIDEO_BUFFER_SIZE ( 512 * 1024 )
+#define MOVIE_PRIMARY_AUDIO_BUFFER_SIZE 2000
+#define MOVIE_SECONDARY_AUDIO_BUFFER_SIZE 1000
+#define MOVIE_AUDIO_BUFFER_SIZE_TYPE IRadSoundHalAudioFormat::Milliseconds
+
+#ifdef RAD_XBOX
+static const float VOLUME_MULTIPLIER = 0.75f;
+#else
+static const float VOLUME_MULTIPLIER = 1.0f;
+#endif
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// FMVPlayer::FMVPlayer
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+FMVPlayer::FMVPlayer() :
+ m_refIRadMoviePlayer( NULL ),
+ mElapsedTime( 0.0f ),
+ mFadeOut(-1.0f)
+{
+ m_UserInputHandler = new FMVUserInputHandler;
+ m_UserInputHandler->AddRef();
+}
+
+//==============================================================================
+// FMVPlayer::~FMVPlayer
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+FMVPlayer::~FMVPlayer()
+{
+ m_UserInputHandler->Release();
+ m_UserInputHandler = NULL;
+
+ if( m_refIRadMoviePlayer != NULL )
+ {
+ m_refIRadMoviePlayer->Unload( );
+ m_refIRadMoviePlayer = NULL;
+ }
+}
+
+//=============================================================================
+// FMVPlayer::LoadData
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( const char* fileName, bool bInInventory )
+//
+// Return: void
+//
+//=============================================================================
+void FMVPlayer::LoadData( const char* fileName, bool bInInventory, void* pUserData )
+{
+ if( GetState() == ANIM_IDLE || GetState() == ANIM_LOADING )
+ {
+ GetSoundManager()->StopForMovie();
+ while( !( GetSoundManager()->IsStoppedForMovie() ) )
+ {
+ ::radMovieService2( );
+ ::radFileService( );
+ SoundManager::GetInstance()->Update();
+ SoundManager::GetInstance()->UpdateOncePerFrame( 0, NUM_CONTEXTS, false );
+ }
+
+ GameMemoryAllocator allocator = GMA_LEVEL_MOVIE;
+ unsigned int audioIndex = 0;
+ FMVEvent::FMVEventData* data = reinterpret_cast<FMVEvent::FMVEventData*>(pUserData);
+ if( data )
+ {
+ allocator = data->Allocator;
+
+ if ( allocator >= GMA_ANYWHERE_IN_LEVEL )
+ {
+ ::SetupAllocatorSearch( allocator );
+ allocator = GMA_ALLOCATOR_SEARCH;
+ }
+
+ audioIndex = data->AudioIndex;
+
+ if( data->KillMusic )
+ {
+ GetEventManager()->TriggerEvent( EVENT_STOP_THE_MUSIC );
+ }
+ }
+ HeapMgr()->PushHeap( allocator );
+ Initialize( allocator );
+ m_refIRadMoviePlayer->Load( fileName, audioIndex );
+ mDriveFinished = false;
+ Game::GetInstance()->GetPlatform()->GetHostDrive()->AddCompletionCallback( this, 0 );
+
+ while( !mDriveFinished )
+ {
+ ::radMovieService2( );
+ ::radFileService( );
+ SoundManager::GetInstance()->Update();
+ SoundManager::GetInstance()->UpdateOncePerFrame( 0, NUM_CONTEXTS, false );
+ }
+ HeapMgr()->PopHeap(allocator);
+ SetState( ANIM_LOADED );
+ }
+}
+
+//=============================================================================
+// FMVPlayer::Play
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void FMVPlayer::Play()
+{
+ if(( GetState() == ANIM_LOADED ) && ( m_refIRadMoviePlayer != NULL ))
+ {
+ AnimationPlayer::Play();
+ FadeScreen(0.0f);
+ p3d::context->SwapBuffers();
+ p3d::display->SetForceVSync(true);
+#ifdef FINAL
+ m_UserInputHandler->SetEnabled(GetSkippable());
+#endif
+ // register GUI user input handler for all controllers
+ for( unsigned i = 0; i < GetInputManager()->GetMaxControllers(); i++ )
+ {
+ GetInputManager()->RegisterMappable( i, m_UserInputHandler );
+ }
+ mElapsedTime = 0.0f;
+ mFadeOut = -1.0f;
+
+ mMovieVolume = VOLUME_MULTIPLIER;
+ if(GetGameFlow()->GetCurrentContext() != CONTEXT_BOOTUP)
+ {
+ mMovieVolume *= GetSoundManager()->GetDialogueVolume();
+ }
+
+ m_refIRadMoviePlayer->SetVolume(mMovieVolume);
+ m_refIRadMoviePlayer->Play( );
+ }
+}
+
+/*=============================================================================
+Causes the movie to begin fading out. When it's finished fading out it stops.
+Fade out time is hard coded right now to half a second.
+=============================================================================*/
+void FMVPlayer::Abort(void)
+{
+ if(mFadeOut == -1.0f)
+ {
+ mFadeOut = 1.0f;
+ }
+}
+
+//=============================================================================
+// FMVPlayer::Stop
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void FMVPlayer::Stop()
+{
+ // Force a clear screen.
+ FadeScreen(0.0f);
+ p3d::context->SwapBuffers();
+ p3d::display->SetForceVSync(false);
+ if( this->IsPlaying() && m_refIRadMoviePlayer != NULL )
+ {
+ for( unsigned i = 0; i < GetInputManager()->GetMaxControllers(); i++ )
+ {
+ GetInputManager()->UnregisterMappable( i, m_UserInputHandler );
+ }
+ m_UserInputHandler->SetEnabled(true);
+ GetSoundManager()->ResumeAfterMovie();
+ AnimationPlayer::Stop();
+
+ ClearData();
+ }
+ mFadeOut = -1.0f;
+}
+
+//=============================================================================
+// FMVPlayer::ForceStop
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+#ifdef RAD_WIN32
+void FMVPlayer::ForceStop()
+{
+ // Force a clear screen.
+ if( this->IsPlaying() && m_refIRadMoviePlayer != NULL )
+ {
+ for( unsigned i = 0; i < GetInputManager()->GetMaxControllers(); i++ )
+ {
+ GetInputManager()->UnregisterMappable( i, m_UserInputHandler );
+ }
+ m_UserInputHandler->SetEnabled(true);
+ GetSoundManager()->ResumeAfterMovie();
+ AnimationPlayer::Stop();
+
+ ClearData();
+ }
+}
+#endif
+
+//=============================================================================
+// FMVPlayer::Pause
+//=============================================================================
+void FMVPlayer::Pause()
+{
+ if( this->IsPlaying() && m_refIRadMoviePlayer != NULL )
+ {
+ m_refIRadMoviePlayer->Pause( );
+ }
+}
+
+//=============================================================================
+// FMVPlayer::UnPause
+//=============================================================================
+void FMVPlayer::UnPause()
+{
+ if( this->IsPlaying() && m_refIRadMoviePlayer != NULL )
+ {
+ m_refIRadMoviePlayer->Play( );
+ }
+}
+
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// FMVPlayer::Initialize
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void FMVPlayer::Initialize( radMemoryAllocator Allocator )
+{
+ //
+ // Initialize the movie player.
+ //
+ // This is where all the memory will be allocated.
+ //
+ ref< IRadMovieRenderLoop > refIRadMovieRenderLoop = this;
+ ref< IRadMovieRenderStrategy > refIRadMovieRenderStrategy =
+ ::radMovieSimpleFullScreenRenderStrategyCreate( Allocator );
+
+ // Note that there is a problem if we start creating multiple movie players
+ //(why would we ever do this???). The allocator is stored as a single global
+ //value in the movieplayer (binkmovieplayer.cpp for instance) and it is set
+ //when you call ::radMoviePlayerCreate2(). So if you make multiple calls
+ //the most recent allocator you pass is the one used.
+ m_refIRadMoviePlayer = ::radMoviePlayerCreate2( Allocator );
+ rAssert( m_refIRadMoviePlayer != NULL );
+
+#if defined(RAD_XBOX) || defined(RAD_GAMECUBE) || defined(RAD_WIN32)
+ m_refIRadMoviePlayer->Initialize(
+ refIRadMovieRenderLoop,
+ refIRadMovieRenderStrategy );
+#else // PS2
+ m_refIRadMoviePlayer->Initialize(
+ refIRadMovieRenderLoop,
+ refIRadMovieRenderStrategy,
+ MOVIE_MAX_WIDTH, MOVIE_MAX_HEIGHT,
+ MOVIE_ENCODED_VIDEO_BUFFER_SIZE,
+ MOVIE_PRIMARY_AUDIO_BUFFER_SIZE,
+ MOVIE_SECONDARY_AUDIO_BUFFER_SIZE,
+ MOVIE_AUDIO_BUFFER_SIZE_TYPE );
+#endif
+}
+
+//=============================================================================
+// FMVPlayer::DoRender
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void FMVPlayer::DoRender()
+{
+ IRadMoviePlayer2::State state = m_refIRadMoviePlayer->GetState( );
+
+ mFrameReady = false;
+
+ while( !mFrameReady && (state != IRadMoviePlayer2::NoData))
+ {
+ ::radMovieService2( );
+ ::radSoundHalSystemGet( )->Service( );
+// ::radSoundHalSystemGet( )->ServiceOncePerFrame( );
+ ::radFileService( );
+
+ state = m_refIRadMoviePlayer->GetState( );
+ if ( state == IRadMoviePlayer2::ReadyToPlay )
+ {
+ // [ps] Here we are paused, so fall out to the regular game.
+ break;
+ }
+ }
+
+ if((mFadeOut <= 0.0f) && (mFadeOut != -1.0f))
+ {
+ Stop();
+ }
+ if( (state == IRadMoviePlayer2::NoData) || ( m_refIRadMoviePlayer == NULL) )
+ {
+ Stop();
+ }
+}
+
+void FMVPlayer::IterateLoop( IRadMoviePlayer2* pIRadMoviePlayer )
+{
+ rAssert( pIRadMoviePlayer != NULL );
+
+ pIRadMoviePlayer->Render();
+ if(mFadeOut > 0.0f )
+ {
+ pIRadMoviePlayer->SetVolume(mMovieVolume * mFadeOut);
+ FadeScreen(mFadeOut);
+ }
+ float deltaTime = mElapsedTime;
+ mElapsedTime = pIRadMoviePlayer->GetCurrentFrameNumber() / pIRadMoviePlayer->GetFrameRate();
+ if(mFadeOut > 0.0f )
+ {
+ deltaTime = mElapsedTime - deltaTime;
+ mFadeOut -= deltaTime * 2.0f; // Half second fade.
+ }
+ mFrameReady = true;
+}
+
+//=============================================================================
+// FMVPlayer::Finalize
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void FMVPlayer::ClearData()
+{
+ //
+ // Free up the radmovie movie player stuff
+ //
+ if( m_refIRadMoviePlayer != NULL )
+ {
+ // I think there is a case where the movie player doesn't shut down properly because the
+ //decode buffer is still in use as a texture in the draw pipeline, preventing it from being
+ //freed.
+ p3d::pddi->DrawSync();
+ m_refIRadMoviePlayer->Unload( );
+ m_refIRadMoviePlayer = NULL;
+
+ mDriveFinished = false;
+ Game::GetInstance()->GetPlatform()->GetHostDrive()->AddCompletionCallback( this, 0 );
+
+ while( !mDriveFinished )
+ {
+ ::radMovieService2( );
+ ::radFileService( );
+ SoundManager::GetInstance()->Update();
+ SoundManager::GetInstance()->UpdateOncePerFrame( 0, NUM_CONTEXTS, false );
+ }
+ }
+
+ AnimationPlayer::ClearData();
+}
+
+void FMVPlayer::OnDriveOperationsComplete( void* pUserData )
+{
+ mDriveFinished = true;
+}
+
+void FMVPlayer::FadeScreen(float Alpha)
+{
+ tColour c;
+ c.Set( 0, 0, 0, int(0xFF * (1.0f - rmt::Clamp(Alpha, 0.0f, 1.0f))) );
+ p3d::stack->Push();
+ bool oldZWrite = p3d::pddi->GetZWrite();
+ pddiCompareMode oldZComp = p3d::pddi->GetZCompare();
+ if( oldZWrite )
+ {
+ p3d::pddi->SetZWrite( false );
+ }
+ if( oldZComp != PDDI_COMPARE_ALWAYS )
+ {
+ p3d::pddi->SetZCompare( PDDI_COMPARE_ALWAYS );
+ }
+ p3d::stack->LoadIdentity();
+ p3d::pddi->SetProjectionMode( PDDI_PROJECTION_ORTHOGRAPHIC );
+ pddiColour oldAmbient = p3d::pddi->GetAmbientLight();
+ p3d::pddi->SetAmbientLight( pddiColour( 255, 255, 255 ) );
+
+ pddiPrimStream* overlay = 0;
+
+ pddiShader* overlayShader = BootupContext::GetInstance()->GetSharedShader();
+ rAssert( overlayShader );
+
+ overlayShader->SetInt( PDDI_SP_BLENDMODE, PDDI_BLEND_ALPHA );
+ overlayShader->SetInt( PDDI_SP_ISLIT, 0 );
+ overlayShader->SetInt( PDDI_SP_SHADEMODE, PDDI_SHADE_FLAT );
+
+ overlay = p3d::pddi->BeginPrims( overlayShader, PDDI_PRIM_TRISTRIP, PDDI_V_C, 4 );
+
+ overlay->Colour( c );
+ overlay->Coord( 0.5f, -0.5f, 1.0f );
+ overlay->Colour( c );
+ overlay->Coord( -0.5f, -0.5f, 1.0f );
+ overlay->Colour( c );
+ overlay->Coord( 0.5f, 0.5f, 1.0f );
+ overlay->Colour( c );
+ overlay->Coord( -0.5f, 0.5f, 1.0f );
+
+ p3d::pddi->EndPrims( overlay );
+ p3d::pddi->SetProjectionMode(PDDI_PROJECTION_PERSPECTIVE);
+ p3d::pddi->SetAmbientLight( oldAmbient );
+ if( oldZWrite )
+ {
+ p3d::pddi->SetZWrite( true );
+ }
+ if( oldZComp != PDDI_COMPARE_ALWAYS )
+ {
+ p3d::pddi->SetZCompare( oldZComp );
+ }
+ p3d::stack->Pop();
+}
diff --git a/game/code/presentation/fmvplayer/fmvplayer.h b/game/code/presentation/fmvplayer/fmvplayer.h
new file mode 100644
index 0000000..663e091
--- /dev/null
+++ b/game/code/presentation/fmvplayer/fmvplayer.h
@@ -0,0 +1,108 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: .h
+//
+// Description: Blahblahblah
+//
+// History: 17/04/2002 + Created -- NAME
+//
+//=============================================================================
+
+#ifndef FMVPLAYER_H
+#define FMVPLAYER_H
+
+//========================================
+// Nested Includes
+//========================================
+
+#include <presentation/animplayer.h>
+#include <radmovie2.hpp>
+
+//========================================
+// Forward References
+//========================================
+
+class FMVUserInputHandler;
+
+//=============================================================================
+//
+// Synopsis: Blahblahblah
+//
+//=============================================================================
+
+class FMVPlayer : public AnimationPlayer,
+ public IRadMovieRenderLoop,
+ public IRadDriveCompletionCallback,
+ public radRefCount
+
+{
+ IMPLEMENT_REFCOUNTED( "FMVPlayer" )
+
+public:
+
+ FMVPlayer();
+ virtual ~FMVPlayer();
+
+ // playback control
+ virtual void Play();
+ virtual void Abort(void);
+ virtual void Stop();
+ virtual void Pause();
+ virtual void UnPause();
+
+#ifdef RAD_WIN32
+ void ForceStop();
+#endif
+
+ // loading
+ virtual void PreLoad(void) { SetState(ANIM_LOADING);}
+ virtual void LoadData( const char* fileName, bool bInInventory, void* pUserData );
+
+ // animation updating (doesn't need any)
+ virtual void Update( unsigned int elapsedTime ) {};
+
+ // IRadMovieRenderLoop interface, called by radMovie service eac time a frame is ready
+ void IterateLoop( IRadMoviePlayer2* pIRadMoviePlayer );
+
+ // reset all internal data
+ virtual void ClearData();
+
+ // How long the FMV has played in seconds. 0 if the movie hasn't played yet.
+ float GetElapsedTime() { return mElapsedTime; }
+
+ inline FMVUserInputHandler* GetUserInputHandler() const
+ {
+ return m_UserInputHandler;
+ }
+
+protected:
+ void Initialize( radMemoryAllocator Allocator );
+
+ // AnimationPlayer interface
+ virtual void DoLoaded() {}; // Movies aren't loader by main game loader, so don't need to handle this
+ virtual void DoRender(); // render a frame (if one is avilible)
+
+ // Implements IRadDriveCompletionCallback. We'll be called this when the movie finishes streaming.
+ //We need to wait for the drive to finish so the internal memory in radmovie is freed.
+ virtual void OnDriveOperationsComplete( void* pUserData );
+ void FadeScreen(float Alpha);
+
+private:
+ //Prevent wasteful constructor creation.
+ FMVPlayer( const FMVPlayer& fmvPlayer );
+ FMVPlayer& operator=( const FMVPlayer& fmvPlayer );
+
+ FMVUserInputHandler* m_UserInputHandler;
+ ref< IRadMoviePlayer2 > m_refIRadMoviePlayer;
+
+ bool mFrameReady;
+ float mElapsedTime; // Elapsed playing time. So you know if you should let the player skip the movie.
+ bool mDriveFinished;
+ float mFadeOut;
+ float mMovieVolume;
+};
+
+
+#endif //FMVPLAYER_H
+
diff --git a/game/code/presentation/fmvplayer/fmvuserinputhandler.cpp b/game/code/presentation/fmvplayer/fmvuserinputhandler.cpp
new file mode 100644
index 0000000..08c0ddf
--- /dev/null
+++ b/game/code/presentation/fmvplayer/fmvuserinputhandler.cpp
@@ -0,0 +1,257 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: FMVUserInputHandler
+//
+// Description: Implementation of the FMVUserInputHandler class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/10/20 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+
+#include <presentation/fmvplayer/fmvplayer.h>
+#include <presentation/fmvplayer/fmvuserinputhandler.h>
+
+#include <presentation/presentation.h>
+#include <presentation/gui/guiscreenmessage.h>
+#include <input/inputmanager.h>
+#include <gameflow/gameflow.h>
+#include <contexts/context.h>
+#include <main/game.h>
+#include <main/platform.h>
+
+#include <raddebug.hpp>
+
+static const float MIN_MOVIE_TIME = 0.125f;
+
+// this will allow any buttons to skip FMV
+//
+//#define ANY_BUTTON_SKIP
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+struct ControlMap
+{
+ char* inputName;
+ FMVInput::FMVInputEnum inputID;
+};
+
+const ControlMap FMV_CONTROL_MAP[] =
+{
+#ifdef RAD_GAMECUBE
+ { "Menu", FMVInput::Skip },
+ { "A", FMVInput::Skip },
+ #ifdef ANY_BUTTON_SKIP
+ { "LeftStickX", FMVInput::Skip },
+ { "LeftStickY", FMVInput::Skip },
+ { "RightStickX", FMVInput::Skip },
+ { "RightStickY", FMVInput::Skip },
+ { "DPadLeft", FMVInput::Skip },
+ { "DPadRight", FMVInput::Skip },
+ { "DPadUp", FMVInput::Skip },
+ { "DPadDown", FMVInput::Skip },
+ { "B", FMVInput::Skip },
+ { "X", FMVInput::Skip },
+ { "Y", FMVInput::Skip },
+ { "Z", FMVInput::Skip },
+ { "TriggerL", FMVInput::Skip },
+ { "TriggerR", FMVInput::Skip },
+ #endif
+#endif // RAD_GAMECUBE
+
+#ifdef RAD_PS2
+ { "Start", FMVInput::Start},
+ { "X", FMVInput::Skip },
+ { "DPadLeft", FMVInput::UNKNOWN },
+ { "DPadRight", FMVInput::UNKNOWN },
+ { "DPadUp", FMVInput::UNKNOWN },
+ { "DPadDown", FMVInput::UNKNOWN },
+ { "Select", FMVInput::UNKNOWN },
+ { "Triangle", FMVInput::UNKNOWN },
+ { "Circle", FMVInput::UNKNOWN },
+ { "Square", FMVInput::UNKNOWN },
+ { "L1", FMVInput::UNKNOWN },
+ { "R1", FMVInput::UNKNOWN },
+ { "L2", FMVInput::UNKNOWN },
+ { "R2", FMVInput::UNKNOWN },
+ #ifdef ANY_BUTTON_SKIP
+ { "LeftStickX", FMVInput::Skip },
+ { "LeftStickY", FMVInput::Skip },
+ { "RightStickX", FMVInput::Skip },
+ { "RightStickY", FMVInput::Skip },
+ #endif
+#endif // RAD_PS2
+
+#ifdef RAD_XBOX
+ { "A", FMVInput::Skip },
+ { "Start", FMVInput::Start},
+ #ifdef ANY_BUTTON_SKIP
+ { "LeftStickX", FMVInput::Skip },
+ { "LeftStickY", FMVInput::Skip },
+ { "RightStickX", FMVInput::Skip },
+ { "RightStickY", FMVInput::Skip },
+ { "DPadLeft", FMVInput::Skip },
+ { "DPadRight", FMVInput::Skip },
+ { "DPadUp", FMVInput::Skip },
+ { "DPadDown", FMVInput::Skip },
+ { "Back", FMVInput::Skip },
+ { "B", FMVInput::Skip },
+ { "X", FMVInput::Skip },
+ { "Y", FMVInput::Skip },
+ { "White", FMVInput::Skip },
+ { "Black", FMVInput::Skip },
+ { "LeftTrigger", FMVInput::Skip },
+ { "RightTrigger", FMVInput::Skip },
+ #endif
+#endif // RAD_XBOX
+
+#ifdef RAD_WIN32
+ { "feStart", FMVInput::Skip },
+ { "feBack", FMVInput::Skip },
+ { "feKeyboardBack", FMVInput::Skip },
+ { "feSelect", FMVInput::Skip },
+#endif // RAD_WIN32
+
+ { "", FMVInput::UNKNOWN }
+};
+
+const int NUM_FMV_CONTROL_MAPPINGS = sizeof( FMV_CONTROL_MAP ) /
+ sizeof( FMV_CONTROL_MAP[ 0 ] );
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// FMVUserInputHandler::FMVUserInputHandler
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+FMVUserInputHandler::FMVUserInputHandler( void )
+: m_isEnabled( true ),
+ m_controllerPromptShown( false ),
+ m_controllerReconnect( false )
+{
+}
+
+
+//===========================================================================
+// FMVUserInputHandler::~FMVUserInputHandler
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+FMVUserInputHandler::~FMVUserInputHandler( void )
+{
+}
+
+
+
+//===========================================================================
+// FMVUserInputHandler::OnButton
+//===========================================================================
+// Description:
+//
+// Constraints:
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+
+//////////////////////////////////////////////////////////////////////////////
+// IButtonedObject declarations
+//
+void FMVUserInputHandler::OnButton( int controllerId, int buttonId, const IButton* pButton )
+{
+}
+
+void FMVUserInputHandler::OnButtonUp( int controllerId, int buttonId, const IButton* pButton )
+{
+}
+
+void FMVUserInputHandler::OnControllerDisconnect( int id )
+{
+#ifndef RAD_GAMECUBE
+ int controllerID = GetInputManager()->GetControllerIDforPlayer( 0 );
+ if (GetGameFlow()->GetCurrentContext() == CONTEXT_GAMEPLAY
+ && controllerID == id )
+ {
+ m_controllerPromptShown = true;
+ char str_buffer[256];
+ CGuiScreenMessage::GetControllerDisconnectedMessage(controllerID, str_buffer, 255);
+ GetGame()->GetPlatform()->OnControllerError(str_buffer);
+ }
+#endif
+}
+void FMVUserInputHandler::OnControllerConnect( int id )
+{
+#ifndef RAD_GAMECUBE
+ if (m_controllerPromptShown && id==GetInputManager()->GetControllerIDforPlayer( 0 ))
+ {
+ m_controllerReconnect = true;
+ }
+#endif
+}
+
+
+void FMVUserInputHandler::OnButtonDown( int controllerId, int buttonId, const IButton* pButton )
+{
+ bool button_skip = buttonId == FMVInput::Skip;
+
+ if (buttonId==FMVInput::Start) // start also skip
+ button_skip = true;
+
+ if (buttonId==FMVInput::Start && m_controllerReconnect)
+ {
+ m_controllerReconnect = false;
+ GetGame()->GetPlatform()->ClearControllerError();
+ m_controllerPromptShown = false;
+ }
+ else if( m_isEnabled && button_skip )
+ {
+ if( GetPresentationManager()->GetFMVPlayer()->IsPlaying() &&
+ GetPresentationManager()->GetFMVPlayer()->GetElapsedTime() > MIN_MOVIE_TIME )
+ {
+ GetPresentationManager()->GetFMVPlayer()->Abort();
+ }
+ }
+}
+
+void FMVUserInputHandler::LoadControllerMappings( unsigned int controllerId )
+{
+ // now set controller mappings
+ for( int i = 0; i < NUM_FMV_CONTROL_MAPPINGS; i++ )
+ {
+ this->Map( FMV_CONTROL_MAP[ i ].inputName,
+ FMV_CONTROL_MAP[ i ].inputID,
+ 0,
+ controllerId );
+ }
+}
+
diff --git a/game/code/presentation/fmvplayer/fmvuserinputhandler.h b/game/code/presentation/fmvplayer/fmvuserinputhandler.h
new file mode 100644
index 0000000..aed8b8f
--- /dev/null
+++ b/game/code/presentation/fmvplayer/fmvuserinputhandler.h
@@ -0,0 +1,91 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: FMVUserInputHandler
+//
+// Description: This class feeds the inputs received by the controller
+// system into the GUI system.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/10/20 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef FMVUSERINPUTHANDLER_H
+#define FMVUSERINPUTHANDLER_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <input/mappable.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+namespace FMVInput
+{
+ // Definition of control points for an abstracted player controller
+ //
+ enum FMVInputEnum
+ {
+ UNKNOWN = -1,
+
+ Skip,
+ Start,
+
+ NUM_FMV_INPUTS
+ };
+};
+
+class FMVUserInputHandler : public Mappable
+{
+public:
+
+ FMVUserInputHandler( void );
+ virtual ~FMVUserInputHandler( void );
+
+ // Mappable interface declarations
+ //
+ virtual void OnButton( int controllerId, int buttonId, const IButton* pButton );
+ virtual void OnButtonUp( int controllerId, int buttonId, const IButton* pButton );
+ virtual void OnButtonDown( int controllerId, int buttonId, const IButton* pButton );
+
+ // Mappable interface declarations.
+ // Dispatch a message when controller is disconnected.
+ //
+ virtual void OnControllerDisconnect( int id );
+
+ // Mappable interface declarations.
+ // Dispatch a message when controller is connected.
+ //
+ virtual void OnControllerConnect( int id );
+
+ // Mappable interface declarations
+ //
+ virtual void LoadControllerMappings( unsigned int controllerId );
+
+ inline bool IsEnabled() const { return m_isEnabled; }
+ inline void SetEnabled( bool isEnabled ) { m_isEnabled = isEnabled; }
+
+
+private:
+ // Disallow object copying or assigning until we know we need it
+ //
+ FMVUserInputHandler( const FMVUserInputHandler& original );
+ FMVUserInputHandler& operator=( const FMVUserInputHandler& rhs );
+
+ bool m_isEnabled : 1;
+ bool m_controllerPromptShown : 1;
+ bool m_controllerReconnect;
+
+};
+
+#endif // FMVUSERINPUTHANDLER_H
diff --git a/game/code/presentation/gui/allgui.cpp b/game/code/presentation/gui/allgui.cpp
new file mode 100644
index 0000000..48e0374
--- /dev/null
+++ b/game/code/presentation/gui/allgui.cpp
@@ -0,0 +1,13 @@
+#include <presentation/gui/guientity.cpp>
+#include <presentation/gui/guimanager.cpp>
+#include <presentation/gui/guimenu.cpp>
+#include <presentation/gui/guimenuitem.cpp>
+#include <presentation/gui/guiscreen.cpp>
+#include <presentation/gui/guiscreenmemcardcheck.cpp>
+#include <presentation/gui/guiscreenmemorycard.cpp>
+#include <presentation/gui/guiscreenmessage.cpp>
+#include <presentation/gui/guiscreenprompt.cpp>
+#include <presentation/gui/guisystem.cpp>
+#include <presentation/gui/guitextbible.cpp>
+#include <presentation/gui/guiuserinputhandler.cpp>
+#include <presentation/gui/guiwindow.cpp>
diff --git a/game/code/presentation/gui/backend/allbackend.cpp b/game/code/presentation/gui/backend/allbackend.cpp
new file mode 100644
index 0000000..9ef2fe2
--- /dev/null
+++ b/game/code/presentation/gui/backend/allbackend.cpp
@@ -0,0 +1,4 @@
+#include <presentation/gui/backend/guimanagerbackend.cpp>
+#include <presentation/gui/backend/guiscreenloading.cpp>
+#include <presentation/gui/backend/guiscreenloadingfe.cpp>
+#include <presentation/gui/backend/guiscreendemo.cpp>
diff --git a/game/code/presentation/gui/backend/guiloadingbar.h b/game/code/presentation/gui/backend/guiloadingbar.h
new file mode 100644
index 0000000..7842105
--- /dev/null
+++ b/game/code/presentation/gui/backend/guiloadingbar.h
@@ -0,0 +1,61 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/22 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUILOADINGBAR_H
+#define GUILOADINGBAR_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+
+//===========================================================================
+// External Constants
+//===========================================================================
+
+const int MB = 1024 * 1024; // bytes
+
+#ifdef RAD_GAMECUBE
+ const float TOTAL_INGAME_MEMORY_USAGE = 9.6f * MB;
+ const float TOTAL_FE_MEMORY_USAGE = 8.8f * MB;
+ const float TOTAL_SUPERSPRINT_MEMORY_USAGE = 3.0f * MB;
+ const float TOTAL_DEMO_MEMORY_USAGE = TOTAL_INGAME_MEMORY_USAGE;
+#endif
+
+#ifdef RAD_PS2
+ const float TOTAL_INGAME_MEMORY_USAGE = 15.2f * MB;
+ const float TOTAL_FE_MEMORY_USAGE = 13.0f * MB;
+ const float TOTAL_SUPERSPRINT_MEMORY_USAGE = 5.6f * MB;
+ const float TOTAL_DEMO_MEMORY_USAGE = TOTAL_INGAME_MEMORY_USAGE;
+#endif
+
+#ifdef RAD_XBOX
+ const float TOTAL_INGAME_MEMORY_USAGE = 16.7f * MB;
+ const float TOTAL_FE_MEMORY_USAGE = 13.1f * MB;
+ const float TOTAL_SUPERSPRINT_MEMORY_USAGE = 5.5f * MB;
+ const float TOTAL_DEMO_MEMORY_USAGE = TOTAL_INGAME_MEMORY_USAGE;
+#endif
+
+#ifdef RAD_WIN32
+ // These settings are for release mode, which has difft memory behaviour than Tune,
+ // only because Tune has debug information.
+ const float TOTAL_INGAME_MEMORY_USAGE = 1.3f * MB;
+ const float TOTAL_FE_MEMORY_USAGE = 1.9f * MB;
+ const float TOTAL_SUPERSPRINT_MEMORY_USAGE = 1.3f * MB;
+ const float TOTAL_DEMO_MEMORY_USAGE = TOTAL_INGAME_MEMORY_USAGE;
+
+ // Our system for windows because the memory tracking doesn't work.
+ const float TOTAL_INGAME_FILES = 56;
+ // no fe.. it doesn't work with this system.
+ const float TOTAL_SUPERSPRINT_FILES = 34;
+ const float LOAD_BLEND_FACTOR = 20;
+ const float LOAD_MIN_SPEED = 0.003f;
+#endif
+
+#endif // GUILOADINGBAR_H
diff --git a/game/code/presentation/gui/backend/guimanagerbackend.cpp b/game/code/presentation/gui/backend/guimanagerbackend.cpp
new file mode 100644
index 0000000..7e65581
--- /dev/null
+++ b/game/code/presentation/gui/backend/guimanagerbackend.cpp
@@ -0,0 +1,296 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiManagerBackEnd
+//
+// Description: Implementation of the CGuiManagerBackEnd class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/15 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/backend/guimanagerbackend.h>
+#include <presentation/gui/backend/guiscreenloading.h>
+#include <presentation/gui/backend/guiscreenloadingfe.h>
+#include <presentation/gui/backend/guiscreendemo.h>
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/guiwindow.h> // for window IDs
+
+#include <contexts/bootupcontext.h>
+
+#include <gameflow/gameflow.h>
+
+#include <memory/srrmemory.h>
+
+#include <raddebug.hpp> // Foundation
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiManagerBackEnd::CGuiManagerBackEnd
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiManagerBackEnd::CGuiManagerBackEnd
+(
+ Scrooby::Project* pProject,
+ CGuiEntity* pParent
+)
+: CGuiManager( pProject, pParent ),
+ m_isQuittingDemo( false ),
+ m_isBackendPreRun( false )
+{
+}
+
+
+//===========================================================================
+// CGuiManagerBackEnd::~CGuiManagerBackEnd
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiManagerBackEnd::~CGuiManagerBackEnd()
+{
+ for( int i = 0; i < CGuiWindow::NUM_GUI_WINDOW_IDS; i++ )
+ {
+ if( m_windows[ i ] != NULL )
+ {
+ delete m_windows[ i ];
+ m_windows[ i ] = NULL;
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiManagerBackEnd::Populate
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiManagerBackEnd::Populate()
+{
+MEMTRACK_PUSH_GROUP( "CGUIManagerBackEnd" );
+ Scrooby::Screen* pScroobyScreen;
+ CGuiScreen* pScreen;
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Loading" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenLoading( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LOADING, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "LoadingFE" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenLoadingFE( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LOADING_FE, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Demo" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenDemo( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_DEMO, pScreen );
+ }
+MEMTRACK_POP_GROUP( "CGUIManagerBackEnd" );
+}
+
+void
+CGuiManagerBackEnd::Start( CGuiWindow::eGuiWindowID initialWindow )
+{
+ rAssert( m_state == GUI_FE_UNINITIALIZED );
+ m_state = GUI_FE_SCREEN_RUNNING;
+/*
+ m_nextScreen = initialWindow != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ?
+ initialWindow :
+ CGuiWindow::GUI_SCREEN_ID_LOADING;
+
+ m_state = GUI_FE_CHANGING_SCREENS; // must be set before calling GotoScreen()
+
+ CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) );
+ rAssert( nextScreen != NULL );
+ m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this );
+*/
+}
+
+//===========================================================================
+// CGuiManagerBackEnd::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiManagerBackEnd::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ switch( message )
+ {
+ case GUI_MSG_PRE_RUN_BACKEND:
+ {
+ this->GotoLoadingScreen( param1 );
+
+ m_isBackendPreRun = true;
+
+ break;
+ }
+
+ case GUI_MSG_RUN_BACKEND:
+ {
+ if( !m_isBackendPreRun )
+ {
+ this->GotoLoadingScreen( param1 );
+ }
+
+ // load dynamic resources for loading screen
+ //
+ CGuiWindow* loadingScreen = this->FindWindowByID( m_nextScreen );
+ rAssert( loadingScreen != NULL );
+ loadingScreen->HandleMessage( GUI_MSG_LOAD_RESOURCES );
+
+ break;
+ }
+
+ case GUI_MSG_QUIT_BACKEND:
+ {
+ m_isBackendPreRun = false;
+
+ // Tell the current screen to shut down.
+ //
+ this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT );
+
+ // Go to a blank screen.
+ //
+ m_pScroobyProject->GotoScreen( "Blank", NULL );
+
+ break;
+ }
+
+ case GUI_MSG_RUN_DEMO:
+ {
+ CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_DEMO,
+ CLEAR_WINDOW_HISTORY | FORCE_WINDOW_RELOAD | FORCE_WINDOW_CHANGE_IMMEDIATE );
+
+ break;
+ }
+
+ case GUI_MSG_QUIT_DEMO:
+ {
+ m_isQuittingDemo = true;
+
+ CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_LOADING_FE,
+ CLEAR_WINDOW_HISTORY );
+
+ break;
+ }
+
+ case GUI_MSG_WINDOW_FINISHED:
+ {
+ if( GUI_FE_CHANGING_SCREENS == m_state )
+ {
+ if( m_isQuittingDemo )
+ {
+ m_isQuittingDemo = false;
+
+ // switch to frontend context
+ //
+ GetGameFlow()->SetContext( CONTEXT_FRONTEND );
+ }
+
+ m_currentScreen = m_nextScreen;
+ CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) );
+ rAssert( nextScreen != NULL );
+ m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this );
+ }
+
+ break;
+ }
+
+ default:
+ {
+ if( m_state != GUI_FE_UNINITIALIZED &&
+ m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED )
+ {
+ // Send the messages down to the current screen.
+ //
+ CGuiWindow* pScreen = this->FindWindowByID( m_currentScreen );
+ rAssert( pScreen );
+
+ pScreen->HandleMessage( message, param1, param2 );
+ }
+ }
+ }
+
+ // propogate message up the hierarchy
+ CGuiManager::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// Private Member Functions
+//===========================================================================
+
+void
+CGuiManagerBackEnd::GotoLoadingScreen( unsigned int param1 )
+{
+ bool isLoadingGameplay = (param1 == IS_LOADING_GAMEPLAY ||
+ GetGameFlow()->GetNextContext() == CONTEXT_LOADING_GAMEPLAY);
+
+ unsigned int loadingScreenID = isLoadingGameplay ?
+ CGuiWindow::GUI_SCREEN_ID_LOADING :
+ CGuiWindow::GUI_SCREEN_ID_LOADING_FE;
+/*
+#ifdef RAD_E3
+ // always show I&S loading screen for E3 build
+ //
+ loadingScreenID = CGuiWindow::GUI_SCREEN_ID_LOADING_FE;
+#endif
+*/
+ CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN,
+ loadingScreenID,
+ CLEAR_WINDOW_HISTORY | FORCE_WINDOW_RELOAD | FORCE_WINDOW_CHANGE_IMMEDIATE );
+}
+
diff --git a/game/code/presentation/gui/backend/guimanagerbackend.h b/game/code/presentation/gui/backend/guimanagerbackend.h
new file mode 100644
index 0000000..f297343
--- /dev/null
+++ b/game/code/presentation/gui/backend/guimanagerbackend.h
@@ -0,0 +1,69 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiManagerBackEnd
+//
+// Description: Interface for the CGuiManagerBackEnd class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/15 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUIMANAGERBACKEND_H
+#define GUIMANAGERBACKEND_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guimanager.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+const unsigned int IS_LOADING_GAMEPLAY = 1;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiManagerBackEnd : public CGuiManager
+{
+ public:
+
+ CGuiManagerBackEnd( Scrooby::Project* pProject,
+ CGuiEntity* pParent );
+
+ virtual ~CGuiManagerBackEnd();
+
+ virtual void Populate();
+ virtual void Start( CGuiWindow::eGuiWindowID initialWindow = CGuiWindow::GUI_WINDOW_ID_UNDEFINED );
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ private:
+
+ //---------------------------------------------------------------------
+ // Private Functions
+ //---------------------------------------------------------------------
+
+ // No copying or assignment. Declare but don't define.
+ //
+ CGuiManagerBackEnd( const CGuiManagerBackEnd& );
+ CGuiManagerBackEnd& operator= ( const CGuiManagerBackEnd& );
+
+ void GotoLoadingScreen( unsigned int param1 );
+
+ //---------------------------------------------------------------------
+ // Private Data
+ //---------------------------------------------------------------------
+
+ bool m_isQuittingDemo;
+ bool m_isBackendPreRun;
+
+};
+
+#endif // GUIMANAGERBACKEND_H
diff --git a/game/code/presentation/gui/backend/guiscreendemo.cpp b/game/code/presentation/gui/backend/guiscreendemo.cpp
new file mode 100644
index 0000000..770f4ce
--- /dev/null
+++ b/game/code/presentation/gui/backend/guiscreendemo.cpp
@@ -0,0 +1,210 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenDemo
+//
+// Description: Implementation of the CGuiScreenDemo class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/backend/guiscreendemo.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <presentation/gui/guisystem.h>
+
+#include <contexts/demo/democontext.h>
+
+#include <raddebug.hpp> // Foundation
+#include <layer.h>
+#include <page.h>
+#include <screen.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenDemo::CGuiScreenDemo
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenDemo::CGuiScreenDemo
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_DEMO ),
+ m_demoText( NULL ),
+ m_elapsedTime( 0 )
+{
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage;
+ pPage = m_pScroobyScreen->GetPage( "Demo" );
+ rAssert( pPage );
+
+ Scrooby::Layer* foreground = pPage->GetLayer( "Foreground" );
+ rAssert( foreground != NULL );
+
+ m_demoText = foreground->GetText( "Demo" );
+ rAssert( m_demoText );
+}
+
+
+//===========================================================================
+// CGuiScreenDemo::~CGuiScreenDemo
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenDemo::~CGuiScreenDemo()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenDemo::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenDemo::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ m_elapsedTime += param1;
+
+ const unsigned int BLINK_PERIOD = 250;
+ bool blinked = GuiSFX::Blink( m_demoText,
+ (float)m_elapsedTime,
+ (float)BLINK_PERIOD );
+ if( blinked )
+ {
+ m_elapsedTime %= BLINK_PERIOD;
+ }
+
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_CONNECT:
+ case GUI_MSG_CONTROLLER_DISCONNECT:
+ case GUI_MSG_CONTROLLER_START:
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ GetDemoContext()->EndDemo();
+// m_pParent->HandleMessage( GUI_MSG_QUIT_DEMO );
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenDemo::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenDemo::InitIntro()
+{
+ rAssert( m_demoText );
+ m_demoText->SetVisible( true );
+
+ m_elapsedTime = 0;
+}
+
+//===========================================================================
+// CGuiScreenDemo::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenDemo::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenDemo::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenDemo::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/backend/guiscreendemo.h b/game/code/presentation/gui/backend/guiscreendemo.h
new file mode 100644
index 0000000..7f28c45
--- /dev/null
+++ b/game/code/presentation/gui/backend/guiscreendemo.h
@@ -0,0 +1,52 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenDemo
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENDEMO_H
+#define GUISCREENDEMO_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenDemo : public CGuiScreen
+{
+public:
+ CGuiScreenDemo( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenDemo();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ Scrooby::Text* m_demoText;
+ unsigned int m_elapsedTime;
+
+};
+
+#endif // GUISCREENDEMO_H
diff --git a/game/code/presentation/gui/backend/guiscreenloading.cpp b/game/code/presentation/gui/backend/guiscreenloading.cpp
new file mode 100644
index 0000000..486a72b
--- /dev/null
+++ b/game/code/presentation/gui/backend/guiscreenloading.cpp
@@ -0,0 +1,624 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLoading
+//
+// Description: Implementation of the CGuiScreenLoading class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <camera/animatedcam.h>
+#include <camera/supercammanager.h>
+#include <presentation/gui/backend/guiscreenloading.h>
+#include <presentation/gui/backend/guiloadingbar.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <presentation/gui/guitextbible.h>
+
+#include <gameflow/gameflow.h>
+#include <memory/createheap.h>
+#include <memory/memoryutilities.h>
+#include <mission/gameplaymanager.h>
+#include <mission/missionmanager.h>
+#include <render/rendermanager/rendermanager.h>
+#include <render/rendermanager/renderlayer.h>
+#include <sound/soundmanager.h>
+
+#include <raddebug.hpp> // Foundation
+#include <p3d/sprite.hpp>
+#include <p3d/utility.hpp>
+#include <screen.h>
+#include <page.h>
+#include <layer.h>
+#include <group.h>
+#include <sprite.h>
+#include <polygon.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+#define ENABLE_DYNA_LOADED_IMAGES
+//#define LOADING_BAR_EXPLOSION
+
+#ifdef ENABLE_DYNA_LOADED_IMAGES
+ const char* DYNAMIC_RESOURCES_DIR = "art\\frontend\\dynaload\\images\\loading\\";
+ const char* DYNA_LOAD_INVENTORY_SECTION = "LoadingScreenImages";
+#endif
+
+// this is to correct the original reduced scale in the source image
+//
+#ifdef RAD_WIN32
+ const float LOADING_BGD0_CORRECTION_SCALE = 1.05f;
+#else
+ const float LOADING_BGD0_CORRECTION_SCALE = 4.2f;
+#endif
+
+#ifdef RAD_WIN32
+ const float LOADING_BGD1_CORRECTION_SCALE = 1.75f;
+#else
+ const float LOADING_BGD1_CORRECTION_SCALE = 8.4f;
+#endif
+
+#ifdef RAD_PS2
+ const float LOADING_IMAGE_CORRECTION_SCALE = 1.95f;
+#elif defined( RAD_WIN32 )
+ const float LOADING_IMAGE_CORRECTION_SCALE = 0.925f;
+#else
+ const float LOADING_IMAGE_CORRECTION_SCALE = 1.85f;
+#endif
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenLoading::CGuiScreenLoading
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLoading::CGuiScreenLoading
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_LOADING ),
+ m_elapsedTime( 0 ),
+ m_elapsedSpiralTime( 0 ),
+ m_loadingBarGroup( NULL ),
+ m_currentMemoryUsage( 0.0f ),
+ m_startingMemoryAvailable( 0 ),
+ m_elapsedFireTime( 0 ),
+ m_loadingImage( NULL ),
+ m_isSpirallingDone( false ),
+ m_loadingImageSprite( NULL ),
+ m_explosionLayer( NULL ),
+ m_explosion( NULL ),
+ m_elapsedExplosionTime( 0 )
+{
+ memset( m_loadingImageName, 0, sizeof( m_loadingImageName ) );
+
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage;
+ pPage = m_pScroobyScreen->GetPage( "Loading" );
+ rAssert( pPage );
+
+ Scrooby::Layer* newspaperLayer = pPage->GetLayer( "Newspaper" );
+ rAssert( newspaperLayer != NULL );
+ m_loadingImage = newspaperLayer->GetSprite( "Loading" );
+ m_loadingImage->SetVisible( false );
+
+ if( this->IsWideScreenDisplay() )
+ {
+ newspaperLayer->ResetTransformation();
+ this->ApplyWideScreenCorrectionScale( newspaperLayer );
+ }
+
+ Scrooby::Layer* foregroundLayer = pPage->GetLayer( "Foreground" );
+
+ for( int i = 0; i < NUM_LOADING_OVERLAYS; i++ )
+ {
+ char overlayName[ 32 ];
+ sprintf( overlayName, "Overlay%d", i );
+ m_loadingOverlays[ i ] = foregroundLayer->GetSprite( overlayName );
+ rAssert( m_loadingOverlays[ i ] != NULL );
+ }
+
+ // get loading bar
+ //
+ m_loadingBarGroup = pPage->GetGroup( "LoadingBar" );
+ rAssert( m_loadingBarGroup != NULL );
+ m_loadingBar.m_type = Slider::HORIZONTAL_SLIDER_RIGHT;
+ m_loadingBar.SetScroobyPolygon( m_loadingBarGroup->GetPolygon( "Wick" ),
+ m_loadingBarGroup->GetSprite( "Fire" ) );
+
+ Scrooby::Sprite* loadingBgd = pPage->GetSprite( "Background" );
+ if( loadingBgd != NULL )
+ {
+ loadingBgd->ScaleAboutCenter( LOADING_BGD0_CORRECTION_SCALE );
+ }
+
+/*
+ // XBOX ONLY: show loading text to satisfy Xbox TCR requirement (C01-07)
+ //
+#ifndef RAD_XBOX
+ // otherwise, hide it for all other platforms
+ //
+ Scrooby::Text* loadingText = pPage->GetText( "Loading" );
+ if( loadingText != NULL )
+ {
+ loadingText->SetVisible( false );
+ }
+#endif // !RAD_XBOX
+*/
+
+ // get explosion overlay (from Explosion.pag)
+ //
+ pPage = m_pScroobyScreen->GetPage( "Explosion" );
+ if( pPage != NULL )
+ {
+ m_explosionLayer = pPage->GetLayer( "Explosion" );
+ rAssert( m_explosionLayer != NULL );
+
+ m_explosion = m_explosionLayer->GetPolygon( "Explosion0" );
+ rAssert( m_explosion != NULL );
+ }
+
+#ifdef ENABLE_DYNA_LOADED_IMAGES
+ // add inventory section for dynamically loaded resources
+ //
+ p3d::inventory->AddSection( DYNA_LOAD_INVENTORY_SECTION );
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenLoading::~CGuiScreenLoading
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLoading::~CGuiScreenLoading()
+{
+#ifdef ENABLE_DYNA_LOADED_IMAGES
+ // delete inventory section for dynamically loaded resources
+ //
+ p3d::inventory->DeleteSection( DYNA_LOAD_INVENTORY_SECTION );
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenLoading::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLoading::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ // update elapsed time
+ m_elapsedTime += param1;
+
+ if( !m_isSpirallingDone )
+ {
+ // update loading image
+ //
+ static float SPIRAL_DURATION_TIME = 1800.0f; // in msec
+ static float SPIRAL_ROTATION_TIME = 60.0f; // in msec
+
+ m_elapsedSpiralTime += param1;
+ m_isSpirallingDone = GuiSFX::Spiral( m_loadingImage,
+ (float)m_elapsedSpiralTime,
+ SPIRAL_DURATION_TIME,
+ SPIRAL_ROTATION_TIME,
+ 0.25f, // LOADING_IMAGE_CORRECTION_SCALE * 2.0f,
+ LOADING_IMAGE_CORRECTION_SCALE );
+ }
+
+ static float ROTATION_PERIOD = 20000; // in msec
+ float currentAngle = ((float)m_elapsedTime / ROTATION_PERIOD) * 360.0f;
+
+ for( int i = 0; i < NUM_LOADING_OVERLAYS; i++ )
+ {
+ rAssert( m_loadingOverlays[ i ] );
+ m_loadingOverlays[ i ]->ResetTransformation();
+ m_loadingOverlays[ i ]->ScaleAboutCenter( LOADING_BGD1_CORRECTION_SCALE );
+ m_loadingOverlays[ i ]->RotateAboutCenter( currentAngle );
+
+ currentAngle *= -1.0f; // reverse rotation direction
+ }
+
+ if( GetGameFlow()->GetCurrentContext() == CONTEXT_LOADING_GAMEPLAY )
+ {
+ // update loading bar
+ //
+ rAssert( m_loadingBarGroup != NULL );
+ m_loadingBarGroup->SetVisible( true );
+
+#if defined( RAD_XBOX )
+ float newMemoryUsage = (m_startingMemoryAvailable - Memory::GetTotalMemoryFree()) / TOTAL_INGAME_MEMORY_USAGE;
+#elif defined( RAD_WIN32 )
+ // this sucks but i just want to finish it.
+ float memUsage = float( GetLoadingManager()->GetNumRequestsProcessed() ) / TOTAL_INGAME_FILES;
+ float newMemoryUsage = m_currentMemoryUsage;
+ if( memUsage - newMemoryUsage < LOAD_MIN_SPEED )
+ {
+ newMemoryUsage = memUsage;
+ }
+ else
+ {
+ float delta = (memUsage - newMemoryUsage) / LOAD_BLEND_FACTOR;
+ newMemoryUsage += delta > LOAD_MIN_SPEED ? delta : LOAD_MIN_SPEED;
+ }
+#else
+ float newMemoryUsage = (m_startingMemoryAvailable - GetTotalMemoryFreeInAllHeaps()) / TOTAL_INGAME_MEMORY_USAGE;
+#endif
+ // don't allow loading bar to go backwards
+ //
+ if( newMemoryUsage > m_currentMemoryUsage )
+ {
+ m_currentMemoryUsage = newMemoryUsage;
+
+ if( m_currentMemoryUsage < 1.0f )
+ {
+ m_loadingBar.SetValue( 1.0f - m_currentMemoryUsage );
+ }
+ else
+ {
+#ifdef LOADING_BAR_EXPLOSION
+ if( m_explosionLayer != NULL && m_explosion != NULL )
+ {
+ m_explosionLayer->SetVisible( true );
+
+ m_elapsedExplosionTime += param1;
+/*
+ float explosionScale = EXPLOSION_SCALE_START + m_elapsedExplosionTime / 1000.0f * EXPLOSION_SCALE_RATE;
+ m_explosion->ResetTransformation();
+ m_explosion->ScaleAboutCenter( explosionScale );
+*/
+ const unsigned int EXPLOSION_FLICKER_PERIOD = 50;
+ bool isBlinked = GuiSFX::Blink( m_explosion,
+ (float)m_elapsedExplosionTime,
+ (float)EXPLOSION_FLICKER_PERIOD );
+
+ if( isBlinked )
+ {
+ m_elapsedExplosionTime %= EXPLOSION_FLICKER_PERIOD;
+ }
+/*
+ tColour currentColour;
+ GuiSFX::ModulateColour( &currentColour,
+ (float)m_elapsedExplosionTime,
+ 100.0f,
+ tColour( 255, 255, 0 ),
+ tColour( 255, 0, 0 ) );
+
+ for( int i = 0; i < m_explosion->GetNumOfVertexes(); i++ )
+ {
+ m_explosion->SetVertexColour( i, currentColour );
+ }
+*/
+ }
+#else
+ #ifndef RAD_DEBUG
+ rReleaseWarningMsg( false, "Current memory usage for loading bar exceeds 100%!" );
+ #endif
+#endif // LOADING_BAR_EXPLOSION
+ }
+ }
+
+ // flicker loading bar flame
+ //
+ const unsigned int LOADING_BAR_FIRE_TIME = 50; // in msec
+ m_elapsedFireTime += param1;
+ if( m_elapsedFireTime > LOADING_BAR_FIRE_TIME )
+ {
+ rAssert( m_loadingBar.m_pImage != NULL );
+ m_loadingBar.m_pImage->SetIndex( 1 - m_loadingBar.m_pImage->GetIndex() );
+
+ m_elapsedFireTime %= LOADING_BAR_FIRE_TIME;
+ }
+ }
+
+ break;
+ }
+ case GUI_MSG_LOAD_RESOURCES:
+ {
+ this->LoadResources();
+
+#ifdef RAD_XBOX
+ m_startingMemoryAvailable = Memory::GetTotalMemoryFree();
+#else
+ m_startingMemoryAvailable = GetTotalMemoryFreeInAllHeaps();
+#endif
+ rReleasePrintf( "Starting Memory Available = %.2f MB\n", (float)m_startingMemoryAvailable / MB );
+
+#ifdef RAD_WIN32
+ GetLoadingManager()->ResetRequestsProcessed();
+#endif
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+void
+CGuiScreenLoading::LoadResources()
+{
+ int currentLevel = GetGameplayManager()->GetCurrentLevelIndex();
+
+#ifdef ENABLE_DYNA_LOADED_IMAGES
+ char languageDir[ 16 ];
+ languageDir[ 0 ] = '\0';
+
+#ifdef PAL
+ switch( CGuiTextBible::GetCurrentLanguage() )
+ {
+ case Scrooby::XL_FRENCH:
+ {
+ strcpy( languageDir, "french\\" );
+
+ break;
+ }
+ case Scrooby::XL_GERMAN:
+ {
+ strcpy( languageDir, "german\\" );
+
+ break;
+ }
+ case Scrooby::XL_SPANISH:
+ {
+ strcpy( languageDir, "spanish\\" );
+
+ break;
+ }
+ default:
+ {
+ rAssert( CGuiTextBible::GetCurrentLanguage() == Scrooby::XL_ENGLISH );
+
+ break;
+ }
+ }
+#endif // PAL
+
+ sprintf( m_loadingImageName, "loading%d.png", currentLevel + 1 );
+
+ char loadingImageFile[ 256 ];
+ sprintf( loadingImageFile, "%s%sloading%d.p3d",
+ DYNAMIC_RESOURCES_DIR,
+ languageDir,
+ currentLevel + 1 );
+
+ // add request to loading manager to load image file
+ //
+ GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D,
+ loadingImageFile,
+ GMA_LEVEL_OTHER,
+ DYNA_LOAD_INVENTORY_SECTION,
+ DYNA_LOAD_INVENTORY_SECTION,
+ this );
+#else
+ // set the current level loading image
+ //
+ rAssert( m_loadingImage );
+ m_loadingImage->SetIndex( currentLevel );
+#endif
+
+ // reset elapsed spiralling time
+ //
+ m_elapsedSpiralTime = 0;
+}
+
+void
+CGuiScreenLoading::OnProcessRequestsComplete( void* pUserData )
+{
+#ifdef ENABLE_DYNA_LOADED_IMAGES
+ // push and select inventory section for searching
+ //
+ p3d::inventory->PushSection();
+ p3d::inventory->SelectSection( DYNA_LOAD_INVENTORY_SECTION );
+ bool currentSectionOnly = p3d::inventory->GetCurrentSectionOnly();
+ p3d::inventory->SetCurrentSectionOnly( true );
+
+ // search for the loading image sprite
+ //
+ rAssert( m_loadingImageSprite == NULL );
+ m_loadingImageSprite = p3d::find<tSprite>( m_loadingImageName );
+ rAssert( m_loadingImageSprite );
+ m_loadingImageSprite->AddRef();
+
+ // pop inventory section and restore states
+ //
+ p3d::inventory->SetCurrentSectionOnly( currentSectionOnly );
+ p3d::inventory->PopSection();
+
+ // set the raw sprite to the Scrooby loading image
+ //
+ rAssert( m_loadingImage );
+ m_loadingImage->SetRawSprite( m_loadingImageSprite, true );
+ m_loadingImage->SetVisible( true );
+ m_loadingImage->ScaleAboutCenter( 0.0f );
+
+ m_isSpirallingDone = false;
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenLoading::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLoading::InitIntro()
+{
+ RenderLayer* levelLayer = GetRenderManager()->mpLayer( RenderEnums::LevelSlot );
+ if( levelLayer != NULL )
+ {
+ levelLayer->Freeze();
+ }
+
+ // reset loading overlay scale
+ //
+ for( int i = 0; i < NUM_LOADING_OVERLAYS; i++ )
+ {
+ rAssert( m_loadingOverlays[ i ] );
+ m_loadingOverlays[ i ]->ResetTransformation();
+ m_loadingOverlays[ i ]->ScaleAboutCenter( LOADING_BGD1_CORRECTION_SCALE );
+ }
+
+ m_loadingBar.SetValue( 1.0f );
+
+ // reset current memory usage
+ //
+ m_currentMemoryUsage = 0.0f;
+
+ // hide loading bar by default
+ //
+ rAssert( m_loadingBarGroup != NULL );
+ m_loadingBarGroup->SetVisible( false );
+
+ // hide explosion overlay
+ //
+ if( m_explosionLayer != NULL && m_explosion != NULL )
+ {
+ m_explosionLayer->SetVisible( false );
+ m_explosion->SetVisible( true );
+
+ m_elapsedExplosionTime = 0;
+ }
+
+ //
+ // Sound ducking, but only for intra-mission stuff. If we're coming
+ // from the FE, we want to play the newspaper spin music.
+ //
+ if( GetGameFlow()->GetCurrentContext() != CONTEXT_FRONTEND )
+ {
+ GetSoundManager()->OnPauseStart();
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenLoading::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLoading::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenLoading::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLoading::InitOutro()
+{
+ RenderLayer* levelLayer = GetRenderManager()->mpLayer( RenderEnums::LevelSlot );
+ if( levelLayer != NULL && levelLayer->IsFrozen() )
+ {
+ levelLayer->Thaw();
+ }
+
+#ifdef ENABLE_DYNA_LOADED_IMAGES
+ p3d::pddi->DrawSync();
+
+ if( m_loadingImageSprite != NULL )
+ {
+ rAssert( m_loadingImage );
+ m_loadingImage->SetRawSprite( NULL, true );
+ m_loadingImage->SetVisible( false );
+
+ // remove and release the loading image sprite
+ //
+ p3d::inventory->RemoveSectionElements( DYNA_LOAD_INVENTORY_SECTION );
+ m_loadingImageSprite->ReleaseVerified();
+ m_loadingImageSprite = NULL;
+ }
+#endif
+
+ rReleasePrintf( "Final memory usage value for loading bar = %.3f\n", m_currentMemoryUsage );
+ m_loadingBar.SetValue( 0.0f );
+
+ m_isSpirallingDone = true;
+
+ // reset elapsed time for any loading animations
+ //
+ m_elapsedTime = 0;
+ m_elapsedFireTime = 0;
+
+ GetSoundManager()->ResetDucking();
+ AnimatedCam::CheckPendingCameraSwitch();
+ GetSuperCamManager()->GetSCC( 0 )->NoTransition();
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/backend/guiscreenloading.h b/game/code/presentation/gui/backend/guiscreenloading.h
new file mode 100644
index 0000000..1961864
--- /dev/null
+++ b/game/code/presentation/gui/backend/guiscreenloading.h
@@ -0,0 +1,84 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLoading
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENLOADING_H
+#define GUISCREENLOADING_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <presentation/gui/utility/slider.h>
+
+#include <loading/loadingmanager.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class tSprite;
+namespace Scrooby
+{
+ class Group;
+}
+
+const int NUM_LOADING_OVERLAYS = 2;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenLoading : public CGuiScreen,
+ public LoadingManager::ProcessRequestsCallback
+{
+public:
+ CGuiScreenLoading( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenLoading();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ void LoadResources();
+ virtual void OnProcessRequestsComplete( void* pUserData );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ unsigned int m_elapsedTime;
+ unsigned int m_elapsedSpiralTime;
+
+ Scrooby::Group* m_loadingBarGroup;
+ Slider m_loadingBar;
+ float m_currentMemoryUsage; // in percent
+ int m_startingMemoryAvailable; // in bytes
+ unsigned int m_elapsedFireTime;
+
+ Scrooby::Sprite* m_loadingImage;
+ Scrooby::Sprite* m_loadingOverlays[ NUM_LOADING_OVERLAYS ];
+ bool m_isSpirallingDone : 1;
+
+ tSprite* m_loadingImageSprite;
+ char m_loadingImageName[ 32 ];
+
+ Scrooby::Layer* m_explosionLayer;
+ Scrooby::Polygon* m_explosion;
+ unsigned int m_elapsedExplosionTime;
+
+};
+
+#endif // GUISCREENLOADING_H
diff --git a/game/code/presentation/gui/backend/guiscreenloadingfe.cpp b/game/code/presentation/gui/backend/guiscreenloadingfe.cpp
new file mode 100644
index 0000000..7435003
--- /dev/null
+++ b/game/code/presentation/gui/backend/guiscreenloadingfe.cpp
@@ -0,0 +1,566 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLoadingFE
+//
+// Description: Implementation of the CGuiScreenLoadingFE class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/backend/guiscreenloadingfe.h>
+#include <presentation/gui/backend/guiloadingbar.h>
+#include <presentation/gui/utility/specialfx.h>
+
+#include <gameflow/gameflow.h>
+#include <memory/createheap.h>
+#include <memory/memoryutilities.h>
+#include <render/rendermanager/rendermanager.h>
+#include <render/rendermanager/renderlayer.h>
+#include <sound/soundmanager.h>
+
+#include <p3d/drawable.hpp>
+#include <p3d/camera.hpp>
+#include <p3d/anim/multicontroller.hpp>
+
+#include <raddebug.hpp> // Foundation
+#include <screen.h>
+#include <layer.h>
+#include <page.h>
+#include <group.h>
+#include <text.h>
+#include <sprite.h>
+#include <polygon.h>
+#include <pure3dobject.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+#define ENABLE_DYNA_LOADED_RESOURCES
+//#define LOADING_BAR_FE_EXPLOSION
+
+#ifdef ENABLE_DYNA_LOADED_RESOURCES
+ const char* LOADING_FE_PURE3D_FILE = "art\\frontend\\scrooby\\resource\\pure3d\\loading.p3d";
+ const char* LOADING_FE_INVENTORY = "LoadingFEScreen";
+
+ const char* LOADING_FE_DRAWABLE = "loading_screen";
+ const char* LOADING_FE_CAMERA = "loading_screen_cameraShape";
+ const char* LOADING_FE_MULTICONTROLLER = "loading_screen_MasterController";
+#endif
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenLoadingFE::CGuiScreenLoadingFE
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLoadingFE::CGuiScreenLoadingFE
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_LOADING_FE ),
+ m_loadingText( NULL ),
+ m_itchyAndScratchy( NULL ),
+ m_elapsedTime( 0 ),
+ m_loadingBarGroup( NULL ),
+ m_currentMemoryUsage( 0.0f ),
+ m_startingMemoryAvailable( 0 ),
+ m_elapsedFireTime( 0 ),
+ m_explosionLayer( NULL ),
+ m_explosion( NULL ),
+ m_elapsedExplosionTime( 0 )
+{
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "LoadingFE" );
+ rAssert( pPage != NULL );
+
+ Scrooby::Layer* foreground = pPage->GetLayer( "Foreground" );
+ Scrooby::Layer* background = pPage->GetLayer( "Background" );
+
+ m_loadingText = foreground->GetText( "Loading" );
+ rAssert( m_loadingText != NULL );
+
+ m_itchyAndScratchy = background->GetPure3dObject( "Loading" );
+ if( m_itchyAndScratchy != NULL )
+ {
+ m_itchyAndScratchy->SetDrawable( NULL );
+ m_itchyAndScratchy->SetCamera( NULL );
+ m_itchyAndScratchy->SetMultiController( NULL );
+
+ m_itchyAndScratchy->SetClearDepthBuffer( true );
+ }
+
+ // get loading bar
+ //
+ m_loadingBarGroup = pPage->GetGroup( "LoadingBar" );
+ rAssert( m_loadingBarGroup != NULL );
+ m_loadingBar.m_type = Slider::HORIZONTAL_SLIDER_RIGHT;
+ m_loadingBar.SetScroobyPolygon( m_loadingBarGroup->GetPolygon( "Wick" ),
+ m_loadingBarGroup->GetSprite( "Fire" ) );
+
+ // get explosion overlay (from Explosion.pag)
+ //
+ pPage = m_pScroobyScreen->GetPage( "Explosion" );
+ if( pPage != NULL )
+ {
+ m_explosionLayer = pPage->GetLayer( "Explosion" );
+ rAssert( m_explosionLayer != NULL );
+
+ m_explosion = m_explosionLayer->GetPolygon( "Explosion0" );
+ rAssert( m_explosion != NULL );
+ }
+
+#ifdef ENABLE_DYNA_LOADED_RESOURCES
+ p3d::inventory->AddSection( LOADING_FE_INVENTORY );
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenLoadingFE::~CGuiScreenLoadingFE
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLoadingFE::~CGuiScreenLoadingFE()
+{
+#ifdef ENABLE_DYNA_LOADED_RESOURCES
+ p3d::inventory->DeleteSection( LOADING_FE_INVENTORY );
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenLoadingFE::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLoadingFE::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ // update loading text
+ //
+ const unsigned int LOADING_TEXT_LOOP_TIME = 500; // in msec
+ m_elapsedTime += param1;
+ if( m_elapsedTime > LOADING_TEXT_LOOP_TIME )
+ {
+ rAssert( m_loadingText != NULL );
+ int nextIndex = (m_loadingText->GetIndex() + 1) % m_loadingText->GetNumOfStrings();
+ m_loadingText->SetIndex( nextIndex );
+
+ m_elapsedTime %= LOADING_TEXT_LOOP_TIME;
+ }
+
+ ContextEnum currentContext = GetGameFlow()->GetCurrentContext();
+ if( currentContext == CONTEXT_FRONTEND ||
+ currentContext == CONTEXT_LOADING_DEMO ||
+ currentContext == CONTEXT_LOADING_SUPERSPRINT ||
+ currentContext == CONTEXT_LOADING_GAMEPLAY )
+ {
+ // update loading bar
+ //
+ rAssert( m_loadingBarGroup != NULL );
+ m_loadingBarGroup->SetVisible( true );
+
+ float newMemoryUsage = this->GetCurrentMemoryUsage( currentContext );
+
+ // don't allow loading bar to go backwards
+ //
+ if( newMemoryUsage > m_currentMemoryUsage )
+ {
+ m_currentMemoryUsage = newMemoryUsage;
+
+ if( m_currentMemoryUsage < 1.0f )
+ {
+ m_loadingBar.SetValue( 1.0f - m_currentMemoryUsage );
+ }
+ else
+ {
+#ifdef LOADING_BAR_FE_EXPLOSION
+ if( m_explosionLayer != NULL && m_explosion != NULL )
+ {
+ m_explosionLayer->SetVisible( true );
+
+ m_elapsedExplosionTime += param1;
+/*
+ float explosionScale = EXPLOSION_SCALE_START + m_elapsedExplosionTime / 1000.0f * EXPLOSION_SCALE_RATE;
+ m_explosion->ResetTransformation();
+ m_explosion->ScaleAboutCenter( explosionScale );
+*/
+ const unsigned int EXPLOSION_FLICKER_PERIOD = 50;
+ bool isBlinked = GuiSFX::Blink( m_explosion,
+ (float)m_elapsedExplosionTime,
+ (float)EXPLOSION_FLICKER_PERIOD );
+
+ if( isBlinked )
+ {
+ m_elapsedExplosionTime %= EXPLOSION_FLICKER_PERIOD;
+ }
+/*
+ tColour currentColour;
+ GuiSFX::ModulateColour( &currentColour,
+ (float)m_elapsedExplosionTime,
+ 100.0f,
+ tColour( 255, 255, 0 ),
+ tColour( 255, 0, 0 ) );
+
+ for( int i = 0; i < m_explosion->GetNumOfVertexes(); i++ )
+ {
+ m_explosion->SetVertexColour( i, currentColour );
+ }
+*/
+ }
+#else
+ #ifndef RAD_DEBUG
+ rReleaseWarningMsg( false, "Current memory usage for loading bar exceeds 100%!" );
+ #endif
+#endif // LOADING_BAR_FE_EXPLOSION
+ }
+ }
+
+ // flicker loading bar flame
+ //
+ const unsigned int LOADING_BAR_FIRE_TIME = 50; // in msec
+ m_elapsedFireTime += param1;
+ if( m_elapsedFireTime > LOADING_BAR_FIRE_TIME )
+ {
+ rAssert( m_loadingBar.m_pImage != NULL );
+ m_loadingBar.m_pImage->SetIndex( 1 - m_loadingBar.m_pImage->GetIndex() );
+
+ m_elapsedFireTime %= LOADING_BAR_FIRE_TIME;
+ }
+ }
+
+ break;
+ }
+ case GUI_MSG_LOAD_RESOURCES:
+ {
+ this->LoadResources();
+
+#ifdef RAD_XBOX
+ m_startingMemoryAvailable = Memory::GetTotalMemoryFree();
+#else
+ m_startingMemoryAvailable = GetTotalMemoryFreeInAllHeaps();
+#endif
+ rReleasePrintf( "Starting Memory Available = %.2f MB\n", (float)m_startingMemoryAvailable / MB );
+
+#ifdef RAD_WIN32
+ GetLoadingManager()->ResetRequestsProcessed();
+#endif
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+void
+CGuiScreenLoadingFE::LoadResources()
+{
+#ifdef ENABLE_DYNA_LOADED_RESOURCES
+ if( m_itchyAndScratchy != NULL )
+ {
+ m_itchyAndScratchy->SetDrawable( NULL );
+ }
+
+ GameMemoryAllocator heapAllocator = GMA_DEFAULT;
+
+ ContextEnum nextContext = GetGameFlow()->GetNextContext();
+ switch( nextContext )
+ {
+ case CONTEXT_FRONTEND:
+ {
+ heapAllocator = GMA_LEVEL_MOVIE;
+
+ break;
+ }
+ case CONTEXT_LOADING_GAMEPLAY:
+ case CONTEXT_LOADING_DEMO:
+ {
+ heapAllocator = GMA_LEVEL_OTHER;
+
+ break;
+ }
+ case CONTEXT_LOADING_SUPERSPRINT:
+ case CONTEXT_SUPERSPRINT_FE:
+ {
+ heapAllocator = GMA_LEVEL_HUD;
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ rAssert( heapAllocator != GMA_DEFAULT );
+
+ GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D,
+ LOADING_FE_PURE3D_FILE,
+ heapAllocator,
+ LOADING_FE_INVENTORY,
+ LOADING_FE_INVENTORY,
+ this );
+#endif
+}
+
+void
+CGuiScreenLoadingFE::OnProcessRequestsComplete( void* pUserData )
+{
+ if( m_itchyAndScratchy != NULL )
+ {
+ // push and select inventory section for searching
+ //
+ p3d::inventory->PushSection();
+ p3d::inventory->SelectSection( LOADING_FE_INVENTORY );
+ bool currentSectionOnly = p3d::inventory->GetCurrentSectionOnly();
+ p3d::inventory->SetCurrentSectionOnly( true );
+
+ // search for drawable, camera, and multicontroller, and assign
+ // them to the itchy & scratchy pure3d object
+ //
+ tDrawable* drawable = p3d::find<tDrawable>( LOADING_FE_DRAWABLE );
+ m_itchyAndScratchy->SetDrawable( drawable );
+
+ tCamera* camera = p3d::find<tCamera>( LOADING_FE_CAMERA );
+ m_itchyAndScratchy->SetCamera( camera );
+
+ tMultiController* multiController = p3d::find<tMultiController>( LOADING_FE_MULTICONTROLLER );
+ m_itchyAndScratchy->SetMultiController( multiController );
+
+ // pop inventory section and restore states
+ //
+ p3d::inventory->SetCurrentSectionOnly( currentSectionOnly );
+ p3d::inventory->PopSection();
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenLoadingFE::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLoadingFE::InitIntro()
+{
+ RenderLayer* levelLayer = GetRenderManager()->mpLayer( RenderEnums::LevelSlot );
+ if( levelLayer != NULL )
+ {
+ levelLayer->Freeze();
+ }
+
+ m_loadingBar.SetValue( 1.0f );
+
+ // reset current memory usage
+ //
+ m_currentMemoryUsage = 0.0f;
+
+ // hide loading bar by default
+ //
+ rAssert( m_loadingBarGroup != NULL );
+ m_loadingBarGroup->SetVisible( false );
+
+ // hide explosion overlay
+ //
+ if( m_explosionLayer != NULL && m_explosion != NULL )
+ {
+ m_explosionLayer->SetVisible( false );
+ m_explosion->SetVisible( true );
+
+ m_elapsedExplosionTime = 0;
+ }
+}
+
+//===========================================================================
+// CGuiScreenLoadingFE::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLoadingFE::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenLoadingFE::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLoadingFE::InitOutro()
+{
+ RenderLayer* levelLayer = GetRenderManager()->mpLayer( RenderEnums::LevelSlot );
+ if( levelLayer != NULL && levelLayer->IsFrozen() )
+ {
+ levelLayer->Thaw();
+ }
+
+#ifdef ENABLE_DYNA_LOADED_RESOURCES
+ p3d::pddi->DrawSync();
+
+ if( m_itchyAndScratchy != NULL )
+ {
+ m_itchyAndScratchy->SetDrawable( NULL );
+ m_itchyAndScratchy->SetCamera( NULL );
+ m_itchyAndScratchy->SetMultiController( NULL );
+ }
+
+ p3d::inventory->RemoveSectionElements( LOADING_FE_INVENTORY );
+#endif
+
+ rReleasePrintf( "Final memory usage value for loading bar = %.3f\n", m_currentMemoryUsage );
+ m_loadingBar.SetValue( 0.0f );
+
+ // reset loading text animation
+ //
+ m_elapsedTime = 0;
+ rAssert( m_loadingText != NULL );
+ m_loadingText->SetIndex( 0 );
+
+ m_elapsedFireTime = 0;
+
+ GetSoundManager()->ResetDucking();
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+float
+CGuiScreenLoadingFE::GetCurrentMemoryUsage( ContextEnum currentContext ) const
+{
+ float currentMemoryUsage = 0.0f;
+
+#ifdef RAD_XBOX
+ int totalMemoryFree = Memory::GetTotalMemoryFree();
+#else
+ int totalMemoryFree = GetTotalMemoryFreeInAllHeaps();
+#endif
+
+ if( totalMemoryFree > 0 )
+ {
+ switch( currentContext )
+ {
+ case CONTEXT_LOADING_GAMEPLAY:
+ {
+ currentMemoryUsage = (m_startingMemoryAvailable - totalMemoryFree) / TOTAL_INGAME_MEMORY_USAGE;
+
+ break;
+ }
+ case CONTEXT_LOADING_DEMO:
+ {
+ currentMemoryUsage = (m_startingMemoryAvailable - totalMemoryFree) / TOTAL_DEMO_MEMORY_USAGE;
+
+ break;
+ }
+ case CONTEXT_LOADING_SUPERSPRINT:
+ {
+#ifndef RAD_WIN32
+ currentMemoryUsage = (m_startingMemoryAvailable - totalMemoryFree) / TOTAL_SUPERSPRINT_MEMORY_USAGE;
+#else
+ // this sucks but i just want to finish it.
+ float memUsage = float( GetLoadingManager()->GetNumRequestsProcessed() ) / TOTAL_SUPERSPRINT_FILES;
+ currentMemoryUsage = m_currentMemoryUsage;
+ if( memUsage - currentMemoryUsage < LOAD_MIN_SPEED )
+ {
+ currentMemoryUsage = memUsage;
+ }
+ else
+ {
+ float delta = (memUsage - currentMemoryUsage) / LOAD_BLEND_FACTOR;
+ currentMemoryUsage += delta > LOAD_MIN_SPEED ? delta : LOAD_MIN_SPEED;
+ }
+#endif
+ break;
+ }
+ case CONTEXT_FRONTEND:
+ {
+ currentMemoryUsage = (m_startingMemoryAvailable - totalMemoryFree) / TOTAL_FE_MEMORY_USAGE;
+
+ break;
+ }
+ default:
+ {
+ rWarningMsg( false, "Invalid context!" );
+
+ break;
+ }
+ }
+ }
+ else
+ {
+ rWarningMsg( false, "Why is total memory free negative??" );
+ }
+
+ return currentMemoryUsage;
+}
+
diff --git a/game/code/presentation/gui/backend/guiscreenloadingfe.h b/game/code/presentation/gui/backend/guiscreenloadingfe.h
new file mode 100644
index 0000000..3800810
--- /dev/null
+++ b/game/code/presentation/gui/backend/guiscreenloadingfe.h
@@ -0,0 +1,79 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLoadingFE
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENLOADINGFE_H
+#define GUISCREENLOADINGFE_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <presentation/gui/utility/slider.h>
+
+#include <contexts/contextenum.h>
+#include <loading/loadingmanager.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class Text;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenLoadingFE : public CGuiScreen,
+ public LoadingManager::ProcessRequestsCallback
+{
+public:
+ CGuiScreenLoadingFE( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenLoadingFE();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ void LoadResources();
+ virtual void OnProcessRequestsComplete( void* pUserData );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ float GetCurrentMemoryUsage( ContextEnum currentContext ) const;
+
+ Scrooby::Text* m_loadingText;
+ Scrooby::Pure3dObject* m_itchyAndScratchy;
+
+ unsigned int m_elapsedTime;
+
+ Scrooby::Group* m_loadingBarGroup;
+ Slider m_loadingBar;
+ float m_currentMemoryUsage; // in percent
+ int m_startingMemoryAvailable; // in bytes
+ unsigned int m_elapsedFireTime;
+
+ Scrooby::Layer* m_explosionLayer;
+ Scrooby::Polygon* m_explosion;
+ unsigned int m_elapsedExplosionTime;
+
+};
+
+#endif // GUISCREENLOADINGFE_H
diff --git a/game/code/presentation/gui/bootup/allbootup.cpp b/game/code/presentation/gui/bootup/allbootup.cpp
new file mode 100644
index 0000000..4fffd7c
--- /dev/null
+++ b/game/code/presentation/gui/bootup/allbootup.cpp
@@ -0,0 +1,5 @@
+#include <presentation/gui/bootup/guimanagerbootup.cpp>
+#include <presentation/gui/bootup/guimanagerlanguage.cpp>
+#include <presentation/gui/bootup/guiscreenbootupload.cpp>
+#include <presentation/gui/bootup/guiscreenlicense.cpp>
+#include <presentation/gui/bootup/guiscreenlanguage.cpp>
diff --git a/game/code/presentation/gui/bootup/guimanagerbootup.cpp b/game/code/presentation/gui/bootup/guimanagerbootup.cpp
new file mode 100644
index 0000000..b42d853
--- /dev/null
+++ b/game/code/presentation/gui/bootup/guimanagerbootup.cpp
@@ -0,0 +1,403 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiManagerBootUp
+//
+// Description: Implementation of the CGuiManagerBootUp class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/15 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/bootup/guimanagerbootup.h>
+#include <presentation/gui/bootup/guiscreenbootupload.h>
+#include <presentation/gui/bootup/guiscreenlicense.h>
+#include <presentation/gui/bootup/guiscreenlanguage.h>
+#include <presentation/gui/frontend/guiscreenloadgame.h>
+#include <presentation/gui/guiscreenmemcardcheck.h>
+#include <presentation/gui/guiscreenmessage.h>
+#include <presentation/gui/guiscreenprompt.h>
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/guiwindow.h> // for window IDs
+
+#include <contexts/bootupcontext.h>
+#include <input/inputmanager.h>
+#include <memory/srrmemory.h>
+
+#ifdef RAD_PS2
+ #include <main/ps2platform.h>
+#endif
+
+#include <raddebug.hpp>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+#ifdef RAD_PS2
+ #ifndef PAL
+ #define ENABLE_PROGRESSIVE_SCAN_PROMPT
+ #endif
+#endif
+
+#ifdef RAD_PS2
+ #define ENABLE_MEMCARD_CHECK_DURING_BOOTUP
+#endif
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiManagerBootUp::CGuiManagerBootUp
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiManagerBootUp::CGuiManagerBootUp
+(
+ Scrooby::Project* pProject,
+ CGuiEntity* pParent
+)
+: CGuiManager( pProject, pParent )
+{
+ if( CommandLineOptions::Get( CLO_SKIP_MEMCHECK ) )
+ {
+ s_memcardCheckState = MEM_CARD_CHECK_COMPLETED;
+ }
+
+#ifdef RAD_DEMO
+ // no memory card checking for demos
+ //
+ s_memcardCheckState = MEM_CARD_CHECK_COMPLETED;
+#endif
+}
+
+
+//===========================================================================
+// CGuiManagerBootUp::~CGuiManagerBootUp
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiManagerBootUp::~CGuiManagerBootUp()
+{
+ for( int i = 0; i < CGuiWindow::NUM_GUI_WINDOW_IDS; i++ )
+ {
+ if( m_windows[ i ] != NULL )
+ {
+ delete m_windows[ i ];
+ m_windows[ i ] = NULL;
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiManagerBootUp::Populate
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiManagerBootUp::Populate()
+{
+MEMTRACK_PUSH_GROUP( "CGuiManagerBootUp" );
+ Scrooby::Screen* pScroobyScreen;
+ CGuiScreen* pScreen;
+
+#ifdef RAD_PS2
+ pScroobyScreen = m_pScroobyProject->GetScreen( "BootupLoad" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenBootupLoad( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_BOOTUP_LOAD, pScreen );
+ }
+#endif
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "License" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenLicense( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LICENSE, pScreen );
+ }
+/*
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Language" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenLanguage( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LANGUAGE, pScreen );
+ }
+*/
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MemCardCheck" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMemCardCheck( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD_CHECK, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Blank" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenAutoLoad( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_AUTO_LOAD, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Message" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMessage( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_GENERIC_MESSAGE, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Prompt" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPrompt( pScroobyScreen, this,
+ CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT );
+
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "ErrorPrompt" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPrompt( pScroobyScreen, this,
+ CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT );
+
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT, pScreen );
+ }
+MEMTRACK_POP_GROUP("CGuiManagerBootUp");
+}
+
+void
+CGuiManagerBootUp::Start( CGuiWindow::eGuiWindowID initialWindow )
+{
+ rAssert( m_state == GUI_FE_UNINITIALIZED );
+
+ if( initialWindow != CGuiWindow::GUI_WINDOW_ID_UNDEFINED )
+ {
+ m_bootupScreenQueue.push( initialWindow );
+ }
+
+#ifdef ENABLE_PROGRESSIVE_SCAN_PROMPT
+ // add progressive scan screen to bootup screen queue
+ //
+ if( GetInputManager()->IsProScanButtonsPressed() )
+ {
+ m_bootupScreenQueue.push( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT );
+ }
+#endif
+
+#ifdef ENABLE_MEMCARD_CHECK_DURING_BOOTUP
+ // add memcard checking screen to bootup screen queue
+ //
+ if( s_memcardCheckState == MEM_CARD_CHECK_NOT_DONE )
+ {
+ m_bootupScreenQueue.push( CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD_CHECK );
+ }
+#endif
+
+#ifdef RAD_PS2
+ // for PS2 only, start off w/ a loading screen
+ //
+ m_bootupScreenQueue.push( CGuiWindow::GUI_SCREEN_ID_BOOTUP_LOAD );
+#endif
+
+ // add license screen to bootup screen queue
+ //
+ m_bootupScreenQueue.push( CGuiWindow::GUI_SCREEN_ID_LICENSE );
+
+
+ // alright, letz bring up the first screen of the game!!
+ //
+ m_nextScreen = this->PopNextScreenInQueue();
+ if( m_nextScreen == CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT )
+ {
+ // special case for progressive scan prompt
+ //
+ CGuiMenuPrompt::ePromptResponse responses[] =
+ {
+ CGuiMenuPrompt::RESPONSE_YES,
+ CGuiMenuPrompt::RESPONSE_NO
+ };
+
+ CGuiScreenPrompt::Display( PROMPT_DISPLAY_PROGRESSIVE_SCAN, this, 2, responses );
+ CGuiScreenPrompt::EnableDefaultToNo( false );
+ }
+
+ m_state = GUI_FE_CHANGING_SCREENS; // must be set before calling GotoScreen()
+
+ CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) );
+ rAssert( nextScreen != NULL );
+ m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this );
+}
+
+//===========================================================================
+// CGuiManagerBootUp::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiManagerBootUp::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ switch( message )
+ {
+ case GUI_MSG_QUIT_BOOTUP:
+ {
+ rAssert( GUI_FE_SCREEN_RUNNING == m_state );
+
+ rAssertMsg( m_bootupScreenQueue.empty(),
+ "Why are we quitting when there's still screens in the bootup queue??" );
+
+ m_state = GUI_FE_SHUTTING_DOWN;
+
+#ifdef RAD_WIN32
+ GetBootupContext()->LoadConfig();
+#endif
+
+ // Tell the current screen to shut down.
+ //
+ this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT );
+
+ break;
+ }
+ case GUI_MSG_WINDOW_FINISHED:
+ {
+ if( GUI_FE_CHANGING_SCREENS == m_state )
+ {
+ m_currentScreen = m_nextScreen;
+ CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) );
+ rAssert( nextScreen != NULL );
+ m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this );
+ }
+ else if( GUI_FE_SHUTTING_DOWN == m_state )
+ {
+ m_state = GUI_FE_TERMINATED;
+
+ // start intro movies
+ //
+ GetBootupContext()->StartMovies();
+ }
+
+ break;
+ }
+ case GUI_MSG_MENU_PROMPT_RESPONSE:
+ {
+ rAssert( param1 == PROMPT_DISPLAY_PROGRESSIVE_SCAN );
+
+ if( param2 == CGuiMenuPrompt::RESPONSE_YES )
+ {
+ // enable progressive scan
+ //
+#ifdef RAD_PS2
+ PS2Platform::GetInstance()->SetProgressiveMode( true );
+#endif
+ }
+
+ // follow-thru
+ //
+ }
+ case GUI_MSG_BOOTUP_LOAD_COMPLETED:
+ case GUI_MSG_LANGUAGE_SELECTION_DONE:
+ case GUI_MSG_MEMCARD_CHECK_COMPLETED:
+ {
+ CGuiWindow::eGuiWindowID nextScreen = this->PopNextScreenInQueue();
+
+ if( nextScreen == CGuiWindow::GUI_SCREEN_ID_BOOTUP_LOAD &&
+ GetGuiSystem()->GetCurrentState() == CGuiSystem::BOOTUP_ACTIVE )
+ {
+ // FE is already loaded, no need to display extra loading screen
+ //
+ nextScreen = this->PopNextScreenInQueue(); // pop off next screen in queue
+ }
+
+ if( nextScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED )
+ {
+ CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN,
+ nextScreen,
+ CLEAR_WINDOW_HISTORY );
+ }
+ else
+ {
+ this->HandleMessage( GUI_MSG_QUIT_BOOTUP );
+ }
+
+ break;
+ }
+ default:
+ {
+ if( m_state != GUI_FE_UNINITIALIZED &&
+ m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED )
+ {
+ // Send the messages down to the current screen.
+ //
+ CGuiWindow* pScreen = this->FindWindowByID( m_currentScreen );
+ rAssert( pScreen );
+
+ pScreen->HandleMessage( message, param1, param2 );
+ }
+ }
+ }
+
+ // propogate message up the hierarchy
+ CGuiManager::HandleMessage( message, param1, param2 );
+}
+
+//===========================================================================
+// Private Member Functions
+//===========================================================================
+
+CGuiWindow::eGuiWindowID
+CGuiManagerBootUp::PopNextScreenInQueue()
+{
+ CGuiWindow::eGuiWindowID nextScreen = CGuiWindow::GUI_WINDOW_ID_UNDEFINED;
+
+ if( !m_bootupScreenQueue.empty() )
+ {
+ nextScreen = m_bootupScreenQueue.front();
+ m_bootupScreenQueue.pop();
+
+ if( nextScreen == CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD_CHECK )
+ {
+ s_memcardCheckState = MEM_CARD_CHECK_IN_PROGRESS;
+ }
+ }
+
+ return nextScreen;
+}
+
diff --git a/game/code/presentation/gui/bootup/guimanagerbootup.h b/game/code/presentation/gui/bootup/guimanagerbootup.h
new file mode 100644
index 0000000..a307206
--- /dev/null
+++ b/game/code/presentation/gui/bootup/guimanagerbootup.h
@@ -0,0 +1,66 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiManagerBootUp
+//
+// Description: Interface for the CGuiManagerBootUp class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/15 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUIMANAGERBOOTUP_H
+#define GUIMANAGERBOOTUP_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guimanager.h>
+#include <memory\srrmemory.h> // Needed for my STL allocations to go on the right heap
+
+#include <queue>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiManagerBootUp : public CGuiManager
+{
+public:
+ CGuiManagerBootUp( Scrooby::Project* pProject, CGuiEntity* pParent );
+ virtual ~CGuiManagerBootUp();
+
+ virtual void Populate();
+ virtual void Start( CGuiWindow::eGuiWindowID initialWindow = CGuiWindow::GUI_WINDOW_ID_UNDEFINED );
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+private:
+
+ //---------------------------------------------------------------------
+ // Private Functions
+ //---------------------------------------------------------------------
+
+ // No copying or assignment. Declare but don't define.
+ //
+ CGuiManagerBootUp( const CGuiManagerBootUp& );
+ CGuiManagerBootUp& operator= ( const CGuiManagerBootUp& );
+
+ CGuiWindow::eGuiWindowID PopNextScreenInQueue();
+
+ //---------------------------------------------------------------------
+ // Private Data
+ //---------------------------------------------------------------------
+ typedef std::deque< CGuiWindow::eGuiWindowID, s2alloc<CGuiWindow::eGuiWindowID> > WindowIDVector;
+ std::queue<CGuiWindow::eGuiWindowID, WindowIDVector> m_bootupScreenQueue;
+
+};
+
+#endif // GUIMANAGERBOOTUP_H
diff --git a/game/code/presentation/gui/bootup/guimanagerlanguage.cpp b/game/code/presentation/gui/bootup/guimanagerlanguage.cpp
new file mode 100644
index 0000000..b70cb16
--- /dev/null
+++ b/game/code/presentation/gui/bootup/guimanagerlanguage.cpp
@@ -0,0 +1,287 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiManagerLanguage
+//
+// Description: Implementation of the CGuiManagerLanguage class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/07/08 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/bootup/guimanagerlanguage.h>
+#include <presentation/gui/bootup/guiscreenlanguage.h>
+#include <presentation/gui/guiwindow.h> // for window IDs
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/language.h>
+
+#include <memory/srrmemory.h>
+#include <render/rendermanager/rendermanager.h>
+#include <render/rendermanager/renderlayer.h>
+
+#include <raddebug.hpp>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiManagerLanguage::CGuiManagerLanguage
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiManagerLanguage::CGuiManagerLanguage
+(
+ Scrooby::Project* pProject,
+ CGuiEntity* pParent
+)
+: CGuiManager( pProject, pParent )
+{
+}
+
+
+//===========================================================================
+// CGuiManagerLanguage::~CGuiManagerLanguage
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiManagerLanguage::~CGuiManagerLanguage()
+{
+ for( int i = 0; i < CGuiWindow::NUM_GUI_WINDOW_IDS; i++ )
+ {
+ if( m_windows[ i ] != NULL )
+ {
+ delete m_windows[ i ];
+ m_windows[ i ] = NULL;
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiManagerLanguage::Populate
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiManagerLanguage::Populate()
+{
+MEMTRACK_PUSH_GROUP( "CGuiManagerLanguage" );
+ Scrooby::Screen* pScroobyScreen;
+ CGuiScreen* pScreen;
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Language" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenLanguage( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LANGUAGE, pScreen );
+ }
+MEMTRACK_POP_GROUP("CGuiManagerLanguage");
+}
+
+void
+CGuiManagerLanguage::Start( CGuiWindow::eGuiWindowID initialWindow )
+{
+ rAssert( m_state == GUI_FE_UNINITIALIZED );
+
+ rAssertMsg( initialWindow == CGuiWindow::GUI_WINDOW_ID_UNDEFINED,
+ "Can't specify another initial window! Not supported by this manager." );
+
+ bool isLanguageSupported = this->CheckLanguage();
+
+ if( !isLanguageSupported || CommandLineOptions::Get( CLO_LANG_PROMPT ) )
+ {
+ m_nextScreen = CGuiWindow::GUI_SCREEN_ID_LANGUAGE;
+
+ m_state = GUI_FE_CHANGING_SCREENS; // must be set before calling GotoScreen()
+
+ CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) );
+ rAssert( nextScreen != NULL );
+ m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this );
+
+ // thaw frontend render layer
+ //
+ GetRenderManager()->mpLayer(RenderEnums::GUI)->Thaw();
+ }
+ else
+ {
+ m_state = GUI_FE_TERMINATED;
+
+ GetGuiSystem()->HandleMessage( GUI_MSG_INIT_BOOTUP );
+ }
+}
+
+//===========================================================================
+// CGuiManagerLanguage::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiManagerLanguage::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ switch( message )
+ {
+ case GUI_MSG_LANGUAGE_SELECTION_DONE:
+ {
+ rAssert( GUI_FE_SCREEN_RUNNING == m_state );
+
+ m_state = GUI_FE_SHUTTING_DOWN;
+
+ // Tell the current screen to shut down.
+ //
+ this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT );
+
+ break;
+ }
+ case GUI_MSG_WINDOW_FINISHED:
+ {
+ if( GUI_FE_CHANGING_SCREENS == m_state )
+ {
+ m_currentScreen = m_nextScreen;
+ CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) );
+ rAssert( nextScreen != NULL );
+ m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this );
+ }
+ else if( GUI_FE_SHUTTING_DOWN == m_state )
+ {
+ m_state = GUI_FE_TERMINATED;
+
+ GetGuiSystem()->HandleMessage( GUI_MSG_INIT_BOOTUP );
+ }
+
+ break;
+ }
+ default:
+ {
+ if( m_state != GUI_FE_UNINITIALIZED &&
+ m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED )
+ {
+ // Send the messages down to the current screen.
+ //
+ CGuiWindow* pScreen = this->FindWindowByID( m_currentScreen );
+ rAssert( pScreen );
+
+ pScreen->HandleMessage( message, param1, param2 );
+ }
+ }
+ }
+
+ // propogate message up the hierarchy
+ CGuiManager::HandleMessage( message, param1, param2 );
+}
+
+//===========================================================================
+// Private Member Functions
+//===========================================================================
+
+bool
+CGuiManagerLanguage::CheckLanguage()
+{
+ bool isLanguageSupported = true;
+
+ switch( Language::GetHardwareLanguage() )
+ {
+ case Language::ENGLISH:
+ {
+ CGuiTextBible::SetCurrentLanguage( Scrooby::XL_ENGLISH );
+
+ rReleasePrintf( "Localization language automatically set to: ENGLISH\n" );
+
+ break;
+ }
+ case Language::FRENCH:
+ {
+ CGuiTextBible::SetCurrentLanguage( Scrooby::XL_FRENCH );
+
+ rReleasePrintf( "Localization language automatically set to: FRENCH\n" );
+
+ break;
+ }
+ case Language::GERMAN:
+ {
+ CGuiTextBible::SetCurrentLanguage( Scrooby::XL_GERMAN );
+
+ rReleasePrintf( "Localization language automatically set to: GERMAN\n" );
+
+ break;
+ }
+/*
+ case Language::ITALIAN:
+ {
+ CGuiTextBible::SetCurrentLanguage( Scrooby::XL_ITALIAN );
+
+ rReleasePrintf( "Localization language automatically set to: ITALIAN\n" );
+
+ break;
+ }
+*/
+#ifndef RAD_GAMECUBE
+ case Language::SPANISH:
+ {
+ CGuiTextBible::SetCurrentLanguage( Scrooby::XL_SPANISH );
+
+ rReleasePrintf( "Localization language automatically set to: SPANISH\n" );
+
+ break;
+ }
+#endif // !RAD_GAMECUBE
+ default:
+ {
+#ifdef RAD_XBOX
+ // default to English, if unsupported language detected
+ //
+ CGuiTextBible::SetCurrentLanguage( Scrooby::XL_ENGLISH );
+#else
+ isLanguageSupported = false;
+#endif
+ rReleasePrintf( "Unsupported hardware language detected.\n" );
+
+ break;
+ }
+ }
+
+ return isLanguageSupported;
+}
+
diff --git a/game/code/presentation/gui/bootup/guimanagerlanguage.h b/game/code/presentation/gui/bootup/guimanagerlanguage.h
new file mode 100644
index 0000000..d34b227
--- /dev/null
+++ b/game/code/presentation/gui/bootup/guimanagerlanguage.h
@@ -0,0 +1,60 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiManagerLanguage
+//
+// Description: Interface for the CGuiManagerLanguage class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/07/08 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUIMANAGERLANGUAGE_H
+#define GUIMANAGERLANGUAGE_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guimanager.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiManagerLanguage : public CGuiManager
+{
+public:
+ CGuiManagerLanguage( Scrooby::Project* pProject, CGuiEntity* pParent );
+ virtual ~CGuiManagerLanguage();
+
+ virtual void Populate();
+ virtual void Start( CGuiWindow::eGuiWindowID initialWindow = CGuiWindow::GUI_WINDOW_ID_UNDEFINED );
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+private:
+ //---------------------------------------------------------------------
+ // Private Functions
+ //---------------------------------------------------------------------
+
+ // No copying or assignment. Declare but don't define.
+ //
+ CGuiManagerLanguage( const CGuiManagerLanguage& );
+ CGuiManagerLanguage& operator= ( const CGuiManagerLanguage& );
+
+ bool CheckLanguage();
+
+ //---------------------------------------------------------------------
+ // Private Data
+ //---------------------------------------------------------------------
+
+};
+
+#endif // GUIMANAGERLANGUAGE_H
diff --git a/game/code/presentation/gui/bootup/guiscreenbootupload.cpp b/game/code/presentation/gui/bootup/guiscreenbootupload.cpp
new file mode 100644
index 0000000..2c4223c
--- /dev/null
+++ b/game/code/presentation/gui/bootup/guiscreenbootupload.cpp
@@ -0,0 +1,200 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenBootupLoad
+//
+// Description: Implementation of the CGuiScreenBootupLoad class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/bootup/guiscreenbootupload.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <presentation/gui/guisystem.h>
+
+#include <raddebug.hpp> // Foundation
+
+#include <screen.h>
+#include <page.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenBootupLoad::CGuiScreenBootupLoad
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenBootupLoad::CGuiScreenBootupLoad
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_BOOTUP_LOAD ),
+ m_loadingText( NULL ),
+ m_elapsedIdleTime( 0 )
+{
+ // get loading text
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "LoadingText" );
+ if( pPage != NULL )
+ {
+ m_loadingText = pPage->GetText( "Loading" );
+ rAssert( m_loadingText != NULL );
+ m_loadingText->SetVisible( false ); // hide by default
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenBootupLoad::~CGuiScreenBootupLoad
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenBootupLoad::~CGuiScreenBootupLoad()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenBootupLoad::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenBootupLoad::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ if( message == GUI_MSG_UPDATE )
+ {
+ m_elapsedIdleTime += param1;
+
+ if( m_loadingText != NULL )
+ {
+ // blink loading text if idling here on this screen to satisfy
+ // TRC/TCR requirements
+ //
+ const unsigned int BLINKING_PERIOD = 250;
+ bool isBlinked = GuiSFX::Blink( m_loadingText,
+ static_cast<float>( m_elapsedIdleTime ),
+ static_cast<float>( BLINKING_PERIOD ) );
+ if( isBlinked )
+ {
+ m_elapsedIdleTime %= BLINKING_PERIOD;
+ }
+ }
+
+ if( GetGuiSystem()->GetCurrentState() == CGuiSystem::BOOTUP_ACTIVE )
+ {
+ m_pParent->HandleMessage( GUI_MSG_BOOTUP_LOAD_COMPLETED );
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenBootupLoad::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenBootupLoad::InitIntro()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenBootupLoad::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenBootupLoad::InitRunning()
+{
+ m_elapsedIdleTime = 0;
+}
+
+
+//===========================================================================
+// CGuiScreenBootupLoad::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenBootupLoad::InitOutro()
+{
+ if( m_loadingText != NULL )
+ {
+ // hide loading text
+ //
+ m_loadingText->SetVisible( false );
+ }
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/bootup/guiscreenbootupload.h b/game/code/presentation/gui/bootup/guiscreenbootupload.h
new file mode 100644
index 0000000..72c8b4f
--- /dev/null
+++ b/game/code/presentation/gui/bootup/guiscreenbootupload.h
@@ -0,0 +1,52 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenBootupLoad
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENBOOTUPLOAD_H
+#define GUISCREENBOOTUPLOAD_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenBootupLoad : public CGuiScreen
+{
+public:
+ CGuiScreenBootupLoad( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenBootupLoad();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ Scrooby::Text* m_loadingText;
+ unsigned int m_elapsedIdleTime;
+
+};
+
+#endif // GUISCREENBOOTUPLOAD_H
diff --git a/game/code/presentation/gui/bootup/guiscreenlanguage.cpp b/game/code/presentation/gui/bootup/guiscreenlanguage.cpp
new file mode 100644
index 0000000..9c18074
--- /dev/null
+++ b/game/code/presentation/gui/bootup/guiscreenlanguage.cpp
@@ -0,0 +1,224 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLanguage
+//
+// Description: Implementation of the CGuiScreenLanguage class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/bootup/guiscreenlanguage.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/gui/guiscreenmessage.h>
+
+#include <raddebug.hpp> // Foundation
+
+#include <app.h>
+#include <group.h>
+#include <page.h>
+#include <screen.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenLanguage::CGuiScreenLanguage
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLanguage::CGuiScreenLanguage
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+:
+ CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_LANGUAGE ),
+ m_pMenu( NULL )
+{
+ // retrieve Scrooby drawing elements
+ //
+ rAssert( m_pScroobyScreen != NULL );
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Language" );
+ rAssert( pPage != NULL );
+
+ m_pMenu = new CGuiMenu( this, NUM_SRR2_LANGUAGES );
+ rAssert( m_pMenu != NULL );
+
+ Scrooby::Group* menu = pPage->GetGroup( "Menu" );
+ rAssert( menu != NULL );
+
+ for( int i = 0; i < NUM_SRR2_LANGUAGES; i++ )
+ {
+ char name[ 32 ];
+ sprintf( name, "Language%d", i );
+ m_pMenu->AddMenuItem( menu->GetText( name ) );
+ }
+
+#ifdef RAD_GAMECUBE
+ m_pMenu->SetMenuItemEnabled( 3, false, true ); // no Spanish on GC PAL
+#endif // RAD_GAMECUBE
+
+ Scrooby::Page* messageBoxPage = m_pScroobyScreen->GetPage( "MessageBox" );
+ if( messageBoxPage != NULL )
+ {
+ this->AutoScaleFrame( messageBoxPage );
+
+ Scrooby::Sprite* messageIcon = messageBoxPage->GetSprite( "ErrorIcon" );
+ if( messageIcon != NULL )
+ {
+ messageIcon->ResetTransformation();
+ messageIcon->ScaleAboutCenter( MESSAGE_ICON_CORRECTION_SCALE );
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenLanguage::~CGuiScreenLanguage
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLanguage::~CGuiScreenLanguage()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenLanguage::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLanguage::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ rAssert( static_cast<int>( param1 ) < NUM_SRR2_LANGUAGES );
+ CGuiTextBible::SetCurrentLanguage( SRR2_LANGUAGE[ param1 ] );
+
+ m_pParent->HandleMessage( GUI_MSG_LANGUAGE_SELECTION_DONE );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenLanguage::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLanguage::InitIntro()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenLanguage::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLanguage::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenLanguage::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLanguage::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/bootup/guiscreenlanguage.h b/game/code/presentation/gui/bootup/guiscreenlanguage.h
new file mode 100644
index 0000000..c12d928
--- /dev/null
+++ b/game/code/presentation/gui/bootup/guiscreenlanguage.h
@@ -0,0 +1,55 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLanguage
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENLANGUAGE_H
+#define GUISCREENLANGUAGE_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class CGuiMenu;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenLanguage : public CGuiScreen
+{
+public:
+ CGuiScreenLanguage( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenLanguage();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ CGuiMenu* m_pMenu;
+
+};
+
+#endif // GUISCREENLANGUAGE_H
diff --git a/game/code/presentation/gui/bootup/guiscreenlicense.cpp b/game/code/presentation/gui/bootup/guiscreenlicense.cpp
new file mode 100644
index 0000000..e6262e4
--- /dev/null
+++ b/game/code/presentation/gui/bootup/guiscreenlicense.cpp
@@ -0,0 +1,202 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLicense
+//
+// Description: Implementation of the CGuiScreenLicense class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/bootup/guiscreenlicense.h>
+
+#include <contexts/bootupcontext.h>
+
+#include <screen.h>
+#include <page.h>
+#include <group.h>
+
+#include <p3d/utility.hpp>
+#include <p3d/sprite.hpp>
+#include <raddebug.hpp> // Foundation
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const float LICENSE_SCREEN_FADE_TIME = 500.0f;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenLicense::CGuiScreenLicense
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLicense::CGuiScreenLicense
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_LICENSE )
+{
+ // retrieve Scrooby drawing elements
+ //
+ rAssert( m_pScroobyScreen != NULL );
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "License" );
+ rAssert( pPage != NULL );
+
+ // set platform-specific license screen image
+ //
+#ifdef RAD_GAMECUBE
+ tSprite* pSprite = p3d::find<tSprite>( "licenseG.png" );
+#endif
+#ifdef RAD_PS2
+ tSprite* pSprite = p3d::find<tSprite>( "licenseP.png" );
+#endif
+#ifdef RAD_XBOX
+ tSprite* pSprite = p3d::find<tSprite>( "licenseX.png" );
+#endif
+#ifdef RAD_WIN32
+ tSprite* pSprite = p3d::find<tSprite>( "licensePC.png" );
+#endif
+ rAssert( pSprite != NULL );
+
+ Scrooby::Sprite* licenseImage = pPage->GetSprite( "License" );
+ rAssert( licenseImage != NULL );
+ licenseImage->SetRawSprite( pSprite );
+
+ // set fade time for license screen (in milliseconds)
+ //
+ this->SetFadeTime( LICENSE_SCREEN_FADE_TIME );
+
+#ifdef RAD_GAMECUBE
+ // skip screen fade in (on Gamecube only)
+ //
+ this->SetFadeTime( 0.0f );
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenLicense::~CGuiScreenLicense
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLicense::~CGuiScreenLicense()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenLicense::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLicense::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenLicense::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLicense::InitIntro()
+{
+ // start loading sound files
+ //
+ GetBootupContext()->StartLoadingSound();
+}
+
+
+//===========================================================================
+// CGuiScreenLicense::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLicense::InitRunning()
+{
+#ifdef RAD_GAMECUBE
+ // allow screen fade out (on Gamecube only)
+ this->SetFadeTime( LICENSE_SCREEN_FADE_TIME );
+#endif
+
+ GetBootupContext()->ResetLicenseScreenDisplayTime();
+}
+
+
+//===========================================================================
+// CGuiScreenLicense::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLicense::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/bootup/guiscreenlicense.h b/game/code/presentation/gui/bootup/guiscreenlicense.h
new file mode 100644
index 0000000..219c82c
--- /dev/null
+++ b/game/code/presentation/gui/bootup/guiscreenlicense.h
@@ -0,0 +1,48 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLicense
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENLICENSE_H
+#define GUISCREENLICENSE_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenLicense : public CGuiScreen
+{
+public:
+ CGuiScreenLicense( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenLicense();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+};
+
+#endif // GUISCREENLICENSE_H
diff --git a/game/code/presentation/gui/frontend/allfrontend.cpp b/game/code/presentation/gui/frontend/allfrontend.cpp
new file mode 100644
index 0000000..57979b6
--- /dev/null
+++ b/game/code/presentation/gui/frontend/allfrontend.cpp
@@ -0,0 +1,19 @@
+#include <presentation/gui/frontend/guimanagerfrontend.cpp>
+#include <presentation/gui/frontend/guiscreencardgallery.cpp>
+#include <presentation/gui/frontend/guiscreencontroller.cpp>
+#include <presentation/gui/frontend/guiscreenloadgame.cpp>
+#include <presentation/gui/frontend/guiscreenmainmenu.cpp>
+#include <presentation/gui/frontend/guiscreenmissiongallery.cpp>
+#include <presentation/gui/frontend/guiscreenskingallery.cpp>
+#include <presentation/gui/frontend/guiscreenvehiclegallery.cpp>
+//#include <presentation/gui/frontend/guiscreenmultichoosechar.cpp>
+//#include <presentation/gui/frontend/guiscreenmultisetup.cpp>
+#include <presentation/gui/frontend/guiscreenoptions.cpp>
+#include <presentation/gui/frontend/guiscreenplaymovie.cpp>
+#include <presentation/gui/frontend/guiscreenscrapbook.cpp>
+#include <presentation/gui/frontend/guiscreenscrapbookcontents.cpp>
+#include <presentation/gui/frontend/guiscreenscrapbookstats.cpp>
+#include <presentation/gui/frontend/guiscreensound.cpp>
+#include <presentation/gui/frontend/guiscreensplash.cpp>
+#include <presentation/gui/frontend/guiscreenviewcredits.cpp>
+#include <presentation/gui/frontend/guiscreenviewmovies.cpp>
diff --git a/game/code/presentation/gui/frontend/guimanagerfrontend.cpp b/game/code/presentation/gui/frontend/guimanagerfrontend.cpp
new file mode 100644
index 0000000..1a7e146
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guimanagerfrontend.cpp
@@ -0,0 +1,829 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiManagerFrontEnd
+//
+// Description: Implementation of the CGuiManagerFrontEnd class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/09/21 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guimanagerfrontend.h>
+#include <presentation/gui/guiwindow.h> // for window IDs
+#include <presentation/gui/guisystem.h>
+
+#include <presentation/gui/guiscreenmessage.h>
+#include <presentation/gui/guiscreenprompt.h>
+#include <presentation/gui/guiscreenmemorycard.h>
+#include <presentation/gui/guiscreenmemcardcheck.h>
+
+#include <presentation/gui/frontend/guiscreensplash.h>
+#include <presentation/gui/frontend/guiscreenmainmenu.h>
+#include <presentation/gui/frontend/guiscreenloadgame.h>
+#include <presentation/gui/frontend/guiscreenscrapbook.h>
+#include <presentation/gui/frontend/guiscreenscrapbookcontents.h>
+#include <presentation/gui/frontend/guiscreenscrapbookstats.h>
+#include <presentation/gui/frontend/guiscreencardgallery.h>
+#include <presentation/gui/frontend/guiscreenmissiongallery.h>
+#include <presentation/gui/frontend/guiscreenskingallery.h>
+#include <presentation/gui/frontend/guiscreenvehiclegallery.h>
+#include <presentation/gui/frontend/guiscreenmultisetup.h>
+#include <presentation/gui/frontend/guiscreenmultichoosechar.h>
+#include <presentation/gui/frontend/guiscreenoptions.h>
+#ifdef RAD_WIN32
+#include <presentation/gui/frontend/guiscreencontrollerWin32.h>
+#else
+#include <presentation/gui/frontend/guiscreencontroller.h>
+#endif
+#include <presentation/gui/frontend/guiscreensound.h>
+#include <presentation/gui/frontend/guiscreenviewcredits.h>
+#include <presentation/gui/frontend/guiscreenviewmovies.h>
+#include <presentation/gui/frontend/guiscreenplaymovie.h>
+#include <presentation/gui/frontend/guiscreendisplay.h>
+
+#include <presentation/presentation.h>
+#include <presentation/fmvplayer/fmvplayer.h>
+#include <presentation/fmvplayer/fmvuserinputhandler.h>
+
+#include <data/gamedatamanager.h>
+#include <events/eventmanager.h>
+#include <gameflow/gameflow.h>
+#include <input/inputmanager.h>
+#include <mission/gameplaymanager.h>
+//#include <mission/headtoheadmanager.h>
+#include <mission/missionmanager.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <supersprint/supersprintmanager.h>
+#include <main/platform.h>
+#include <main/game.h>
+#include <sound/soundmanager.h>
+
+#include <memory/srrmemory.h>
+
+#include <raddebug.hpp> // Foundation
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+
+#define SHOW_SPLASH_SCREEN
+
+#ifdef RAD_RELEASE
+ #ifndef RAD_E3
+ #define SHOW_INTRO_MOVIE
+ #endif
+#endif
+
+//#define SKIP_INTRO_MOVIE_IF_GAME_LOADED
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiManagerFrontEnd::CGuiManagerFrontEnd
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiManagerFrontEnd::CGuiManagerFrontEnd
+(
+ Scrooby::Project* pProject,
+ CGuiEntity* pParent
+)
+: CGuiManager( pProject, pParent ),
+ m_levelNum( 1 ),
+ m_disconnectedController(-1),
+ m_quittingToDemo( false ),
+ m_controllerPromptShown ( false ),
+ m_quittingToMiniGame( false ),
+ m_isControllerReconnected( false ),
+ m_wasFMVInputHandlerEnabled( false )
+{
+#ifdef RAD_WIN32
+ m_quittingGame = false;
+#endif
+}
+
+
+//===========================================================================
+// CGuiManagerFrontEnd::~CGuiManagerFrontEnd
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiManagerFrontEnd::~CGuiManagerFrontEnd()
+{
+}
+
+
+
+//===========================================================================
+// CGuiManagerFrontEnd::Populate
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiManagerFrontEnd::Populate()
+{
+MEMTRACK_PUSH_GROUP( "CGUIManagerFrontEnd" );
+ HeapMgr()->PushHeap( GMA_LEVEL_FE );
+
+ Scrooby::Screen* pScroobyScreen;
+ CGuiScreen* pScreen;
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Message3D" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMessage( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_GENERIC_MESSAGE, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Prompt3D" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPrompt( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "ErrorPrompt3D" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPrompt( pScroobyScreen, this,
+ CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT );
+
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MemoryCard3D" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMemoryCard( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Splash" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenSplash( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SPLASH, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MemCardCheck" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMemCardCheck( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD_CHECK, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MainMenu" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenIntroTransition( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_INTRO_TRANSITION, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MainMenu" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMainMenu( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MAIN_MENU, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "LoadGame" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenLoadGame( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LOAD_GAME, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Blank" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenAutoLoad( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_AUTO_LOAD, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "ScrapBook" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenScrapBook( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SCRAP_BOOK, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "ScrapBookContents" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenScrapBookContents( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "ScrapBookStats" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenScrapBookStats( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SCRAP_BOOK_STATS, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "CardGallery" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenCardGallery( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_CARD_GALLERY, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MissionGallery" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMissionGallery( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MISSION_GALLERY, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "SkinGallery" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenSkinGallery( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SKIN_GALLERY, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "VehicleGallery" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenVehicleGallery( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_VEHICLE_GALLERY, pScreen );
+ }
+/*
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MultiSetup" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMultiSetup( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MULTIPLAYER_SETUP, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MultiChooseCharacter" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMultiChooseChar( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MULTIPLAYER_CHOOSE_CHARACTER, pScreen );
+ }
+*/
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Options" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenOptions( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_OPTIONS, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Controller" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenController( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_CONTROLLER, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Sound" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenSound( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SOUND, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "ViewCredits" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenViewCredits( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_VIEW_CREDITS, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "ViewMovies" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenViewMovies( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_VIEW_MOVIES, pScreen );
+ }
+
+#ifdef RAD_WIN32
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Display" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenDisplay( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_DISPLAY, pScreen );
+ }
+#endif
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "PlayMovie" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPlayMovie( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Demo" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPlayMovie( pScroobyScreen, this,
+ CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_DEMO );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_DEMO, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Blank" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPlayMovie( pScroobyScreen, this,
+ CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_INTRO );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_INTRO, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Blank" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPlayMovie( pScroobyScreen, this,
+ CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME, pScreen );
+ }
+
+ HeapMgr()->PopHeap( GMA_LEVEL_FE );
+MEMTRACK_POP_GROUP( "CGUIManagerFrontEnd" );
+}
+
+void
+CGuiManagerFrontEnd::Start( CGuiWindow::eGuiWindowID initialWindow )
+{
+ rAssert( GUI_FE_UNINITIALIZED == m_state );
+
+ m_nextScreen = initialWindow != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ?
+ initialWindow :
+ CGuiWindow::GUI_SCREEN_ID_MAIN_MENU;
+
+// On PC never show the splash screen.. it is very console-ish...
+#if defined(SHOW_SPLASH_SCREEN) && !defined(RAD_WIN32)
+ bool skipSplashScreen = CommandLineOptions::Get( CLO_NO_SPLASH );
+#else
+ bool skipSplashScreen = true;
+#endif
+ if( skipSplashScreen &&
+ initialWindow == CGuiWindow::GUI_SCREEN_ID_SPLASH )
+ {
+ if( s_memcardCheckState != MEM_CARD_CHECK_COMPLETED )
+ {
+ m_nextScreen = CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD_CHECK;
+ }
+ else
+ {
+ m_nextScreen = CGuiWindow::GUI_SCREEN_ID_INTRO_TRANSITION;
+ }
+
+ GetGuiSystem()->SetSplashScreenFinished();
+ }
+
+ if( s_memcardCheckState != MEM_CARD_CHECK_COMPLETED )
+ {
+ CGuiScreen* messageScreen = static_cast<CGuiScreen*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_GENERIC_MESSAGE ) );
+ if( messageScreen != NULL )
+ {
+ messageScreen->SetScroobyScreen( m_pScroobyProject->GetScreen( "Message" ) );
+ }
+
+ CGuiScreen* errorPromptScreen = static_cast<CGuiScreen*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT ) );
+ if( errorPromptScreen != NULL )
+ {
+ errorPromptScreen->SetScroobyScreen( m_pScroobyProject->GetScreen( "ErrorPrompt" ) );
+ }
+
+ CGuiScreen* genericPromptScreen = static_cast<CGuiScreen*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT ) );
+ if( genericPromptScreen != NULL )
+ {
+ genericPromptScreen->SetScroobyScreen( m_pScroobyProject->GetScreen( "Prompt" ) );
+ }
+
+ }
+
+ m_state = GUI_FE_CHANGING_SCREENS; // must be set before calling GotoScreen()
+
+ CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) );
+ rAssert( nextScreen != NULL );
+ m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this );
+}
+
+void
+CGuiManagerFrontEnd::OnControllerConnected( int controllerID )
+{
+#ifdef RAD_PS2
+ if( m_controllerPromptShown
+ && m_disconnectedController == controllerID )
+#else
+ if( m_controllerPromptShown
+ && GetGuiSystem()->GetPrimaryController() == controllerID )
+#endif
+ {
+ m_isControllerReconnected = true;
+ m_disconnectedController = -1;
+
+ GetGame()->GetPlatform()->ClearControllerError();
+ }
+}
+
+void
+CGuiManagerFrontEnd::OnControllerDisconnected( int controllerID )
+{
+ if( !m_controllerPromptShown )
+ {
+ m_controllerPromptShown = true;
+
+ // disable FMV user input handler
+ //
+ FMVUserInputHandler* userInputHandler = GetPresentationManager()->GetFMVPlayer()->GetUserInputHandler();
+ rAssert( userInputHandler != NULL );
+ m_wasFMVInputHandlerEnabled = userInputHandler->IsEnabled();
+ userInputHandler->SetEnabled( false );
+
+ // this->DisplayMessage( CGuiScreenMessage::MSG_ID_CONTROLLER_DISCONNECTED_GC + PLATFORM_TEXT_INDEX );
+ char str_buffer[256];
+ CGuiScreenMessage::GetControllerDisconnectedMessage(controllerID, str_buffer, 255);
+ GetGame()->GetPlatform()->OnControllerError(str_buffer);
+ }
+}
+
+//===========================================================================
+// CGuiManagerFrontEnd::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiManagerFrontEnd::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ switch( message )
+ {
+ case GUI_MSG_WINDOW_FINISHED:
+ {
+ if( GUI_FE_CHANGING_SCREENS == m_state )
+ {
+ m_currentScreen = m_nextScreen;
+
+ CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) );
+ rAssert( nextScreen != NULL );
+ m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this );
+ }
+/*
+ else if( GUI_FE_HIDING_POPUP == m_state )
+ {
+ m_state = GUI_FE_SCREEN_RUNNING;
+
+ // Tell the current screen to resume.
+ //
+ this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_RESUME );
+ }
+*/
+ else if( GUI_FE_SHUTTING_DOWN == m_state )
+ {
+ m_state = GUI_FE_TERMINATED;
+
+ CGuiScreen::Reset3dFEMultiController();
+
+ if( m_quittingToDemo )
+ {
+ if ( CommandLineOptions::Get( CLO_SEQUENTIAL_DEMO ) )
+ {
+ RenderEnums::LevelEnum oldLevel = GetGameplayManager()->GetCurrentLevelIndex();
+
+ unsigned int whichLevel = (oldLevel + 1) % RenderEnums::numLevels;
+ GetGameplayManager()->SetLevelIndex( (RenderEnums::LevelEnum)whichLevel );
+
+ if ( whichLevel == 0 )
+ {
+ RenderEnums::MissionEnum oldMisssion = GetGameplayManager()->GetCurrentMissionForDemo();
+ unsigned int whichMission = (oldMisssion + 1) % RenderEnums::numMissions;
+ GetGameplayManager()->SetMissionIndex( (RenderEnums::MissionEnum)whichMission );
+ }
+ }
+ else
+ {
+
+#ifdef NEALL_DEMOTEST
+ unsigned int whichLevel = RenderEnums::L1; //All seven levels
+ GetGameplayManager()->SetLevelIndex( (RenderEnums::LevelEnum)whichLevel );
+
+ unsigned int whichMission = RenderEnums::M1; //Why not.
+ GetGameplayManager()->SetMissionIndex( (RenderEnums::MissionEnum)whichMission );
+#else
+ unsigned int whichLevel = rand() % RenderEnums::numLevels; //All seven levels
+ GetGameplayManager()->SetLevelIndex( (RenderEnums::LevelEnum)whichLevel );
+
+ unsigned int whichMission = rand() % RenderEnums::numMissions; //Why not.
+ GetGameplayManager()->SetMissionIndex( (RenderEnums::MissionEnum)whichMission );
+#endif
+ }
+
+ GetInputManager()->RegisterControllerID( 0, 0 );
+
+ // let's go to demo mode
+ //
+ GetGameFlow()->SetContext( CONTEXT_LOADING_DEMO );
+ }
+ else if( m_quittingToMiniGame )
+ {
+ // let's go to mini-game mode
+ //
+ GetGameFlow()->SetContext( CONTEXT_SUPERSPRINT_FE );
+ }
+#ifdef RAD_WIN32
+ else if( m_quittingGame )
+ {
+ // let's begin the quit procedure
+ //
+ GetGameFlow()->SetContext( CONTEXT_EXIT );
+ }
+#endif
+ else
+ {
+ CurrentMissionStruct currentMission = GetCharacterSheetManager()->QueryCurrentMission();
+
+ // Set the current level and mission to load
+ //
+ GetGameplayManager()->SetLevelIndex( currentMission.mLevel );
+ GetGameplayManager()->SetMissionIndex( static_cast<RenderEnums::MissionEnum>( currentMission.mMissionNumber ) );
+
+ // let's go to normal gameplay mode
+ //
+ GetGameFlow()->SetContext( CONTEXT_LOADING_GAMEPLAY );
+ }
+ }
+
+ break;
+ }
+
+ case GUI_MSG_SPLASH_SCREEN_DONE:
+ {
+ GetGuiSystem()->SetSplashScreenFinished();
+
+ if( s_memcardCheckState == CGuiManager::MEM_CARD_CHECK_NOT_DONE )
+ {
+ CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD_CHECK,
+ CLEAR_WINDOW_HISTORY );
+ }
+ else
+ {
+ rAssert( s_memcardCheckState == CGuiManager::MEM_CARD_CHECK_COMPLETED );
+
+ this->StartIntroMovie();
+ }
+
+ break;
+ }
+
+ case GUI_MSG_MEMCARD_CHECK_COMPLETED:
+ {
+ CGuiScreen* messageScreen = static_cast<CGuiScreen*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_GENERIC_MESSAGE ) );
+ if( messageScreen != NULL )
+ {
+ messageScreen->SetScroobyScreen( m_pScroobyProject->GetScreen( "Message3D" ) );
+ }
+
+ CGuiScreen* errorPromptScreen = static_cast<CGuiScreen*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT ) );
+ if( errorPromptScreen != NULL )
+ {
+ errorPromptScreen->SetScroobyScreen( m_pScroobyProject->GetScreen( "ErrorPrompt3D" ) );
+ }
+
+ CGuiScreen* genericPromptScreen = static_cast<CGuiScreen*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT ) );
+ if( genericPromptScreen != NULL )
+ {
+ genericPromptScreen->SetScroobyScreen( m_pScroobyProject->GetScreen( "Prompt3D" ) );
+ }
+
+ this->StartIntroMovie();
+
+ break;
+ }
+
+ case GUI_MSG_QUIT_FRONTEND:
+ {
+ rAssert( GUI_FE_SCREEN_RUNNING == m_state );
+
+ GetEventManager()->TriggerEvent( EVENT_FE_START_GAME_SELECTED );
+ GetSoundManager()->DuckEverythingButMusicBegin();
+
+ // Set appropriate gameplay manager depending on number of players
+ //
+ switch( param1 )
+ {
+ case 0: // single player demo mode
+ {
+ m_quittingToDemo = true;
+
+ // follow-through
+ }
+ case 1: // single player story mode
+ {
+ SetGameplayManager( MissionManager::GetInstance() );
+
+ break;
+ }
+ case 2:
+ {
+ m_quittingToMiniGame = true;
+
+ SetGameplayManager( SuperSprintManager::GetInstance() );
+
+ break;
+ }
+ /*
+ case 2: // two players head-to-head
+ {
+ SetGameplayManager( HeadToHeadManager::GetInstance() );
+
+ break;
+ }
+ */
+ default:
+ {
+ rAssertMsg( 0, "ERROR: *** Invalid Number of Players!\n" );
+
+ break;
+ }
+ }
+
+ m_state = GUI_FE_SHUTTING_DOWN;
+
+ // Tell the current screen to shut down.
+ //
+ this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT );
+
+ break;
+ }
+
+ case GUI_MSG_QUIT_GAME:
+ {
+#ifdef RAD_WIN32
+ rAssert( GUI_FE_SCREEN_RUNNING == m_state );
+
+ m_state = GUI_FE_SHUTTING_DOWN;
+
+ m_quittingGame = true;
+
+ // Tell the current screen to shut down.
+ //
+ this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT );
+#endif // RAD_WIN32
+
+ break;
+ }
+
+
+ case GUI_MSG_CONTROLLER_DISCONNECT:
+ {
+#ifdef RAD_PS2
+ if( !m_controllerPromptShown )
+ {
+ // show controller disconnected message on PS2 only if:
+ //
+ // - primary controller hasn't been established yet and ANY controller is disconnected; OR
+ // - the controller disconnected is the primary controller
+ //
+ int primaryControllerID = GetGuiSystem()->GetPrimaryController();
+ if( primaryControllerID == -1 || primaryControllerID == static_cast<int>( param1 ) )
+ {
+ m_disconnectedController = static_cast<int>( param1 );
+ }
+ }
+#endif // RAD_PS2
+
+ break;
+ }
+
+ default:
+ {
+ if( message == GUI_MSG_UPDATE && m_isControllerReconnected )
+ {
+ m_isControllerReconnected = false;
+ m_controllerPromptShown = false;
+
+ // re-enable FMV user input handler
+ //
+ FMVUserInputHandler* userInputHandler = GetPresentationManager()->GetFMVPlayer()->GetUserInputHandler();
+ rAssert( userInputHandler != NULL );
+ userInputHandler->SetEnabled( m_wasFMVInputHandlerEnabled );
+ }
+
+ if( m_controllerPromptShown )
+ {
+ if (message==GUI_MSG_CONTROLLER_START) // start trigger reconnection
+ {
+ this->OnControllerConnected( static_cast<int>( param1 ) );
+ }
+ break; // don't pass event if controller error
+ }
+
+ if( m_state != GUI_FE_UNINITIALIZED && m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED )
+ {
+ // Send the messages down to the current screen.
+ //
+ CGuiScreen* pScreen = static_cast<CGuiScreen*>(this->FindWindowByID( m_currentScreen ));
+ rAssert( pScreen );
+ if (pScreen->IsIgnoringControllerInputs() && pScreen->IsControllerMessage(message))
+ ; // don't pass to screen
+ else
+ pScreen->HandleMessage( message, param1, param2 );
+ }
+
+ if( message == GUI_MSG_UPDATE )
+ {
+#ifndef RAD_GAMECUBE
+#ifdef RAD_PS2
+ int controllerID = m_disconnectedController;
+#else
+ int controllerID = GetGuiSystem()->GetPrimaryController();
+#endif
+ if( controllerID >=0 && !GetInputManager()->GetController( controllerID )->IsConnected() )
+ {
+ this->OnControllerDisconnected( controllerID );
+ }
+#endif
+ }
+
+ break;
+ }
+ }
+
+ // propogate message up the hierarchy
+ CGuiManager::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// Private Member Functions
+//===========================================================================
+
+void
+CGuiManagerFrontEnd::StartIntroMovie()
+{
+#ifdef SKIP_INTRO_MOVIE_IF_GAME_LOADED
+ if( GetGameDataManager()->IsGameLoaded() )
+ {
+ // skip intro fmv and go straight to main menu
+ //
+ CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_INTRO_TRANSITION,
+ CLEAR_WINDOW_HISTORY );
+ }
+ else
+#endif // SKIP_INTRO_MOVIE_IF_GAME_LOADED
+ {
+#ifdef SHOW_INTRO_MOVIE
+ // start the intro fmv
+ //
+ CGuiScreenPlayMovie* playMovieScreen = static_cast<CGuiScreenPlayMovie*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_INTRO ) );
+ rAssert( playMovieScreen != NULL );
+ playMovieScreen->SetMovieToPlay( MovieNames::INTROFMV, true, false, false );
+
+ CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_PLAY_MOVIE_INTRO,
+ CLEAR_WINDOW_HISTORY );
+#else
+ CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_INTRO_TRANSITION,
+ CLEAR_WINDOW_HISTORY );
+#endif // SHOW_INTRO_MOVIE
+ }
+}
+
diff --git a/game/code/presentation/gui/frontend/guimanagerfrontend.h b/game/code/presentation/gui/frontend/guimanagerfrontend.h
new file mode 100644
index 0000000..dbd1460
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guimanagerfrontend.h
@@ -0,0 +1,82 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiManagerFrontEnd
+//
+// Description: Interface for the CGuiManagerFrontEnd class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/09/20 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef GUIMANAGERFRONTEND_H
+#define GUIMANAGERFRONTEND_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guimanager.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+const unsigned int FOR_THE_FIRST_TIME = 1;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiManagerFrontEnd : public CGuiManager
+{
+public:
+ CGuiManagerFrontEnd( Scrooby::Project* pProject,
+ CGuiEntity* pParent );
+
+ virtual ~CGuiManagerFrontEnd();
+
+ virtual void Populate();
+ virtual void Start( CGuiWindow::eGuiWindowID initialWindow = CGuiWindow::GUI_WINDOW_ID_UNDEFINED );
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+private:
+ //---------------------------------------------------------------------
+ // Private Functions
+ //---------------------------------------------------------------------
+
+ // No copying or assignment. Declare but don't define.
+ //
+ CGuiManagerFrontEnd( const CGuiManagerFrontEnd& );
+ CGuiManagerFrontEnd& operator= ( const CGuiManagerFrontEnd& );
+
+ void OnControllerDisconnected( int controllerID );
+ void OnControllerConnected( int controllerID );
+
+ void StartIntroMovie();
+
+ //---------------------------------------------------------------------
+ // Private Data
+ //---------------------------------------------------------------------
+
+ int m_levelNum;
+ int m_disconnectedController;
+ bool m_quittingToDemo : 1;
+ bool m_controllerPromptShown : 1;
+ bool m_quittingToMiniGame : 1;
+ bool m_isControllerReconnected : 1;
+ bool m_wasFMVInputHandlerEnabled : 1;
+
+#ifdef RAD_WIN32
+ bool m_quittingGame : 1;
+#endif
+
+};
+
+#endif // GUIMANAGERFRONTEND_H
diff --git a/game/code/presentation/gui/frontend/guiscreencardgallery.cpp b/game/code/presentation/gui/frontend/guiscreencardgallery.cpp
new file mode 100644
index 0000000..c14a76e
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreencardgallery.cpp
@@ -0,0 +1,767 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenCardGallery
+//
+// Description: Implementation of the CGuiScreenCardGallery class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/21 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreencardgallery.h>
+#include <presentation/gui/frontend/guiscreenscrapbookcontents.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <presentation/gui/utility/scrollingtext.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guimenu.h>
+
+#include <cards/card.h>
+#include <cards/cardsdb.h>
+#include <events/eventmanager.h>
+#include <memory/srrmemory.h>
+
+#include <raddebug.hpp> // Foundation
+
+#include <screen.h>
+#include <page.h>
+#include <layer.h>
+#include <group.h>
+#include <sprite.h>
+#include <text.h>
+#include <pure3dobject.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const unsigned int NUM_CARD_ROWS = 2;
+const unsigned int NUM_CARD_COLUMNS = 4;
+const float CARD_TRANSITION_TIME = 250.0f; // in msec
+const float CARD_PROJECTILE_GRAVITY = 0.005f; // in m/ms/ms
+
+#ifdef RAD_WIN32
+const float CARD_THUMBNAIL_SCALE = 0.44f;
+const float CARD_DESCRIPTION_TEXT_SCALE = 0.9f;
+const float CARD_QUESTION_CORRECTION_SCALE = 2.0f / 3.0f;
+const float CARD_GREY_CORRECTION_SCALE = 2.0f / 3.0f;
+#else
+const float CARD_THUMBNAIL_SCALE = 0.44f;
+const float CARD_DESCRIPTION_TEXT_SCALE = 0.9f;
+const float CARD_QUESTION_CORRECTION_SCALE = 2.0f;
+const float CARD_GREY_CORRECTION_SCALE = 2.0f;
+#endif
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenCardGallery::CGuiScreenCardGallery
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenCardGallery::CGuiScreenCardGallery
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent,
+ eGuiWindowID windowID
+)
+: CGuiScreen( pScreen, pParent, windowID ),
+ m_cardGalleryState( STATE_BROWSING_CARDS ),
+ m_cardScaleSmall( CARD_THUMBNAIL_SCALE ),
+ m_cardScaleLarge( 1.0f ),
+ m_pMenu( NULL ),
+ m_viewCard( NULL ),
+ m_viewCardDistX( 0 ),
+ m_viewCardDistY( 0 ),
+ m_cardBrowseLayer( NULL ),
+ m_cardViewLayer( NULL ),
+ m_cardSFXLayer( NULL ),
+ m_elapsedTime( 0 ),
+ m_currentCard( NULL ),
+ m_cardTitle( NULL ),
+ m_cardEpisode( NULL ),
+ m_cardDescription( NULL ),
+ m_currentQuote( -1 )
+{
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "CardGallery" );
+ if( windowID == GUI_SCREEN_ID_VIEW_CARDS )
+ {
+ pPage = m_pScroobyScreen->GetPage( "PauseViewCards" );
+ }
+ rAssert( pPage != NULL );
+
+ char cardName[ 8 ];
+
+ // create a 2D sprite menu
+ //
+ m_pMenu = new CGuiMenu2D( this, NUM_CARDS_PER_LEVEL, 4, GUI_SPRITE_MENU, MENU_SFX_NONE );
+ rAssert( m_pMenu != NULL );
+ m_pMenu->SetGreyOutEnabled( false );
+
+ Scrooby::Group* pGroup = pPage->GetGroup( "CollectedCards" );
+ rAssert( pGroup != NULL );
+
+ // add sprites to menu
+ //
+ for( unsigned int i = 0; i < NUM_CARDS_PER_LEVEL; i++ )
+ {
+ sprintf( cardName, "Card%d", i );
+ m_pMenu->AddMenuItem( pGroup->GetSprite( cardName ) );
+ }
+
+ // add menu cursor
+ //
+ m_pMenu->SetCursor( pGroup->GetSprite( "CardFrame" ) );
+
+ m_cardBrowseLayer = pPage->GetLayer( "Foreground" );
+ rAssert( m_cardBrowseLayer );
+
+ // from ViewCard page
+ //
+ pPage = m_pScroobyScreen->GetPage( "ViewCard" );
+ rAssert( pPage != NULL );
+
+ this->AutoScaleFrame( pPage );
+
+ for( unsigned int j = 0; j < NUM_CARDS_PER_LEVEL; j++ )
+ {
+ sprintf( cardName, "Card%d", j );
+ Scrooby::Sprite* greyCard = pPage->GetSprite( cardName );
+ if( greyCard != NULL )
+ {
+ greyCard->ResetTransformation();
+ greyCard->ScaleAboutCenter( CARD_GREY_CORRECTION_SCALE );
+ }
+ }
+
+ m_cardViewLayer = pPage->GetLayer( "ViewCard" );
+ rAssert( m_cardViewLayer );
+ m_cardViewLayer->SetVisible( false );
+
+ m_cardTitle = pPage->GetText( "CardTitle" );
+ rAssert( m_cardTitle );
+ m_cardTitle->SetTextMode( Scrooby::TEXT_WRAP );
+
+ m_cardEpisode = pPage->GetText( "CardEpisode" );
+ rAssert( m_cardEpisode );
+ m_cardEpisode->SetTextMode( Scrooby::TEXT_WRAP );
+
+ m_cardDescription = pPage->GetText( "CardDescription" );
+ rAssert( m_cardDescription );
+ m_cardDescription->SetTextMode( Scrooby::TEXT_WRAP );
+ m_cardDescription->ScaleAboutPoint( CARD_DESCRIPTION_TEXT_SCALE, 0, 0 );
+
+ for( unsigned int i = 0; i < MAX_NUM_QUOTES; i++ )
+ {
+ char name[ 32 ];
+ sprintf( name, "Quote%d", i );
+
+ m_quoteIcon[ i ] = pPage->GetSprite( name );
+ rAssert( m_quoteIcon[ i ] );
+
+ m_quote[ i ] = new( GMA_LEVEL_FE ) ScrollingText( pPage->GetText( name ) );
+ rAssert( m_quote[ i ] );
+ }
+
+ if( windowID == GUI_SCREEN_ID_CARD_GALLERY )
+ {
+ // from HighResCard page
+ //
+ pPage = m_pScroobyScreen->GetPage( "HighResCard" );
+ }
+ else
+ {
+ // from LowResCard page
+ //
+ pPage = m_pScroobyScreen->GetPage( "LowResCard" );
+ }
+
+ rAssert( pPage != NULL );
+ Scrooby::Layer* cardLayer = pPage->GetLayer( "Card" );
+ rAssert( cardLayer != NULL );
+
+ m_viewCard = cardLayer->GetSprite( "Card" );
+ rAssert( m_viewCard );
+ m_viewCard->SetVisible( false );
+
+ m_cardSFXLayer = pPage->GetLayer( "SFX" );
+ if( m_cardSFXLayer != NULL )
+ {
+ m_cardSFXLayer->SetVisible( false );
+ }
+
+ if( this->IsWideScreenDisplay() )
+ {
+ if( m_cardSFXLayer != NULL )
+ {
+ Scrooby::Pure3dObject* cardSparkle = m_cardSFXLayer->GetPure3dObject( "CardSparkle" );
+ if( cardSparkle != NULL )
+ {
+ cardSparkle->SetWideScreenCorrectionEnabled( true );
+ }
+ }
+
+ cardLayer->ResetTransformation();
+ this->ApplyWideScreenCorrectionScale( cardLayer );
+
+ m_cardViewLayer->ResetTransformation();
+ this->ApplyWideScreenCorrectionScale( m_cardViewLayer );
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenCardGallery::~CGuiScreenCardGallery
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenCardGallery::~CGuiScreenCardGallery()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+
+ for( unsigned int i = 0; i < MAX_NUM_QUOTES; i++ )
+ {
+ if( m_quote[ i ] != NULL )
+ {
+ delete m_quote[ i ];
+ m_quote[ i ] = NULL;
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenCardGallery::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenCardGallery::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_cardGalleryState != STATE_BROWSING_CARDS )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ if( m_cardGalleryState == STATE_GOTO_VIEW_CARD )
+ {
+ this->UpdateCardTransition( param1, true );
+ }
+ else if( m_cardGalleryState == STATE_BACK_VIEW_CARD )
+ {
+ this->UpdateCardTransition( param1, false );
+ }
+ else
+ {
+ rAssert( m_cardGalleryState == STATE_VIEWING_CARD );
+ this->UpdateViewCard( param1 );
+ }
+
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ if( m_cardGalleryState == STATE_VIEWING_CARD )
+ {
+ if( m_cardSFXLayer != NULL )
+ {
+ m_cardSFXLayer->SetVisible( false );
+ }
+
+ m_cardGalleryState = STATE_BACK_VIEW_CARD;
+ m_elapsedTime = 0;
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); // sound effect
+ }
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ return;
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ // pulse cursor alpha
+ //
+ Scrooby::Drawable* cursor = m_pMenu->GetCursor();
+ if( cursor != NULL )
+ {
+ const unsigned int PULSE_PERIOD = 1000;
+
+ float alpha = GuiSFX::Pulse( (float)m_elapsedTime,
+ (float)PULSE_PERIOD,
+ 0.75f,
+ 0.25f,
+ -rmt::PI_BY2 );
+
+ cursor->SetAlpha( alpha );
+
+ m_elapsedTime += param1;
+ m_elapsedTime %= PULSE_PERIOD;
+ }
+
+ break;
+ }
+/*
+ case GUI_MSG_CONTROLLER_LEFT:
+ {
+ int newSelection = m_currentSelection - 1;
+ if( newSelection < 0 )
+ {
+ newSelection += NUM_CARDS_PER_LEVEL;
+ }
+
+ this->MoveCursor( m_currentSelection, newSelection );
+ m_currentSelection = newSelection;
+
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_RIGHT:
+ {
+ int newSelection = (m_currentSelection + 1) % NUM_CARDS_PER_LEVEL;
+ this->MoveCursor( m_currentSelection, newSelection );
+ m_currentSelection = newSelection;
+
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_UP:
+ {
+ int newSelection = m_currentSelection - NUM_CARD_COLUMNS;
+ if( newSelection < 0 )
+ {
+ newSelection += NUM_CARDS_PER_LEVEL;
+ }
+
+ this->MoveCursor( m_currentSelection, newSelection );
+ m_currentSelection = newSelection;
+
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_DOWN:
+ {
+ int newSelection = (m_currentSelection + NUM_CARD_COLUMNS) % NUM_CARDS_PER_LEVEL;
+
+ this->MoveCursor( m_currentSelection, newSelection );
+ m_currentSelection = newSelection;
+
+ break;
+ }
+*/
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ Scrooby::Sprite* currentCardSelection = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( param1 )->GetItem() );
+ rAssert( currentCardSelection != NULL );
+
+ int cardID = currentCardSelection->GetIndex() - 1;
+ if( cardID != -1 )
+ {
+ this->SetCurrentViewCard( cardID );
+
+ int smallPosX, smallPosY;
+ currentCardSelection->GetOriginPosition( smallPosX, smallPosY );
+
+ int bigPosX, bigPosY;
+ m_viewCard->GetOriginPosition( bigPosX, bigPosY );
+
+ m_viewCardDistX = smallPosX - bigPosX;
+ m_viewCardDistY = smallPosY - bigPosY;
+
+ m_cardVelocity.x = m_viewCardDistX / CARD_TRANSITION_TIME;
+ m_cardVelocity.y = (m_viewCardDistY - 0.5f * CARD_PROJECTILE_GRAVITY * CARD_TRANSITION_TIME * CARD_TRANSITION_TIME) / CARD_TRANSITION_TIME;
+ m_cardVelocity.z = 0.0f;
+
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, false );
+
+ // hide level bar
+ //
+ CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ if( scrapBookContents != NULL )
+ {
+ scrapBookContents->SetLevelBarVisible( false );
+ }
+
+ m_viewCard->SetVisible( true );
+ m_cardViewLayer->SetVisible( true );
+ m_cardGalleryState = STATE_GOTO_VIEW_CARD;
+ m_elapsedTime = 0;
+
+ this->UpdateCardTransition( 0, true );
+ }
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ //
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenCardGallery::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenCardGallery::InitIntro()
+{
+ CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ rAssert( scrapBookContents != NULL );
+ this->UpdateCards( scrapBookContents->GetCurrentLevel() );
+}
+
+
+//===========================================================================
+// CGuiScreenCardGallery::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenCardGallery::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenCardGallery::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenCardGallery::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+/*
+void
+CGuiScreenCardGallery::MoveCursor( unsigned int from,
+ unsigned int to )
+{
+ if( m_cursor != NULL )
+ {
+ rAssert( from < NUM_CARDS_PER_LEVEL && to < NUM_CARDS_PER_LEVEL );
+
+ int posX = 0;
+ int posY = 0;
+ m_collectedCards[ to ]->GetOriginPosition( posX, posY );
+
+ m_cursor->SetPosition( posX, posY );
+ }
+
+ // turn on/off 'accept' button
+ //
+ bool isSelectable = (m_collectedCards[ to ]->GetIndex() != 0);
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, isSelectable );
+}
+*/
+
+void
+CGuiScreenCardGallery::UpdateCards( unsigned int currentLevel )
+{
+ // update the cards
+ //
+ const CardList* collectedCards = GetCardGallery()->GetCollectedCards( currentLevel );
+ rAssert( collectedCards != NULL );
+ rAssert( m_pMenu != NULL );
+
+ // hide accept button by default (unless there is at least one collected card to view)
+ //
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, false );
+
+ for( unsigned int i = 0; i < NUM_CARDS_PER_LEVEL; i++ )
+ {
+ Scrooby::Sprite* cardSelection = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() );
+ rAssert( cardSelection != NULL );
+ cardSelection->ResetTransformation();
+
+ bool isCardCollected = ( collectedCards->m_cards[ i ] != NULL );
+ m_pMenu->SetMenuItemEnabled( i, isCardCollected );
+
+ if( isCardCollected )
+ {
+ unsigned int cardID = collectedCards->m_cards[ i ]->GetID();
+ rAssert( cardID < static_cast<unsigned int>( cardSelection->GetNumOfImages() ) );
+ cardSelection->SetIndex( cardID + 1 );
+ cardSelection->ScaleAboutCenter( m_cardScaleSmall );
+
+// m_pMenu->Reset();
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, true );
+ }
+ else
+ {
+ cardSelection->SetIndex( 0 );
+ cardSelection->ScaleAboutCenter( CARD_QUESTION_CORRECTION_SCALE );
+ }
+ }
+}
+
+void
+CGuiScreenCardGallery::UpdateCardTransition( unsigned int elapsedTime, bool toViewCard )
+{
+ rAssert( m_viewCard );
+ m_viewCard->ResetTransformation();
+
+ if( m_elapsedTime < CARD_TRANSITION_TIME )
+ {
+ float t = toViewCard ? (float)m_elapsedTime / CARD_TRANSITION_TIME :
+ 1.0f - (float)m_elapsedTime / CARD_TRANSITION_TIME;
+
+ // scale card
+ //
+ float scale = t * (m_cardScaleLarge - m_cardScaleSmall) + m_cardScaleSmall;
+ m_viewCard->ScaleAboutCenter( scale );
+
+/*
+ // translate card
+ //
+ int translateX = static_cast<int>( (1.0f - t) * m_viewCardDistX );
+ int translateY = static_cast<int>( (1.0f - t) * m_viewCardDistY );
+ m_viewCard->Translate( translateX, translateY );
+*/
+
+ GuiSFX::Projectile( m_viewCard,
+ (float)m_elapsedTime,
+ CARD_TRANSITION_TIME,
+ m_cardVelocity,
+ toViewCard,
+ CARD_PROJECTILE_GRAVITY );
+
+ // fade in/out foreground layers (non-linearly)
+ //
+ m_cardBrowseLayer->SetAlpha( (1.0f - t) * (1.0f - t) );
+ m_cardViewLayer->SetAlpha( t * t );
+
+ m_elapsedTime += elapsedTime;
+ }
+ else
+ {
+ // transition completed
+ //
+ if( toViewCard )
+ {
+ m_viewCard->ScaleAboutCenter( m_cardScaleLarge );
+
+ m_cardGalleryState = STATE_VIEWING_CARD;
+
+ m_cardBrowseLayer->SetAlpha( 0.0f );
+ m_cardViewLayer->SetAlpha( 1.0f );
+
+ if( m_cardSFXLayer != NULL )
+ {
+ m_cardSFXLayer->SetVisible( true );
+ }
+ }
+ else
+ {
+ m_viewCard->ScaleAboutCenter( m_cardScaleSmall );
+
+ m_cardViewLayer->SetVisible( false );
+ m_viewCard->SetVisible( false );
+ m_cardGalleryState = STATE_BROWSING_CARDS;
+
+ m_cardBrowseLayer->SetAlpha( 1.0f );
+ m_cardViewLayer->SetAlpha( 0.0f );
+
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, true );
+
+ // show level bar
+ //
+ CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ if( scrapBookContents != NULL )
+ {
+ scrapBookContents->SetLevelBarVisible( true );
+ }
+ }
+ }
+}
+
+void
+CGuiScreenCardGallery::UpdateViewCard( unsigned int elapsedTime )
+{
+ rAssert( m_currentCard );
+
+ if( m_currentQuote != -1 )
+ {
+ // update current scrolling quote
+ //
+ rAssert( m_quote[ m_currentQuote ] );
+ m_quote[ m_currentQuote ]->Update( elapsedTime );
+
+ if( m_quote[ m_currentQuote ]->GetCurrentState() == ScrollingText::STATE_IDLE )
+ {
+ // turn off current quote icon
+ //
+ m_quoteIcon[ m_currentQuote ]->SetVisible( false );
+
+ // start next quote (and wrap to first one)
+ //
+ m_currentQuote = (m_currentQuote + 1) % m_currentCard->GetNumQuotes();
+ m_quote[ m_currentQuote ]->Start();
+
+ // turn on new quote icon
+ //
+ m_quoteIcon[ m_currentQuote ]->SetVisible( true );
+ }
+ }
+}
+
+void
+CGuiScreenCardGallery::SetCurrentViewCard( unsigned int cardID )
+{
+ // set current card reference
+ //
+ m_currentCard = GetCardGallery()->GetCardsDB()->GetCardByID( cardID );
+ rAssert( m_currentCard );
+
+ // set card image
+ //
+ rAssert( m_viewCard );
+ rAssert( cardID < static_cast<unsigned int>( m_viewCard->GetNumOfImages() ) );
+ m_viewCard->SetIndex( cardID );
+
+ // set card title
+ //
+ rAssert( m_cardTitle );
+ rAssert( cardID < static_cast<unsigned int>( m_cardTitle->GetNumOfStrings() ) );
+ m_cardTitle->SetIndex( cardID );
+
+ // set card episode
+ //
+ rAssert( m_cardEpisode );
+ rAssert( cardID < static_cast<unsigned int>( m_cardEpisode->GetNumOfStrings() ) );
+ m_cardEpisode->SetIndex( cardID );
+
+ // set card description
+ //
+ rAssert( m_cardDescription );
+ rAssert( cardID < static_cast<unsigned int>( m_cardDescription->GetNumOfStrings() ) );
+ m_cardDescription->SetIndex( cardID );
+
+ // stop current quote
+ //
+ if( m_currentQuote != -1 )
+ {
+ m_quote[ m_currentQuote ]->Stop();
+ }
+
+ // set card quotes
+ //
+ for( unsigned int i = 0; i < MAX_NUM_QUOTES; i++ )
+ {
+ m_quoteIcon[ i ]->SetVisible( false );
+
+ eQuoteID quoteID = m_currentCard->GetQuoteID( i );
+ if( quoteID != EMPTY_QUOTE )
+ {
+ m_quoteIcon[ i ]->SetIndex( static_cast<int>( quoteID ) );
+ }
+
+ m_quote[ i ]->SetTextIndex( cardID );
+ }
+
+ if( m_currentCard->GetNumQuotes() > 0 )
+ {
+ // start scrolling first quote
+ //
+ m_currentQuote = 0;
+ m_quote[ m_currentQuote ]->Start();
+ m_quoteIcon[ m_currentQuote ]->SetVisible( true );
+ }
+ else
+ {
+ m_currentQuote = -1;
+ }
+}
+
diff --git a/game/code/presentation/gui/frontend/guiscreencardgallery.h b/game/code/presentation/gui/frontend/guiscreencardgallery.h
new file mode 100644
index 0000000..d3284fe
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreencardgallery.h
@@ -0,0 +1,104 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenCardGallery
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/21 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENCARDGALLERY_H
+#define GUISCREENCARDGALLERY_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <cards/cardgallery.h>
+#include <cards/card.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class CGuiMenu2D;
+class ScrollingText;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenCardGallery : public CGuiScreen
+{
+public:
+ CGuiScreenCardGallery( Scrooby::Screen* pScreen, CGuiEntity* pParent,
+ eGuiWindowID windowID = GUI_SCREEN_ID_CARD_GALLERY );
+ virtual ~CGuiScreenCardGallery();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+ void UpdateCards( unsigned int currentLevel );
+
+ enum eScreenState
+ {
+ STATE_BROWSING_CARDS,
+ STATE_GOTO_VIEW_CARD,
+ STATE_VIEWING_CARD,
+ STATE_BACK_VIEW_CARD,
+
+ NUM_SCREEN_STATES
+ };
+
+ eScreenState m_cardGalleryState;
+
+ float m_cardScaleSmall;
+ float m_cardScaleLarge;
+
+ CGuiMenu2D* m_pMenu;
+
+private:
+// void MoveCursor( unsigned int from, unsigned int to );
+ void UpdateCardTransition( unsigned int elapsedTime, bool toViewCard );
+ void UpdateViewCard( unsigned int elapsedTime );
+ void SetCurrentViewCard( unsigned int cardID );
+
+ Scrooby::Sprite* m_viewCard;
+ int m_viewCardDistX;
+ int m_viewCardDistY;
+ rmt::Vector m_cardVelocity;
+
+ Scrooby::Layer* m_cardBrowseLayer;
+ Scrooby::Layer* m_cardViewLayer;
+ Scrooby::Layer* m_cardSFXLayer;
+
+ unsigned int m_elapsedTime;
+
+ // for viewing card
+ //
+ Card* m_currentCard;
+
+ Scrooby::Text* m_cardTitle;
+ Scrooby::Text* m_cardEpisode;
+ Scrooby::Text* m_cardDescription;
+
+ Scrooby::Sprite* m_quoteIcon[ MAX_NUM_QUOTES ];
+ ScrollingText* m_quote[ MAX_NUM_QUOTES ];
+ int m_currentQuote;
+
+};
+
+#endif // GUISCREENCARDGALLERY_H
diff --git a/game/code/presentation/gui/frontend/guiscreencontroller.cpp b/game/code/presentation/gui/frontend/guiscreencontroller.cpp
new file mode 100644
index 0000000..3ffd076
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreencontroller.cpp
@@ -0,0 +1,401 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenController
+//
+// Description: Implementation of the CGuiScreenController class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreencontroller.h>
+#include <presentation/gui/guimenu.h>
+
+#include <input/inputmanager.h>
+#include <memory/srrmemory.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+
+#include <raddebug.hpp> // Foundation
+#include <group.h>
+#include <layer.h>
+#include <page.h>
+#include <screen.h>
+#include <text.h>
+
+#include <strings/unicodestring.h>
+#include <p3d/unicode.hpp>
+#include <string.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+enum eMenuItem
+{
+ MENU_ITEM_CONFIGURATION,
+ MENU_ITEM_DISPLAY,
+ MENU_ITEM_VIBRATION,
+
+ NUM_MENU_ITEMS
+};
+
+static const char* MENU_ITEMS[] =
+{
+ "Configuration",
+ "Display",
+ "Vibration"
+};
+
+const int NUM_DISPLAY_MODES = 2;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenController::CGuiScreenController
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenController::CGuiScreenController
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_CONTROLLER ),
+ m_pMenu( NULL ),
+ m_numLabels( 0 ),
+ m_currentConfig( 0 ),
+ m_currentDisplay( 0 ),
+ m_currentControllerID( 0 )
+{
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage;
+ pPage = m_pScroobyScreen->GetPage( "Controller" );
+ rAssert( pPage );
+
+ // create a menu
+ //
+ m_pMenu = new(GMA_LEVEL_FE) CGuiMenu( this, NUM_MENU_ITEMS );
+ rAssert( m_pMenu != NULL );
+
+ // add menu items
+ //
+ Scrooby::Group* menu = pPage->GetGroup( "Menu" );
+ for( int j = 0; j < NUM_MENU_ITEMS; j++ )
+ {
+ char objectName[ 32 ];
+ sprintf( objectName, "%s_Value", MENU_ITEMS[ j ] );
+ m_pMenu->AddMenuItem( menu->GetText( MENU_ITEMS[ j ] ),
+ menu->GetText( objectName ),
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED );
+ }
+
+#ifdef RAD_GAMECUBE
+ // change "Vibration" text to "Rumble"
+ //
+ Scrooby::Text* vibrationText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_ITEM_VIBRATION )->GetItem() );
+ rAssert( vibrationText );
+ vibrationText->SetIndex( 1 );
+#endif // RAD_GAMECUBE
+
+ // disable configuration until there are multiple configurations from
+ // which to choose
+ //
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_CONFIGURATION, false, true );
+
+ // get the platform-specific Controller page
+ //
+#ifdef RAD_GAMECUBE
+ pPage = m_pScroobyScreen->GetPage( "ControllerGC" );
+ rAssert( pPage );
+#endif // RAD_GAMECUBE
+
+#ifdef RAD_PS2
+ pPage = m_pScroobyScreen->GetPage( "ControllerPS2" );
+ rAssert( pPage );
+#endif // RAD_PS2
+
+#ifdef RAD_XBOX
+ pPage = m_pScroobyScreen->GetPage( "ControllerXBOX" );
+ rAssert( pPage );
+#endif // RAD_XBOX
+
+#ifdef RAD_WIN32
+ pPage = m_pScroobyScreen->GetPage( "ControllerPC" );
+ rAssert( pPage );
+#endif // RAD_WIN32
+
+ // and make it visible
+ //
+ pPage->GetLayerByIndex( 0 )->SetVisible( true );
+
+ // get text labels
+ //
+ Scrooby::Group* textLabels = pPage->GetGroup( "TextLabels" );
+ rAssert( textLabels != NULL );
+ for( int i = 0; i < MAX_NUM_LABELS; i++ )
+ {
+ char objectName[ 32 ];
+ sprintf( objectName, "Label%02d", i );
+
+ Scrooby::Text* textLabel = textLabels->GetText( objectName );
+ if( textLabel != NULL )
+ {
+#ifdef PAL
+ textLabel->StretchBoundingBox( 30, 0 );
+#endif // PAL
+
+ textLabel->SetTextMode( Scrooby::TEXT_WRAP );
+ m_labels[ i ] = textLabel;
+ m_numLabels++;
+
+ // TC: this is now done in the text bible
+ //
+/*
+ // convert text label strings to all caps
+ //
+ for( int j = 0; j < NUM_DISPLAY_MODES; j++ )
+ {
+ rAssert( j < textLabel->GetNumOfStrings() );
+
+ p3d::UnicodeStrUpr( textLabel->GetStringBuffer( j ) );
+ }
+*/
+ }
+ else
+ {
+ // assume no more labels, which means they all must have
+ // been numbered sequentially without any gaps
+ //
+ break;
+ }
+ }
+
+#ifdef PAL
+ // scale down controller image and text labels a bit so that
+ // all localized versions will fit on screen
+ //
+ #ifdef RAD_PS2
+ const float SCALE_FACTOR = 0.95f;
+ #else
+ const float SCALE_FACTOR = 0.9f;
+ #endif
+
+ textLabels->ResetTransformation();
+ textLabels->ScaleAboutCenter( SCALE_FACTOR );
+
+ pPage = m_pScroobyScreen->GetPage( "ControllerImage" );
+ if( pPage != NULL )
+ {
+ Scrooby::Sprite* controllerImage = pPage->GetSprite( "Controller" );
+ if( controllerImage != NULL )
+ {
+ controllerImage->ResetTransformation();
+ controllerImage->ScaleAboutCenter( SCALE_FACTOR );
+ }
+ }
+#endif // PAL
+}
+
+
+//===========================================================================
+// CGuiScreenController::~CGuiScreenController
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenController::~CGuiScreenController()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenController::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenController::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_LEFT:
+ case GUI_MSG_CONTROLLER_RIGHT:
+ {
+ if( m_pMenu->GetSelection() == MENU_ITEM_VIBRATION )
+ {
+ m_currentControllerID = static_cast<int>( param1 );
+ }
+
+ break;
+ }
+
+ case GUI_MSG_MENU_SELECTION_VALUE_CHANGED:
+ {
+ if( param1 == MENU_ITEM_CONFIGURATION )
+ {
+ m_currentConfig = param2;
+
+ this->UpdateLabels();
+ }
+ else if( param1 == MENU_ITEM_DISPLAY )
+ {
+ m_currentDisplay = param2;
+
+ this->UpdateLabels();
+ }
+ else if( param1 == MENU_ITEM_VIBRATION )
+ {
+ if( param2 == 0 ) // vibration turned ON
+ {
+ // send vibration pulse to controller
+ //
+ GetInputManager()->TriggerRumblePulse( m_currentControllerID );
+ }
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ this->StartTransitionAnimation( 560, 590 );
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenController::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenController::InitIntro()
+{
+ // update controller settings on menu
+ //
+ bool vibrationOn = GetInputManager()->IsRumbleEnabled();
+ m_pMenu->SetSelectionValue( MENU_ITEM_VIBRATION,
+ vibrationOn ? 0 : 1 );
+}
+
+
+//===========================================================================
+// CGuiScreenController::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenController::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenController::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenController::InitOutro()
+{
+ bool vibrationOn = (m_pMenu->GetSelectionValue( MENU_ITEM_VIBRATION ) == 0);
+ GetInputManager()->SetRumbleEnabled( vibrationOn );
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenController::UpdateLabels()
+{
+ int labelIndex = m_currentConfig * NUM_DISPLAY_MODES + m_currentDisplay;
+ for( int i = 0; i < m_numLabels; i++ )
+ {
+ rAssert( m_labels[ i ] );
+ m_labels[ i ]->SetIndex( labelIndex );
+ }
+}
+
diff --git a/game/code/presentation/gui/frontend/guiscreencontroller.h b/game/code/presentation/gui/frontend/guiscreencontroller.h
new file mode 100644
index 0000000..9c56c19
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreencontroller.h
@@ -0,0 +1,65 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenController
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/30 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENCONTROLLER_H
+#define GUISCREENCONTROLLER_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenController : public CGuiScreen
+{
+public:
+ CGuiScreenController( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenController();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ void UpdateLabels();
+
+ static const int MAX_NUM_LABELS = 32;
+
+ CGuiMenu* m_pMenu;
+
+ Scrooby::Text* m_labels[ MAX_NUM_LABELS ];
+ int m_numLabels;
+
+ int m_currentConfig;
+ int m_currentDisplay;
+ int m_currentControllerID;
+
+};
+
+#endif // GUISCREENCONTROLLER_H
diff --git a/game/code/presentation/gui/frontend/guiscreencontrollerWin32.cpp b/game/code/presentation/gui/frontend/guiscreencontrollerWin32.cpp
new file mode 100644
index 0000000..eb17100
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreencontrollerWin32.cpp
@@ -0,0 +1,1200 @@
+/******************************************************************************
+ File: GuiScreenControllerWin32.cpp
+ Desc: Defines the CGuiScreenController class.
+ Author: Neil Haran
+ Date: July 31, 2003
+ History:
+*****************************************************************************/
+#include <presentation/gui/frontend/guiscreencontrollerWin32.h>
+#include <presentation/gui/guiscreenprompt.h>
+#include <presentation/gui/guimanager.h>
+#include <input/inputmanager.h>
+#include <memory/srrmemory.h>
+#include <data/config/gameconfigmanager.h>
+#include <presentation/tutorialmanager.h>
+#include <events/eventmanager.h>
+#include <camera/supercammanager.h>
+#include <camera/supercamcentral.h>
+
+#include <group.h>
+#include <layer.h>
+#include <page.h>
+#include <screen.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const char* szMainControllerPage = "ControllerPC";
+const char* szCCPage = "CharacterControls";
+const char* szVCPage = "VehicleControls";
+const char* szGSPage = "GameSettings";
+const char* szNotAssigned = "---";
+
+const int NUM_DISPLAY_MODES = 2;
+const int MAX_INPUTNAME_LENGTH = 10;
+
+const tColour DEFAULT_SELECTED_ITEM_COLOUR( 255, 255, 0 );
+const tColour DEFAULT_INPUTMAPPED_ITEM_COLOUR( 255, 0, 0 ); // the same as in guiscreenmemorycard.cpp
+
+const float SLIDER_ICON_SCALE = 0.5f;
+
+/******************************************************************************
+ Construction/Destruction
+*****************************************************************************/
+CGuiScreenController::CGuiScreenController( Scrooby::Screen* pScreen, CGuiEntity* pParent )
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_CONTROLLER ),
+ m_pMenu( NULL ),
+ m_currentPage( MENU_PAGE_MAIN ),
+ m_currentControllerID( 0 ),
+ m_bMapInput( false ),
+ m_currentTextLabel(NULL),
+ m_bDisableBack(false),
+ m_numControllerGroups(0)
+{
+ memset( m_menuGroupStartIndex, 0 , sizeof( m_menuGroupStartIndex ) );
+ m_pMenu = new(GMA_LEVEL_FE) CGuiMenu( this, NUM_MENU_ITEMS );
+ rAssert( m_pMenu != NULL );
+
+ // Add main menu items
+ SetGroups( m_pMenuLabels, NUM_MAINMENU_LABELS, szMainControllerPage, "Menu", "Label", ALL_ATTRIBUTES_ON );
+ m_numControllerGroups = 1; // The first page is the MENU_PAGE_MAIN with an index of 0.
+
+ // Add map items
+ SetGroups( m_pCCLabels[MAP_PRIMARY], NUM_CHARACTERCONTROL_LABELS, szCCPage, "Map1", "Map1Label" );
+ SetGroups( m_pCCLabels[MAP_SECONDARY], NUM_CHARACTERCONTROL_LABELS, szCCPage, "Map2", "Map2Label" );
+ SetGroups( m_pVCLabels[MAP_PRIMARY], NUM_VEHICLECONTROL_LABELS, szVCPage, "Map1", "Map1Label" );
+ SetGroups( m_pVCLabels[MAP_SECONDARY], NUM_VEHICLECONTROL_LABELS, szVCPage, "Map2", "Map2Label" );
+
+ // Add game setting items
+ SetGroups( m_pMSLabels, NUM_GAMESETTING_LABELS, szGSPage, "Menu",
+ "Label", (SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED) );
+
+ //Turn off the controller page that shows up for the consoles.
+ SetPageVisiblility( "Controller", false );
+ SetPageVisiblility( szMainControllerPage, true );
+ SetPageVisiblility( szCCPage, false );
+ SetPageVisiblility( szVCPage, false );
+ SetPageVisiblility( szGSPage, false );
+
+ // Size the slider icons in the game settings page.
+ Scrooby::Group* group = pScreen->GetPage( szGSPage )->GetGroup( "Menu" );
+ if( group != NULL )
+ {
+ group->GetSprite( "MouseXSliderIcon" )->ScaleAboutCenter( SLIDER_ICON_SCALE );
+ group->GetSprite( "MouseYSliderIcon" )->ScaleAboutCenter( SLIDER_ICON_SCALE );
+ group->GetSprite( "WheelSliderIcon" )->ScaleAboutCenter( SLIDER_ICON_SCALE );
+ }
+}
+
+CGuiScreenController::~CGuiScreenController()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+//===========================================================================
+// CGuiScreenController::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenController::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ static bool bRelayMessage = true;
+
+ if( message == GUI_MSG_MENU_PROMPT_RESPONSE )
+ {
+ switch( param1 )
+ {
+ case PROMPT_CONFIRM_RESTOREALLDEFAULTS:
+ {
+ switch( param2 )
+ {
+ case (CGuiMenuPrompt::RESPONSE_YES):
+ {
+ GetInputManager()->GetController(m_currentControllerID)->LoadDefaults();
+ this->InitIntro();
+ this->ReloadScreen();
+
+ break;
+ }
+
+ case (CGuiMenuPrompt::RESPONSE_NO):
+ {
+ this->ReloadScreen();
+
+ break;
+ }
+
+ default:
+ {
+ rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" );
+
+ break;
+ }
+ }
+ }
+ break;
+ default: break;
+ }
+ }
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_MENU_SELECTION_VALUE_CHANGED:
+ {
+ rAssert( m_pMenu );
+ GuiMenuItem* currentItem = m_pMenu->GetMenuItem( param1 );
+ rAssert( currentItem );
+
+ switch( m_currentPage )
+ {
+ case MENU_PAGE_GAMESETTINGS:
+ {
+ // convert to Gamesetting specific items.
+ int menuItem = param1-NUM_CHARACTERCONTROL_LABELS-NUM_VEHICLECONTROL_LABELS;
+ UserController* pController = GetInputManager()->GetController( m_currentControllerID );
+
+ switch( menuItem )
+ {
+ case GS_MOUSELOOK:
+ {
+ pController->SetMouseLook( m_pMenu->GetSelectionValue( param1 ) == PROMPT_YES );
+
+ GetSuperCamManager()->GetSCC( 0 )->SelectSuperCam( SuperCam::ON_FOOT_CAM, SuperCamCentral::CUT, 0 );
+ GetSuperCamManager()->GetSCC( 0 )->Update( 0 );
+ }
+ break;
+ case GS_MOUSESENSITIVITY_X:
+ {
+ pController->SetMouseSensitivityX( m_pMenu->GetMenuItem( param1 )->m_slider.m_value );
+ }
+ break;
+ case GS_MOUSESENSITIVITY_Y:
+ {
+ pController->SetMouseSensitivityY( m_pMenu->GetMenuItem( param1 )->m_slider.m_value );
+ }
+ break;
+ case GS_INVERTMOUSEX:
+ {
+ pController->SetInvertMouseX( m_pMenu->GetSelectionValue( param1 ) == PROMPT_YES );
+ }
+ break;
+ case GS_INVERTMOUSEY:
+ {
+ pController->SetInvertMouseY( m_pMenu->GetSelectionValue( param1 ) == PROMPT_YES );
+ }
+ break;
+ case GS_FORCEFEEDBACK:
+ {
+ pController->SetForceFeedback( m_pMenu->GetSelectionValue( param1 ) == PROMPT_YES );
+ }
+ break;
+ case GS_WHEELSENSITIVITY:
+ {
+ pController->SetWheelSensitivityX( m_pMenu->GetMenuItem( param1 )->m_slider.m_value );
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_UP:
+ {
+ // Basically a wrap around system when you reach the top.
+ // Just jumps to the last element.
+ switch(m_currentPage)
+ {
+ case MENU_PAGE_MAIN:
+ if( m_pMenu->GetSelection() == m_menuGroupStartIndex[m_currentPage] )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_MAINMENU_LABELS-1));
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ break;
+ case MENU_PAGE_CHARACTERCONTROLS:
+ {
+ int menuItem = m_pMenu->GetSelection();
+ // On the first element on keyboard Map 1
+ if( menuItem == m_menuGroupStartIndex[m_currentPage] )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_CHARACTERCONTROL_LABELS-1));
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ else if( menuItem == m_menuGroupStartIndex[m_currentPage]+NUM_CHARACTERCONTROL_LABELS )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_CHARACTERCONTROL_LABELS*2)-1);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ }
+
+ break;
+ case MENU_PAGE_VEHICLECONTROLS:
+ {
+ int menuItem = m_pMenu->GetSelection();
+ // On the first element on gamepad Map 1
+ if( menuItem == m_menuGroupStartIndex[m_currentPage] )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_VEHICLECONTROL_LABELS-1));
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ else if( menuItem == m_menuGroupStartIndex[m_currentPage]+NUM_VEHICLECONTROL_LABELS )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_VEHICLECONTROL_LABELS*2)-1);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ }
+ case MENU_PAGE_GAMESETTINGS:
+ {
+ int menuItem = m_pMenu->GetSelection();
+ // On the first element on gamepad Map 1
+ if( menuItem == m_menuGroupStartIndex[m_currentPage] )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_GAMESETTING_LABELS-1));
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case GUI_MSG_CONTROLLER_DOWN:
+ {
+ // Basically a wrap around system when you reach the bottom.
+ // Just jumps to the first element.
+ switch(m_currentPage)
+ {
+ case MENU_PAGE_MAIN:
+ if( m_pMenu->GetSelection() == m_menuGroupStartIndex[m_currentPage]+(NUM_MAINMENU_LABELS-1) )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ break;
+ case MENU_PAGE_CHARACTERCONTROLS:
+ {
+ int menuItem = m_pMenu->GetSelection();
+ // On the first element on keyboard Map 1
+ if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_CHARACTERCONTROL_LABELS-1) )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ else if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_CHARACTERCONTROL_LABELS*2)-1 )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+NUM_CHARACTERCONTROL_LABELS);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ }
+
+ break;
+ case MENU_PAGE_VEHICLECONTROLS:
+ {
+ int menuItem = m_pMenu->GetSelection();
+ // On the first element on gamepad Map 1
+ if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_VEHICLECONTROL_LABELS-1) )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ else if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_VEHICLECONTROL_LABELS*2)-1 )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+NUM_VEHICLECONTROL_LABELS);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ }
+
+ break;
+
+ case MENU_PAGE_GAMESETTINGS:
+ {
+ int menuItem = m_pMenu->GetSelection();
+ // On the first element on gamepad Map 1
+ if( menuItem == m_menuGroupStartIndex[m_currentPage]+NUM_GAMESETTING_LABELS-1 )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case GUI_MSG_CONTROLLER_LEFT:
+ case GUI_MSG_CONTROLLER_RIGHT:
+ {
+ // Basically a wrap around system when you go left or right.
+ switch(m_currentPage)
+ {
+ case MENU_PAGE_CHARACTERCONTROLS:
+ {
+ int menuItem = m_pMenu->GetSelection();
+ // On Map 1
+ if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_CHARACTERCONTROL_LABELS )
+ {
+ m_pMenu->Reset(menuItem+NUM_CHARACTERCONTROL_LABELS);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ else // On Map 2
+ {
+ m_pMenu->Reset(menuItem-NUM_CHARACTERCONTROL_LABELS);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ }
+
+ break;
+ case MENU_PAGE_VEHICLECONTROLS:
+ {
+ int menuItem = m_pMenu->GetSelection();
+ // On Map 1
+ if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_VEHICLECONTROL_LABELS )
+ {
+ m_pMenu->Reset(menuItem+NUM_VEHICLECONTROL_LABELS);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ else // On Map 2
+ {
+ m_pMenu->Reset(menuItem-NUM_VEHICLECONTROL_LABELS);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ }
+
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ // guiscreencontrollerwin32 is a circumvention of normal ENTER/EXIT
+ // WINDOW front-end scheme. Since we are disabling the mouse
+ // each time a selection has been made, we need to re-enable
+ // it for this situation, when you transit from some screen to
+ // one of these screens, so the mouse continues to function normally.
+ //
+ GetInputManager()->GetFEMouse()->SetSelectable( true );
+
+ switch( m_currentPage )
+ {
+ case MENU_PAGE_MAIN:
+ {
+ switch( param1 )
+ {
+ case MENU_ITEM_CHARACTERCONTROLS:
+ {
+ GetInputManager()->GetFEMouse()->SetClickStopMode( true );
+ SetPageVisiblility( szMainControllerPage, false );
+ SetPageVisiblility( szCCPage, true );
+ m_currentPage = MENU_PAGE_CHARACTERCONTROLS;
+ break;
+ }
+ case MENU_ITEM_VEHICLECONTROLS:
+ {
+ GetInputManager()->GetFEMouse()->SetClickStopMode( true );
+ SetPageVisiblility( szMainControllerPage, false );
+ SetPageVisiblility( szVCPage, true );
+ m_currentPage = MENU_PAGE_VEHICLECONTROLS;
+ break;
+ }
+ case MENU_ITEM_GAMESETTINGS:
+ {
+ SetPageVisiblility( szMainControllerPage, false );
+ SetPageVisiblility( szGSPage, true );
+ m_currentPage = MENU_PAGE_GAMESETTINGS;
+ break;
+ }
+ case MENU_ITEM_RESTOREALLDEFAULTS:
+ {
+ rAssert( m_guiManager );
+ GetInputManager()->GetFEMouse()->SetSelectable( true );
+ m_guiManager->DisplayPrompt( PROMPT_CONFIRM_RESTOREALLDEFAULTS, this );
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ } break;
+ case MENU_PAGE_CHARACTERCONTROLS:
+ {
+ // if we're on Map 1 or Map 2
+ if( param1 >= (unsigned int)m_menuGroupStartIndex[m_currentPage] )
+ {
+ int menuItem = param1;
+ // On Map 1
+ if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_CHARACTERCONTROL_LABELS )
+ {
+ // We know what map it is so just convert this into a value between 0 - NUM_CHARACTERCONTROL_LABELS-1
+ menuItem = menuItem - m_menuGroupStartIndex[m_currentPage];
+ RemapButton( MAP_PRIMARY, menuItem );
+ break;
+ }
+ else // On Map 2
+ {
+ menuItem = menuItem - m_menuGroupStartIndex[m_currentPage] - NUM_CHARACTERCONTROL_LABELS;
+ RemapButton( MAP_SECONDARY, menuItem );
+ break;
+ }
+ }
+ } break;
+ case MENU_PAGE_VEHICLECONTROLS:
+ {
+ if( param1 >= (unsigned int)m_menuGroupStartIndex[m_currentPage] )
+ {
+ int menuItem = param1;
+ // On Map 1
+ if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_VEHICLECONTROL_LABELS )
+ {
+ // We know what map it is so just convert this into a value between 0 - NUM_CHARACTERCONTROL_LABELS-1
+ menuItem = menuItem - m_menuGroupStartIndex[m_currentPage];
+ RemapButton( MAP_PRIMARY, menuItem );
+ break;
+ }
+ else // On Map 2
+ {
+ menuItem = menuItem - m_menuGroupStartIndex[m_currentPage] - NUM_VEHICLECONTROL_LABELS;
+ RemapButton( MAP_SECONDARY, menuItem );
+ break;
+ }
+ }
+ } break;
+ default: break;
+ }
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ // mapping an input, so any key to trigger this event should be ignored.
+ if( !m_bDisableBack )
+ {
+ switch( m_currentPage )
+ {
+ case MENU_PAGE_CHARACTERCONTROLS:
+ GetInputManager()->GetFEMouse()->SetClickStopMode( false );
+ SetPageVisiblility( szCCPage, false );
+ SetPageVisiblility( szMainControllerPage, true );
+ m_currentPage = MENU_PAGE_MAIN;
+ bRelayMessage = false;
+ break;
+ case MENU_PAGE_VEHICLECONTROLS:
+ GetInputManager()->GetFEMouse()->SetClickStopMode( false );
+ SetPageVisiblility( szVCPage, false );
+ SetPageVisiblility( szMainControllerPage, true );
+ m_currentPage = MENU_PAGE_MAIN;
+ bRelayMessage = false;
+ break;
+ case MENU_PAGE_GAMESETTINGS:
+ SetPageVisiblility( szGSPage, false );
+ SetPageVisiblility( szMainControllerPage, true );
+ m_currentPage = MENU_PAGE_MAIN;
+ bRelayMessage = false;
+ break;
+
+ default:
+ this->StartTransitionAnimation( 560, 590 );
+ bRelayMessage = true;
+ }
+ }
+ else
+ {
+ m_bDisableBack = false;
+ bRelayMessage = false;
+ }
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( m_pMenu != NULL && !m_bMapInput )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ if( bRelayMessage )
+ CGuiScreen::HandleMessage( message, param1, param2 );
+ else
+ bRelayMessage = true;
+}
+
+//===========================================================================
+// CGuiScreen::CheckCursorAgainstHotspots
+//===========================================================================
+// Description: Checks cursor position against its list of hotspots.
+//
+// Constraints: None.
+//
+// Parameters: float x - The x position of cursor in P3D coordinates.
+// float y - The y position of cursor in P3D coordinates.
+//
+// Return: N/A.
+//
+//===========================================================================
+eFEHotspotType CGuiScreenController::CheckCursorAgainstHotspots( float x, float y )
+{
+ if( m_bMapInput ) return HOTSPOT_NONE;
+ else return CGuiScreen::CheckCursorAgainstHotspots( x, y );
+}
+
+void CGuiScreenController::RemapButton( eControllerColumn column, int menuItem )
+{
+ switch(m_currentPage)
+ {
+ case MENU_PAGE_CHARACTERCONTROLS:
+ m_currentTextLabel = m_pCCLabels[column][menuItem];
+ break;
+ case MENU_PAGE_VEHICLECONTROLS:
+ m_currentTextLabel = m_pVCLabels[column][menuItem];
+ break;
+ default:
+ break;
+ }
+ if( m_currentTextLabel )
+ m_currentTextLabel->SetColour(DEFAULT_INPUTMAPPED_ITEM_COLOUR);
+
+ GetInputManager()->GetController(m_currentControllerID)->RemapButton( column,
+ GetVirtualKey(m_currentPage, menuItem),
+ this );
+ GetInputManager()->GetFEMouse()->SetSelectable( false );
+ m_bMapInput = true;
+}
+
+//===========================================================================
+// CGuiScreenController::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenController::InitIntro()
+{
+ // Init the page labels.
+ InitPageLabels(MENU_PAGE_CHARACTERCONTROLS);
+ InitPageLabels(MENU_PAGE_VEHICLECONTROLS);
+
+ UserController* pController = GetInputManager()->GetController( m_currentControllerID );
+ GuiMenuItem* pMenuItem = NULL;
+ // This is the real menuItem index.
+ int menuItem = m_menuGroupStartIndex[MENU_PAGE_GAMESETTINGS];
+
+ // This is relative to the enum section for GAME SETTINGS.
+ int relMenuItem = m_menuGroupStartIndex[MENU_PAGE_GAMESETTINGS] -
+ NUM_CHARACTERCONTROL_LABELS -
+ NUM_VEHICLECONTROL_LABELS;
+
+ rAssert( m_pMenu );
+
+ for( int i = 0; i < NUM_GAMESETTING_LABELS; i++, menuItem++, relMenuItem++ )
+ {
+ switch( relMenuItem )
+ {
+ case GS_MOUSELOOK:
+ {
+ m_pMenu->SetSelectionValue( menuItem, pController->IsMouseLookOn() == PROMPT_YES );
+ }
+ break;
+ case GS_MOUSESENSITIVITY_X:
+ {
+ pMenuItem = m_pMenu->GetMenuItem( menuItem );
+ rAssert( pMenuItem );
+ pMenuItem->m_slider.SetValue( pController->GetMouseSensitivityX() );
+ }
+ break;
+ case GS_MOUSESENSITIVITY_Y:
+ {
+ pMenuItem = m_pMenu->GetMenuItem( menuItem );
+ rAssert( pMenuItem );
+ pMenuItem->m_slider.SetValue( pController->GetMouseSensitivityY() );
+ }
+ break;
+ case GS_INVERTMOUSEX:
+ {
+ m_pMenu->SetSelectionValue( menuItem, pController->IsMouseXInverted() == PROMPT_YES );
+ }
+ break;
+ case GS_INVERTMOUSEY:
+ {
+ m_pMenu->SetSelectionValue( menuItem, pController->IsMouseYInverted() == PROMPT_YES );
+ }
+ break;
+ case GS_FORCEFEEDBACK:
+ {
+ m_pMenu->SetSelectionValue( menuItem, pController->IsForceFeedbackOn() == PROMPT_YES );
+ }
+ break;
+ case GS_WHEELSENSITIVITY:
+ {
+ pMenuItem = m_pMenu->GetMenuItem( menuItem );
+ rAssert( pMenuItem );
+ pMenuItem->m_slider.SetValue( pController->GetWheelSensitivityX() );
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenController::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenController::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenController::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenController::InitOutro()
+{
+ GetInputManager()->GetFEMouse()->SetClickStopMode( false );
+
+ // Save the new controller mappings to the config file.
+ GetGameConfigManager()->SaveConfigFile();
+}
+
+//===========================================================================
+// CGuiScreenController::OnButtonMapped
+//===========================================================================
+// Description: Gets called back by the UserController when a button is
+// mapped.
+//
+// Constraints: None.
+//
+// Parameters: szNewInput - The new input that just got mapped.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenController::OnButtonMapped( const char* szNewInput, eControllerType cont, int num_dirs, eDirectionType direction )
+{
+ char szText[255];
+ memset( szText, 0, sizeof( szText) );
+
+ if( !szNewInput ) //user cancelled the mapper event.
+ {
+ m_bDisableBack = true;
+ }
+ else
+ {
+ // Reset flags we changed.
+ if( m_currentTextLabel )
+ m_currentTextLabel->SetColour(DEFAULT_SELECTED_ITEM_COLOUR);
+
+ strcpy( szText, szNewInput );
+ GetAppropriateInputName( szText, cont, direction, num_dirs );
+
+ //Update the page labels.
+ UpdatePageLabels( m_currentPage, szText );
+
+ //Disable the tutorials if controls are changed.
+ GetInputManager()->GetController(0)->SetTutorialDisabled( true );
+ GetTutorialManager()->EnableTutorialMode( false );
+ }
+
+ GetInputManager()->GetFEMouse()->SetSelectable( true );
+ m_bMapInput = false;
+ m_currentTextLabel = NULL;
+}
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+void CGuiScreenController::UpdatePageLabels( eMenuPages page, const char* szNewInput )
+{
+ switch( page )
+ {
+ case MENU_PAGE_CHARACTERCONTROLS:
+ if( szNewInput )
+ {
+ //Search for this text in the array of texts to see if it already exists.
+ for( int mapCount = 0; mapCount < NUM_COLUMNS; mapCount++ )
+ {
+ for( int itemCount = 0; itemCount < NUM_CHARACTERCONTROL_LABELS; itemCount++ )
+ {
+ UnicodeString uniStrTemp = m_pCCLabels[mapCount][itemCount]->GetString();
+ char tempStr[255];
+ memset( tempStr, 0, sizeof( tempStr ) );
+ uniStrTemp.MakeAscii( tempStr, uniStrTemp.Length() + 1 );
+ if( strcmp( szNewInput, tempStr ) == 0 )
+ {
+ m_pCCLabels[mapCount][itemCount]->SetString(0, szNotAssigned);
+ break;
+ }
+ }
+ }
+ }
+
+ break;
+ case MENU_PAGE_VEHICLECONTROLS:
+ if( szNewInput )
+ {
+ //Search for this text in the array of texts to see if it already exists.
+ for( int mapCount = 0; mapCount < NUM_COLUMNS; mapCount++ )
+ {
+ for( int itemCount = 0; itemCount < NUM_VEHICLECONTROL_LABELS; itemCount++ )
+ {
+ UnicodeString uniStrTemp = m_pVCLabels[mapCount][itemCount]->GetString();
+ char tempStr[255];
+ memset( tempStr, 0, sizeof( tempStr ) );
+ uniStrTemp.MakeAscii( tempStr, uniStrTemp.Length() + 1 );
+ if( strcmp( szNewInput, tempStr ) == 0 )
+ {
+ m_pVCLabels[mapCount][itemCount]->SetString(0, szNotAssigned);
+ break;
+ }
+ }
+ }
+ }
+
+ break;
+ default:
+ break;
+ }
+ if( m_currentTextLabel )
+ m_currentTextLabel->SetString(0, szNewInput);
+}
+
+void CGuiScreenController::InitPageLabels( eMenuPages page )
+{
+ UserController* pController = GetInputManager()->GetController(m_currentControllerID);
+
+ switch( page )
+ {
+ case MENU_PAGE_CHARACTERCONTROLS:
+ {
+ // Go through the elements and set the maps.
+ for( int mapCount = 0; mapCount < NUM_COLUMNS; mapCount++ )
+ {
+ eControllerType controllerType;
+ int ndirections;
+ eDirectionType dir;
+
+ for( int i = 0; i < NUM_CONTROLLERTYPES; i++ )
+ {
+ for( int ccItem = 0; ccItem < NUM_CHARACTERCONTROL_LABELS; ccItem++ )
+ {
+ const char* szName = pController->GetMap( mapCount,
+ GetVirtualKey(MENU_PAGE_CHARACTERCONTROLS,ccItem),
+ ndirections, controllerType, dir );
+ if( szName )
+ {
+ char szText[255];
+ memset( szText, 0, sizeof( szText) );
+
+ strcpy( szText, szName );
+ GetAppropriateInputName( szText, controllerType, dir, ndirections );
+ m_pCCLabels[mapCount][ccItem]->SetString(0, szText);
+ }
+ else
+ {
+ m_pCCLabels[mapCount][ccItem]->SetString(0, szNotAssigned);
+ }
+ }
+ }
+ }
+ } break;
+ case MENU_PAGE_VEHICLECONTROLS:
+ {
+ // Go through the elements and set the maps.
+ for( int mapCount = 0; mapCount < NUM_COLUMNS; mapCount++ )
+ {
+ eControllerType controllerType;
+ int ndirections;
+ eDirectionType dir;
+
+ for( int i = 0; i < NUM_CONTROLLERTYPES; i++ )
+ {
+ for( int ccItem = 0; ccItem < NUM_VEHICLECONTROL_LABELS; ccItem++ )
+ {
+ const char* szName = pController->GetMap( mapCount,
+ GetVirtualKey(MENU_PAGE_VEHICLECONTROLS,ccItem),
+ ndirections, controllerType, dir );
+ if( szName )
+ {
+ char szText[255];
+ memset( szText, 0, sizeof( szText) );
+
+ strcpy( szText, szName );
+ GetAppropriateInputName( szText, controllerType, dir, ndirections );
+ m_pVCLabels[mapCount][ccItem]->SetString(0, szText);
+ }
+ else
+ {
+ m_pVCLabels[mapCount][ccItem]->SetString(0, szNotAssigned);
+ }
+ }
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+
+}
+
+void CGuiScreenController::SetGroups( Scrooby::Text** pLabels,
+ int numMenuItems,
+ const char* strPage,
+ char* strGroup,
+ char* szLabel,
+ int attributes )
+{
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( strPage );
+ rAssert( pPage );
+
+
+ // if this is a controller page set the start index of its menu items.
+ if( m_numControllerGroups < NUM_MENU_PAGES )
+ {
+ if( strcmp( strGroup, "Map1" ) == 0 || strcmp( strPage, szGSPage ) == 0 )
+ {
+ m_menuGroupStartIndex[m_numControllerGroups++] = m_pMenu->GetNumItems();
+ }
+ }
+
+ // Add main menu items
+ Scrooby::Group* pMenuGroup = pPage->GetGroup( strGroup );
+ for( int itemCount = 0; itemCount < numMenuItems; itemCount++ )
+ {
+ char objectName[ 32 ];
+ sprintf( objectName, "%s%02d", szLabel, itemCount );
+ Scrooby::Text* pMenuItemText = pMenuGroup->GetText( objectName );
+ if( pMenuItemText != NULL )
+ {
+ pMenuItemText->SetTextMode( Scrooby::TEXT_WRAP );
+
+ char itemName[32];
+ sprintf( itemName, "%s%02d_Value", szLabel, itemCount );
+ Scrooby::Text* pTextValue = pMenuGroup->GetText( itemName );
+
+ sprintf( itemName, "%s%02d_ArrowL", szLabel, itemCount );
+ Scrooby::Sprite* pLArrow = pMenuGroup->GetSprite( itemName );
+
+ sprintf( itemName, "%s%02d_ArrowR", szLabel, itemCount );
+ Scrooby::Sprite* pRArrow = pMenuGroup->GetSprite( itemName );
+
+ sprintf( itemName, "%s%02d_Slider", szLabel, itemCount );
+ Scrooby::Sprite* pSlider = pMenuGroup->GetSprite( itemName );
+
+ GuiMenuItem* pMenuItem = m_pMenu->AddMenuItem( pMenuItemText,
+ pTextValue,
+ NULL,
+ pSlider,
+ pLArrow,
+ pRArrow,
+ attributes );
+ pLabels[itemCount] = pMenuItemText;
+
+ if( pSlider )
+ pMenuItem->m_slider.m_type = Slider::HORIZONTAL_SLIDER_ABOUT_CENTER;
+ }
+ else
+ {
+ break;
+ }
+ }
+}
+
+void CGuiScreenController::SetPageVisiblility( const char* strPage, bool bVisible )
+{
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( strPage );
+ rAssert( pPage );
+ pPage->GetLayerByIndex( 0 )->SetVisible( bVisible );
+
+ //if it is any of our pages, set all their menu items to bVisible.
+ if( strcmp( strPage, szMainControllerPage ) == 0 )
+ {
+ for( int i = 0; i < NUM_MAINMENU_LABELS; i++ )
+ m_pMenuLabels[i]->SetVisible( bVisible );
+ if( bVisible )
+ m_pMenu->Reset( MENU_ITEM_CHARACTERCONTROLS );
+ }
+ else if( strcmp( strPage, szGSPage ) == 0 )
+ {
+ for( int i = 0; i < NUM_GAMESETTING_LABELS; i++ )
+ m_pMSLabels[i]->SetVisible( bVisible );
+ if( bVisible )
+ m_pMenu->Reset( m_menuGroupStartIndex[MENU_PAGE_GAMESETTINGS] );
+ }
+ else if( strcmp( strPage, szCCPage ) == 0 )
+ {
+ for( int columnCount = 0; columnCount < NUM_COLUMNS; columnCount++ )
+ for( int labelCount = 0; labelCount < NUM_CHARACTERCONTROL_LABELS; labelCount++ )
+ m_pCCLabels[columnCount][labelCount]->SetVisible( bVisible );
+ if( bVisible )
+ m_pMenu->Reset( m_menuGroupStartIndex[MENU_PAGE_CHARACTERCONTROLS] );
+ }
+ else if( strcmp( strPage, szVCPage ) == 0 )
+ {
+ for( int columnCount = 0; columnCount < NUM_COLUMNS; columnCount++ )
+ for( int labelCount = 0; labelCount < NUM_VEHICLECONTROL_LABELS; labelCount++ )
+ m_pVCLabels[columnCount][labelCount]->SetVisible( bVisible );
+ if( bVisible )
+ m_pMenu->Reset( m_menuGroupStartIndex[MENU_PAGE_VEHICLECONTROLS] );
+ }
+}
+
+int CGuiScreenController::GetVirtualKey( eMenuPages page, int menuItem )
+{
+ // We have to start the menuitem off at the correct index.
+ // This is simple, just add the menuitem with the correct start index.
+ switch(page)
+ {
+ case MENU_PAGE_CHARACTERCONTROLS:
+ menuItem += CC_MOVEUP;
+ break;
+ case MENU_PAGE_VEHICLECONTROLS:
+ menuItem += VC_ACCELERATE;
+ break;
+ default:
+ break;
+ }
+
+ switch(menuItem)
+ {
+ case CC_MOVEUP:
+ return InputManager::MoveUp;
+ case CC_MOVEDOWN:
+ return InputManager::MoveDown;
+ case CC_MOVELEFT:
+ return InputManager::MoveLeft;
+ case CC_MOVERIGHT:
+ return InputManager::MoveRight;
+ case CC_ATTACK:
+ return InputManager::Attack;
+ case CC_JUMP:
+ return InputManager::Jump;
+ case CC_SPRINT:
+ return InputManager::Sprint;
+ case CC_ACTION:
+ return InputManager::DoAction;
+ case CC_CAMERALEFT:
+ return InputManager::CameraLeft;
+ case CC_CAMERARIGHT:
+ return InputManager::CameraRight;
+ case CC_CAMERAMOVEIN:
+ return InputManager::CameraMoveIn;
+ case CC_CAMERAMOVEOUT:
+ return InputManager::CameraMoveOut;
+ case CC_LOOKUP:
+ return InputManager::CameraLookUp;
+ case CC_ZOOM:
+ return InputManager::CameraZoom;
+
+ case VC_ACCELERATE:
+ return InputManager::Accelerate;
+ case VC_REVERSE:
+ return InputManager::Reverse;
+ case VC_STEERLEFT:
+ return InputManager::SteerLeft;
+ case VC_STEERRIGHT:
+ return InputManager::SteerRight;
+ case VC_EBRAKE:
+ return InputManager::HandBrake;
+ case VC_ACTION:
+ return InputManager::GetOutCar;
+ case VC_HORN:
+ return InputManager::Horn;
+ case VC_RESET:
+ return InputManager::ResetCar;
+ case VC_LOOKLEFT:
+ return InputManager::CameraCarLeft;
+ case VC_LOOKRIGHT:
+ return InputManager::CameraCarRight;
+ case VC_LOOKUP:
+ return InputManager::CameraCarLookUp;
+ case VC_LOOKBACK:
+ return InputManager::CameraCarLookBack;
+ case VC_CHANGECAMERA:
+ return InputManager::CameraToggle;
+ default:
+ return 0;
+ }
+}
+
+void CGuiScreenController::GetAppropriateInputName( char* szInputName,
+ eControllerType controllerType,
+ eDirectionType direction,
+ int numDirections )
+{
+ char szText[255];
+ memset( szText, 0, sizeof( szText) );
+
+ if( szInputName )
+ {
+ // Do some hacky special casing here.
+ // Only done for the keyboard atm.
+ switch( controllerType )
+ {
+ case KEYBOARD:
+ {
+ // Special cases.
+ if( strcmp( szInputName, "Right Shift" ) == 0 )
+ strcpy( szInputName, "R. Shift" );
+ else if( strcmp( szInputName, "Left Shift" ) == 0 )
+ strcpy( szInputName, "L. Shift" );
+ }
+
+ break;
+ }
+ // truncate the name to the max allowed letters.
+ if( strlen(szInputName) > MAX_INPUTNAME_LENGTH )
+ {
+ szInputName[MAX_INPUTNAME_LENGTH-1] = '\0';
+ }
+ switch( controllerType )
+ {
+ case GAMEPAD:
+ case STEERINGWHEEL:
+ {
+ switch( numDirections )
+ {
+ case 2:
+ switch( direction )
+ {
+ case DIR_UP:
+ strcat( szInputName, " +");
+ break;
+ case DIR_DOWN:
+ strcat( szInputName, " -");
+ break;
+ default:
+ break;
+ }
+ break;
+ case 4: // It is a POV hat...
+ switch( direction )
+ {
+ case DIR_UP:
+ strcpy( szInputName,"POV Up" );
+ break;
+ case DIR_DOWN:
+ strcpy( szInputName,"POV Down" );
+ break;
+ case DIR_LEFT:
+ strcpy( szInputName,"POV Left" );
+ break;
+ case DIR_RIGHT:
+ strcpy( szInputName,"POV Right" );
+ break;
+ }
+ break;
+ }
+
+ switch( controllerType )
+ {
+ case GAMEPAD:
+ sprintf( szText,"J %s", szInputName );
+ strcpy( szInputName, szText );
+ break;
+ case STEERINGWHEEL:
+ sprintf( szText,"S %s", szInputName );
+ strcpy( szInputName, szText );
+ break;
+ }
+
+ break;
+ }
+ case MOUSE:
+ {
+ if( strchr( szInputName, '0' ) )
+ strcpy( szInputName,"Left Mouse" );
+ else if( strchr( szInputName, '1' ) )
+ strcpy( szInputName,"Right Mouse" );
+ else if( strchr( szInputName, '2' ) )
+ strcpy( szInputName,"Mid Mouse" );
+ else if( strchr( szInputName, '3' ) )
+ strcpy( szInputName,"Shoulder L" );
+ else if( strchr( szInputName, '4' ) )
+ strcpy( szInputName,"Shoulder R" );
+ else if( strchr( szInputName, '5' ) )
+ strcpy( szInputName,"Side Left" );
+ else if( strchr( szInputName, '6' ) )
+ strcpy( szInputName,"Side Right" );
+ }
+
+ break;
+ default:
+ break;
+ }
+ }
+} \ No newline at end of file
diff --git a/game/code/presentation/gui/frontend/guiscreencontrollerWin32.h b/game/code/presentation/gui/frontend/guiscreencontrollerWin32.h
new file mode 100644
index 0000000..d90a005
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreencontrollerWin32.h
@@ -0,0 +1,163 @@
+/******************************************************************************
+
+ File: GuiScreenControllerWin32.h
+ Desc: Interface for the CGuiScreenController class.
+
+ Date: July 31, 2003
+ Author: Neil Haran
+ History:
+
+*****************************************************************************/
+
+#ifndef GUISCREENCONTROLLER_H
+#define GUISCREENCONTROLLER_H
+
+#include <presentation/gui/guiscreen.h>
+#include <input/usercontrollerWin32.h>
+
+class CGuiScreenController : public CGuiScreen,
+ public ButtonMappedCallback
+{
+public:
+ CGuiScreenController( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenController();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+ virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y );
+ virtual void OnButtonMapped( const char* InputName, eControllerType cont, int num_dirs, eDirectionType direction );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ enum eControllerPromptResponse
+ {
+ PROMPT_NO,
+ PROMPT_YES,
+ NUM_CONTROLLER_PROMPT_RESPONSES
+ };
+
+ enum eControllerColumn
+ {
+ MAP_PRIMARY = 0,
+ MAP_SECONDARY,
+ NUM_COLUMNS,
+ };
+
+ enum eMenuPages
+ {
+ MENU_PAGE_MAIN,
+ MENU_PAGE_CHARACTERCONTROLS,
+ MENU_PAGE_VEHICLECONTROLS,
+ MENU_PAGE_GAMESETTINGS,
+ NUM_MENU_PAGES,
+ NUM_CONTROLLER_PAGES = NUM_MENU_PAGES - 1,
+ MENU_PAGE_NONE
+ };
+
+ enum eMenuItem
+ {
+ // MAIN CONTROLLER MENU ITEMS
+ MENU_ITEM_CHARACTERCONTROLS = 0,
+ MENU_ITEM_VEHICLECONTROLS,
+ MENU_ITEM_GAMESETTINGS,
+ MENU_ITEM_RESTOREALLDEFAULTS,
+ MENU_ITEM_NONE,
+ NUM_MAINMENU_LABELS = MENU_ITEM_NONE,
+
+ // Character Control ITEMS
+ CC_MOVEUP = MENU_ITEM_NONE,
+ CC_MOVEDOWN,
+ CC_MOVELEFT,
+ CC_MOVERIGHT,
+ CC_ATTACK,
+ CC_JUMP,
+ CC_SPRINT,
+ CC_ACTION,
+ CC_CAMERALEFT,
+ CC_CAMERARIGHT,
+ CC_CAMERAMOVEIN,
+ CC_CAMERAMOVEOUT,
+ CC_ZOOM,
+ CC_LOOKUP,
+ CC_NONE,
+ NUM_CHARACTERCONTROL_LABELS = CC_NONE - MENU_ITEM_NONE,
+
+ // Vehicle Control ITEMS
+ VC_ACCELERATE = CC_NONE,
+ VC_REVERSE,
+ VC_STEERLEFT,
+ VC_STEERRIGHT,
+ VC_EBRAKE,
+ VC_ACTION,
+ VC_HORN,
+ VC_RESET,
+ VC_LOOKLEFT,
+ VC_LOOKRIGHT,
+ VC_LOOKUP,
+ VC_LOOKBACK,
+ VC_CHANGECAMERA,
+
+ VC_NONE,
+ NUM_VEHICLECONTROL_LABELS = VC_NONE - CC_NONE,
+
+ // Game Setting Items
+ GS_MOUSELOOK = VC_NONE,
+ GS_MOUSESENSITIVITY_X,
+ GS_MOUSESENSITIVITY_Y,
+ GS_INVERTMOUSEX,
+ GS_INVERTMOUSEY,
+ GS_FORCEFEEDBACK,
+ GS_WHEELSENSITIVITY,
+ GS_NONE,
+ NUM_GAMESETTING_LABELS = GS_NONE - VC_NONE,
+
+ NUM_MENU_ITEMS = NUM_MAINMENU_LABELS +
+ NUM_CHARACTERCONTROL_LABELS*NUM_COLUMNS +
+ NUM_VEHICLECONTROL_LABELS*NUM_COLUMNS +
+ NUM_GAMESETTING_LABELS
+ };
+
+private:
+ void InitPageLabels( eMenuPages page );
+ void UpdatePageLabels( eMenuPages page, const char* szNewInput );
+ void SetGroups( Scrooby::Text** pLabels,
+ int numMenuItems,
+ const char* strPage,
+ char* strGroup = "Menu",
+ char* szLabel = "Label",
+ int attributes = SELECTION_ENABLED | SELECTABLE | VALUES_WRAPPED );
+
+ void SetPageVisiblility( const char* strPage, bool bVisible );
+ int GetVirtualKey( eMenuPages page, int menuItem );
+ void RemapButton( eControllerColumn column, int menuItem );
+ void GetAppropriateInputName( char* szInputName,
+ eControllerType controllerType,
+ eDirectionType direction,
+ int numDirections );
+
+private:
+ CGuiMenu* m_pMenu;
+ Scrooby::Text* m_pMenuLabels[ NUM_MAINMENU_LABELS ];
+ Scrooby::Text* m_pCCLabels[ NUM_COLUMNS ][ NUM_CHARACTERCONTROL_LABELS ];
+ Scrooby::Text* m_pVCLabels[ NUM_COLUMNS ][ NUM_VEHICLECONTROL_LABELS ];
+ Scrooby::Text* m_pMSLabels[ NUM_GAMESETTING_LABELS ];
+ Scrooby::Text* m_currentTextLabel;
+
+ // These arrays are for the screen mappings.
+ eMenuPages m_currentPage;
+ int m_currentControllerID;
+ bool m_bMapInput;
+ bool m_bDisableBack;
+ int m_menuGroupStartIndex[NUM_MENU_PAGES];
+ int m_numControllerGroups;
+};
+
+#endif
diff --git a/game/code/presentation/gui/frontend/guiscreencontrollerWin32old.cpp b/game/code/presentation/gui/frontend/guiscreencontrollerWin32old.cpp
new file mode 100644
index 0000000..5309702
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreencontrollerWin32old.cpp
@@ -0,0 +1,867 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenController
+//
+// Description: Implementation of the CGuiScreenController class.
+//
+// Authors: Tony Chu,
+// Neil Haran
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreencontrollerWin32.h>
+#include <presentation/gui/guimenu.h>
+
+#include <data/config/gameconfigmanager.h>
+#include <input/inputmanager.h>
+#include <memory/srrmemory.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <events/eventmanager.h>
+
+#include <raddebug.hpp> // Foundation
+#include <group.h>
+#include <layer.h>
+#include <page.h>
+#include <screen.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const char* szMainControllerPage = "ControllerPC";
+const char* szKeyboardMousePage = "PCKeyboardConfig";
+const char* szGamepadPage = "PCGamepadConfig";
+
+const int NUM_DISPLAY_MODES = 2;
+extern const char* gVirtualInputs[];
+
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+const tColour DEFAULT_SELECTED_ITEM_COLOUR( 255, 255, 0 );
+const tColour DEFAULT_INPUTMAPPED_ITEM_COLOUR( 255, 0, 0 ); // the same as in guiscreenmemorycard.cpp
+
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenController::CGuiScreenController
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenController::CGuiScreenController
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_CONTROLLER ),
+ m_pMenu( NULL ),
+ m_currentPage( MENU_PAGE_MAIN ),
+ m_currentControllerID( 0 ),
+ m_bMapInput( false ),
+ m_currentTextLabel(NULL),
+ m_bDisableBack(false),
+ m_numControllerGroups(0)
+{
+ memset( m_menuGroupStartIndex, 0 , sizeof( m_menuGroupStartIndex ) );
+ m_pMenu = new(GMA_LEVEL_FE) CGuiMenu( this, NUM_MENU_ITEMS );
+ rAssert( m_pMenu != NULL );
+
+ // Add main menu items
+ SetSingleItemMenuPage( m_pMenuLabels, NUM_MAINMENU_LABELS, szMainControllerPage, "Menu", "Label", ALL_ATTRIBUTES_ON );
+ m_numControllerGroups = 1; // The first page is the MENU_PAGE_MAIN with an index of 0.
+
+ // Add master list items
+ SetSingleItemMenuPage( m_pKMLabels[MASTER_LIST], NUM_KEYBOARDMOUSE_LABELS, szKeyboardMousePage, "Menu", "Label", ALL_ATTRIBUTES_OFF );
+ SetSingleItemMenuPage( m_pGamepadLabels[MASTER_LIST], NUM_GAMEPAD_LABELS, szGamepadPage, "Menu", "Label", ALL_ATTRIBUTES_OFF );
+ // Add map items
+ SetSingleItemMenuPage( m_pKMLabels[MAP_PRIMARY], NUM_KEYBOARDMOUSE_LABELS, szKeyboardMousePage, "Map1", "Map1Label" );
+ SetSingleItemMenuPage( m_pKMLabels[MAP_SECONDARY], NUM_KEYBOARDMOUSE_LABELS, szKeyboardMousePage, "Map2", "Map2Label" );
+ SetSingleItemMenuPage( m_pGamepadLabels[MAP_PRIMARY], NUM_GAMEPAD_LABELS, szGamepadPage, "Map1", "Map1Label" );
+ SetSingleItemMenuPage( m_pGamepadLabels[MAP_SECONDARY], NUM_GAMEPAD_LABELS, szGamepadPage, "Map2", "Map2Label" );
+
+
+ //Turn off the controller page that shows up for the consoles.
+ SetPageVisiblility( "Controller", false );
+ SetPageVisiblility( szMainControllerPage, true );
+}
+
+
+//===========================================================================
+// CGuiScreenController::~CGuiScreenController
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenController::~CGuiScreenController()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenController::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenController::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ static bool bRelayMessage = true;
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_UP:
+ {
+ // Basically a wrap around system when you reach the top.
+ // Just jumps to the last element.
+ switch(m_currentPage)
+ {
+ case MENU_PAGE_MAIN:
+ if( m_pMenu->GetSelection() == m_menuGroupStartIndex[m_currentPage] )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_MAINMENU_LABELS-1));
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ break;
+ case MENU_PAGE_KM:
+ {
+ int menuItem = m_pMenu->GetSelection();
+ // On the first element on keyboard Map 1
+ if( menuItem == m_menuGroupStartIndex[m_currentPage] )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_KEYBOARDMOUSE_LABELS-1));
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ else if( menuItem == m_menuGroupStartIndex[m_currentPage]+NUM_KEYBOARDMOUSE_LABELS )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_KEYBOARDMOUSE_LABELS*2)-1);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ }
+
+ break;
+ case MENU_PAGE_GAMEPAD:
+ {
+ int menuItem = m_pMenu->GetSelection();
+ // On the first element on gamepad Map 1
+ if( menuItem == m_menuGroupStartIndex[m_currentPage] )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_GAMEPAD_LABELS-1));
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ else if( menuItem == m_menuGroupStartIndex[m_currentPage]+NUM_GAMEPAD_LABELS )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+(NUM_GAMEPAD_LABELS*2)-1);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ }
+
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case GUI_MSG_CONTROLLER_DOWN:
+ {
+ // Basically a wrap around system when you reach the bottom.
+ // Just jumps to the first element.
+ switch(m_currentPage)
+ {
+ case MENU_PAGE_MAIN:
+ if( m_pMenu->GetSelection() == m_menuGroupStartIndex[m_currentPage]+(NUM_MAINMENU_LABELS-1) )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ break;
+ case MENU_PAGE_KM:
+ {
+ int menuItem = m_pMenu->GetSelection();
+ // On the first element on keyboard Map 1
+ if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_KEYBOARDMOUSE_LABELS-1) )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ else if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_KEYBOARDMOUSE_LABELS*2)-1 )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+NUM_KEYBOARDMOUSE_LABELS);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ }
+
+ break;
+ case MENU_PAGE_GAMEPAD:
+ {
+ int menuItem = m_pMenu->GetSelection();
+ // On the first element on gamepad Map 1
+ if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_GAMEPAD_LABELS-1) )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ else if( menuItem == m_menuGroupStartIndex[m_currentPage]+(NUM_GAMEPAD_LABELS*2)-1 )
+ {
+ m_pMenu->Reset(m_menuGroupStartIndex[m_currentPage]+NUM_GAMEPAD_LABELS);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ }
+
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case GUI_MSG_CONTROLLER_LEFT:
+ case GUI_MSG_CONTROLLER_RIGHT:
+ {
+ // Basically a wrap around system when you go left or right.
+ switch(m_currentPage)
+ {
+ case MENU_PAGE_KM:
+ {
+ int menuItem = m_pMenu->GetSelection();
+ // On Map 1
+ if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_KEYBOARDMOUSE_LABELS )
+ {
+ m_pMenu->Reset(menuItem+NUM_KEYBOARDMOUSE_LABELS);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ else // On Map 2
+ {
+ m_pMenu->Reset(menuItem-NUM_KEYBOARDMOUSE_LABELS);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ }
+
+ break;
+ case MENU_PAGE_GAMEPAD:
+ {
+ int menuItem = m_pMenu->GetSelection();
+ // On Map 1
+ if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_GAMEPAD_LABELS )
+ {
+ m_pMenu->Reset(menuItem+NUM_GAMEPAD_LABELS);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ else // On Map 2
+ {
+ m_pMenu->Reset(menuItem-NUM_GAMEPAD_LABELS);
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ return;
+ }
+ }
+
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ switch( m_currentPage )
+ {
+ case MENU_PAGE_MAIN:
+ {
+ switch( param1 )
+ {
+ case MENU_ITEM_KEYMOUSECONFIG:
+ {
+ GetInputManager()->GetFEMouse()->SetClickStopMode( true );
+ SetPageVisiblility( szMainControllerPage, false );
+ SetPageVisiblility( szKeyboardMousePage, true );
+ m_currentPage = MENU_PAGE_KM;
+ break;
+ }
+ case MENU_ITEM_GAMEPADCONFIG:
+ {
+ GetInputManager()->GetFEMouse()->SetClickStopMode( true );
+ SetPageVisiblility( szMainControllerPage, false );
+ SetPageVisiblility( szGamepadPage, true );
+ m_currentPage = MENU_PAGE_GAMEPAD;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ } break;
+ case MENU_PAGE_KM:
+ {
+ // if we're on Map 1 or Map 2
+ if( param1 >= (unsigned int)m_menuGroupStartIndex[m_currentPage] )
+ {
+ int menuItem = param1;
+ // On Map 1
+ if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_KEYBOARDMOUSE_LABELS )
+ {
+ // We know what map it is so just convert this into a value between 0 - NUM_KEYBOARDMOUSE_LABELS-1
+ menuItem = menuItem - m_menuGroupStartIndex[m_currentPage];
+ RemapButton( MAP_PRIMARY, KEYBOARD, menuItem );
+ break;
+ }
+ else // On Map 2
+ {
+ menuItem = menuItem - m_menuGroupStartIndex[m_currentPage] - NUM_KEYBOARDMOUSE_LABELS;
+ RemapButton( MAP_SECONDARY, KEYBOARD, menuItem );
+ break;
+ }
+ }
+ } break;
+ case MENU_PAGE_GAMEPAD:
+ {
+ if( param1 >= (unsigned int)m_menuGroupStartIndex[m_currentPage] )
+ {
+ int menuItem = param1;
+ // On Map 1
+ if( menuItem < m_menuGroupStartIndex[m_currentPage] + NUM_GAMEPAD_LABELS )
+ {
+ // We know what map it is so just convert this into a value between 0 - NUM_KEYBOARDMOUSE_LABELS-1
+ menuItem = menuItem - m_menuGroupStartIndex[m_currentPage];
+ RemapButton( MAP_PRIMARY, GAMEPAD, menuItem );
+ break;
+ }
+ else // On Map 2
+ {
+ menuItem = menuItem - m_menuGroupStartIndex[m_currentPage] - NUM_GAMEPAD_LABELS;
+ RemapButton( MAP_SECONDARY, GAMEPAD, menuItem );
+ break;
+ }
+ }
+ } break;
+ default: break;
+ }
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ // mapping an input, so any key to trigger this event should be ignored.
+ if( !m_bDisableBack )
+ {
+ switch( m_currentPage )
+ {
+ case MENU_PAGE_KM:
+ GetInputManager()->GetFEMouse()->SetClickStopMode( false );
+ SetPageVisiblility( szKeyboardMousePage, false );
+ SetPageVisiblility( szMainControllerPage, true );
+ m_currentPage = MENU_PAGE_MAIN;
+ bRelayMessage = false;
+ break;
+ case MENU_PAGE_GAMEPAD:
+ GetInputManager()->GetFEMouse()->SetClickStopMode( false );
+ SetPageVisiblility( szGamepadPage, false );
+ SetPageVisiblility( szMainControllerPage, true );
+ m_currentPage = MENU_PAGE_MAIN;
+ bRelayMessage = false;
+ break;
+
+ default:
+ this->StartTransitionAnimation( 560, 590 );
+ bRelayMessage = true;
+ }
+ }
+ else
+ {
+ m_bDisableBack = false;
+ bRelayMessage = false;
+ }
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( m_pMenu != NULL && !m_bMapInput )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ if( bRelayMessage)
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+void CGuiScreenController::RemapButton( eControllerColumn column, eControllerType type, int menuItem )
+{
+ switch(m_currentPage)
+ {
+ case MENU_PAGE_KM:
+ m_currentTextLabel = m_pKMLabels[column][menuItem];
+ break;
+ case MENU_PAGE_GAMEPAD:
+ m_currentTextLabel = m_pGamepadLabels[column][menuItem];
+ break;
+ default:
+ break;
+ }
+ if( m_currentTextLabel )
+ m_currentTextLabel->SetColour(DEFAULT_INPUTMAPPED_ITEM_COLOUR);
+ GetInputManager()->GetController(m_currentControllerID)->RemapButton( type,
+ (column == MAP_PRIMARY) ? SLOT_PRIMARY : SLOT_SECONDARY,
+ GetVirtualKey(menuItem),
+ this );
+ GetInputManager()->GetFEMouse()->SetSelectable( false );
+ m_bMapInput = true;
+}
+
+//===========================================================================
+// CGuiScreenController::CheckCursorAgainstHotspots
+//===========================================================================
+// Description: Checks cursor position against its list of hotspots.
+//
+// Constraints: None.
+//
+// Parameters: float x - The x position of cursor in P3D coordinates.
+// float y - The y position of cursor in P3D coordinates.
+//
+// Return: N/A.
+//
+//===========================================================================
+eFEHotspotType CGuiScreenController::CheckCursorAgainstHotspots( float x, float y )
+{
+ eFEHotspotType hotSpotType = HOTSPOT_NONE;
+ CGuiMenu* pCurrentMenu = HasMenu();
+ int numMenuItems = 0;
+ GuiMenuItem* pMenuItem = NULL;
+
+
+ if( pCurrentMenu )
+ {
+ numMenuItems = pCurrentMenu->GetNumItems();
+
+ for( int i = 0; i < numMenuItems; i++ )
+ {
+ bool bIsMenuItemEnabled = pCurrentMenu->IsMenuItemEnabled(i);
+ pMenuItem = pCurrentMenu->GetMenuItem( i );
+
+ if( pMenuItem && bIsMenuItemEnabled )
+ {
+ if( pMenuItem->GetItem()->IsVisible() )
+ {
+ // Just tests if the point is in the bounding rect of the sprite.
+ if( pMenuItem->GetItem()->IsPointInBoundingRect( x, y ) )
+ {
+ //rDebugPrintf( "Cursor is inside Sprite %d rectangle!\n", i );
+ pCurrentMenu->HandleMessage( GUI_MSG_MOUSE_OVER, i );
+ hotSpotType = HOTSPOT_BUTTON;
+
+ //After taking care of all the events for this menu item, just bail out.
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return hotSpotType;
+}
+
+void CGuiScreenController::OnButtonMapped( const char* szNewInput )
+{
+ if( szNewInput )
+ {
+ if( m_currentTextLabel )
+ m_currentTextLabel->SetString(0, szNewInput);
+ }
+ else //user cancelled the mapper event.
+ {
+ m_bDisableBack = true;
+ }
+
+ // Reset flags we changed.
+ if( m_currentTextLabel )
+ m_currentTextLabel->SetColour(DEFAULT_SELECTED_ITEM_COLOUR);
+
+ //Update the page labels.
+ UpdatePageLabels(m_currentPage);
+ GetInputManager()->GetFEMouse()->SetSelectable( true );
+ m_bMapInput = false;
+ m_currentTextLabel = NULL;
+}
+
+//===========================================================================
+// CGuiScreenController::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenController::InitIntro()
+{
+ // Init the page labels.
+ UpdatePageLabels(MENU_PAGE_KM);
+ UpdatePageLabels(MENU_PAGE_GAMEPAD);
+}
+
+
+//===========================================================================
+// CGuiScreenController::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenController::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenController::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenController::InitOutro()
+{
+ GetInputManager()->GetFEMouse()->SetClickStopMode( false );
+
+ // Save the new controller mappings to the config file.
+ GetGameConfigManager()->SaveConfigFile();
+}
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void CGuiScreenController::UpdatePageLabels( eMenuPages page )
+{
+ UserController* pController = GetInputManager()->GetController(m_currentControllerID);
+ const char* szNotAssigned = "---";
+ switch( page )
+ {
+ case MENU_PAGE_KM:
+ {
+ RealController* pKeyBoard = pController->GetRealController( KEYBOARD );
+
+ int diMap[NUM_MAPS][NUM_KEYBOARDMOUSE_LABELS] =
+ {
+ pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::MoveUp ),
+ pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::MoveDown ),
+ pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::MoveLeft ),
+ pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::MoveRight ),
+ pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::CameraFirstPerson ),
+ pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::Attack ),
+ pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::Jump ),
+ pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::Sprint ),
+ pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::DoAction ),
+ pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::CameraZoom ),
+ pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::Accelerate ),
+ pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::HandBrake ),
+ pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::Horn ),
+ pKeyBoard->GetMap( SLOT_PRIMARY, InputManager::ResetCar ),
+
+ pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::MoveUp ),
+ pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::MoveDown ),
+ pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::MoveLeft ),
+ pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::MoveRight ),
+ pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::CameraFirstPerson ),
+ pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::Attack ),
+ pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::Jump ),
+ pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::Sprint ),
+ pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::DoAction ),
+ pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::CameraZoom ),
+ pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::Accelerate ),
+ pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::HandBrake ),
+ pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::Horn ),
+ pKeyBoard->GetMap( SLOT_SECONDARY, InputManager::ResetCar ),
+ };
+
+ //Input::INVALID_CONTROLLERID
+
+ for( int column = MAP_PRIMARY, mapCount = 0; column < NUM_COLUMNS; column++, mapCount++ )
+ {
+ for( int kmItem = 0; kmItem < NUM_KEYBOARDMOUSE_LABELS; kmItem++ )
+ {
+ RADCONTROLLER pRadController = pKeyBoard->getController();
+ IRadControllerInputPoint* pInputPoint = NULL;
+ const char* szText = szNotAssigned;
+ int vKey = diMap[mapCount][kmItem];
+ if( vKey != Input::INVALID_CONTROLLERID )
+ {
+ pInputPoint = pRadController->GetInputPointByTypeAndIndex("Button", VirtualKeyToIndex[vKey]);
+ if( pInputPoint ) szText = pInputPoint->GetName();
+ }
+
+ m_pKMLabels[column][kmItem]->SetString(0, szText);
+ }
+ }
+ } break;
+ case MENU_PAGE_GAMEPAD:
+ {
+ RealController* pGamepad = pController->GetRealController( GAMEPAD );
+ RADCONTROLLER pRadController = pGamepad->getController();
+ if( pGamepad && pRadController )
+ {
+ int diMap[NUM_MAPS][NUM_GAMEPAD_LABELS] =
+ {
+ pGamepad->GetMap( SLOT_PRIMARY, InputManager::CameraFirstPerson ),
+ pGamepad->GetMap( SLOT_PRIMARY, InputManager::Attack ),
+ pGamepad->GetMap( SLOT_PRIMARY, InputManager::Jump ),
+ pGamepad->GetMap( SLOT_PRIMARY, InputManager::Sprint ),
+ pGamepad->GetMap( SLOT_PRIMARY, InputManager::DoAction ),
+ pGamepad->GetMap( SLOT_PRIMARY, InputManager::CameraZoom ),
+ pGamepad->GetMap( SLOT_PRIMARY, InputManager::Accelerate ),
+ pGamepad->GetMap( SLOT_PRIMARY, InputManager::HandBrake ),
+ pGamepad->GetMap( SLOT_PRIMARY, InputManager::Horn ),
+ pGamepad->GetMap( SLOT_PRIMARY, InputManager::ResetCar ),
+
+ pGamepad->GetMap( SLOT_SECONDARY, InputManager::CameraFirstPerson ),
+ pGamepad->GetMap( SLOT_SECONDARY, InputManager::Attack ),
+ pGamepad->GetMap( SLOT_SECONDARY, InputManager::Jump ),
+ pGamepad->GetMap( SLOT_SECONDARY, InputManager::Sprint ),
+ pGamepad->GetMap( SLOT_SECONDARY, InputManager::DoAction ),
+ pGamepad->GetMap( SLOT_SECONDARY, InputManager::CameraZoom ),
+ pGamepad->GetMap( SLOT_SECONDARY, InputManager::Accelerate ),
+ pGamepad->GetMap( SLOT_SECONDARY, InputManager::HandBrake ),
+ pGamepad->GetMap( SLOT_SECONDARY, InputManager::Horn ),
+ pGamepad->GetMap( SLOT_SECONDARY, InputManager::ResetCar ),
+ };
+
+ //Input::INVALID_CONTROLLERID
+
+ for( int column = MAP_PRIMARY, mapCount = 0; column < NUM_COLUMNS; column++, mapCount++ )
+ {
+ for( int gamepadItem = 0; gamepadItem < NUM_GAMEPAD_LABELS; gamepadItem++ )
+ {
+ IRadControllerInputPoint* pInputPoint = NULL;
+ const char* szText = szNotAssigned;
+ int vKey = diMap[mapCount][gamepadItem];
+ if( vKey != Input::INVALID_CONTROLLERID )
+ {
+ pInputPoint = pRadController->GetInputPointByTypeAndIndex("Button", VirtualJoyKeyToIndex[vKey]);
+ if( pInputPoint ) szText = pInputPoint->GetName();
+ }
+
+ m_pGamepadLabels[column][gamepadItem]->SetString(0, szText);
+ }
+ }
+ }
+ else
+ {
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_GAMEPADCONFIG, false );
+ }
+ } break;
+ default:
+ break;
+ }
+
+}
+
+void CGuiScreenController::SetSingleItemMenuPage( Scrooby::Text** pLabels,
+ int numMenuItems,
+ const char* strPage,
+ char* strGroup,
+ char* szLabel,
+ int attributes )
+{
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( strPage );
+ rAssert( pPage );
+
+
+ // if this is a controller page set the start index of its menu items.
+ if( !strcmp( strGroup, "Map1" ) && m_numControllerGroups < NUM_MENU_PAGES )
+ {
+ m_menuGroupStartIndex[m_numControllerGroups++] = m_pMenu->GetNumItems();
+ }
+
+ // Add main menu items
+ Scrooby::Group* pMenuGroup = pPage->GetGroup( strGroup );
+ for( int itemCount = 0; itemCount < numMenuItems; itemCount++ )
+ {
+ char objectName[ 32 ];
+ sprintf( objectName, "%s%02d", szLabel, itemCount );
+ Scrooby::Text* pMenuItemText = pMenuGroup->GetText( objectName );
+ if( pMenuItemText != NULL )
+ {
+ pMenuItemText->SetTextMode( Scrooby::TEXT_WRAP );
+ m_pMenu->AddMenuItem( pMenuItemText,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ attributes );
+ pLabels[itemCount] = pMenuItemText;
+ }
+ else
+ {
+ break;
+ }
+ }
+}
+
+void CGuiScreenController::SetPageVisiblility( const char* strPage, bool bVisible )
+{
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( strPage );
+ rAssert( pPage );
+ pPage->GetLayerByIndex( 0 )->SetVisible( bVisible );
+
+ //if it is any of our pages, set all their menu items to bVisible.
+ if( !strcmp( strPage, szMainControllerPage ) )
+ {
+ for( int i = 0; i < NUM_MAINMENU_LABELS; i++ )
+ m_pMenuLabels[i]->SetVisible( bVisible );
+ if( bVisible )
+ m_pMenu->Reset( MENU_ITEM_KEYMOUSECONFIG );
+ }
+ else if( !strcmp( strPage, szKeyboardMousePage ) )
+ {
+ for( int columnCount = 0; columnCount < NUM_COLUMNS; columnCount++ )
+ for( int labelCount = 0; labelCount < NUM_KEYBOARDMOUSE_LABELS; labelCount++ )
+ m_pKMLabels[columnCount][labelCount]->SetVisible( bVisible );
+ if( bVisible )
+ m_pMenu->Reset( m_menuGroupStartIndex[MENU_PAGE_KM] );
+ }
+ else if( !strcmp( strPage, szGamepadPage ) )
+ {
+ for( int columnCount = 0; columnCount < NUM_COLUMNS; columnCount++ )
+ for( int labelCount = 0; labelCount < NUM_GAMEPAD_LABELS; labelCount++ )
+ m_pGamepadLabels[columnCount][labelCount]->SetVisible( bVisible );
+ if( bVisible )
+ m_pMenu->Reset( m_menuGroupStartIndex[MENU_PAGE_GAMEPAD] );
+ }
+}
+
+int CGuiScreenController::GetVirtualKey( int menuItem )
+{
+ // We have to start the menuitem off at the correct index.
+ // This is simple, just add the menuitem with the correct start index.
+ switch(m_currentPage)
+ {
+ case MENU_PAGE_KM:
+ menuItem += KM_MOVEUP;
+ break;
+ case MENU_PAGE_GAMEPAD:
+ menuItem += GAMEPAD_FIRSTPERSON;
+ break;
+ default:
+ break;
+ }
+
+ switch(menuItem)
+ {
+ case KM_MOVEUP:
+ return InputManager::MoveUp;
+ case KM_MOVEDOWN:
+ return InputManager::MoveDown;
+ case KM_MOVELEFT:
+ return InputManager::MoveLeft;
+ case KM_MOVERIGHT:
+ return InputManager::MoveRight;
+ case KM_FIRSTPERSON:
+ case GAMEPAD_FIRSTPERSON:
+ return InputManager::CameraFirstPerson;
+ case KM_ATTACK:
+ case GAMEPAD_ATTACK:
+ return InputManager::Attack;
+ case KM_JUMP:
+ case GAMEPAD_JUMP:
+ return InputManager::Jump;
+ case KM_SPRINT:
+ case GAMEPAD_SPRINT:
+ return InputManager::Sprint;
+ case KM_DOACTION:
+ case GAMEPAD_DOACTION:
+ return InputManager::DoAction;
+ case KM_CAMERAZOOM:
+ case GAMEPAD_CAMERAZOOM:
+ return InputManager::CameraZoom;
+ case KM_ACCELERATE:
+ case GAMEPAD_ACCELERATE:
+ return InputManager::Accelerate;
+ case KM_EBRAKE:
+ case GAMEPAD_EBRAKE:
+ return InputManager::HandBrake;
+ case KM_HORN:
+ case GAMEPAD_HORN:
+ return InputManager::Horn;
+ case KM_RESETCAR:
+ case GAMEPAD_RESETCAR:
+ return InputManager::ResetCar;
+ default:
+ return 0;
+ }
+} \ No newline at end of file
diff --git a/game/code/presentation/gui/frontend/guiscreencontrollerWin32old.h b/game/code/presentation/gui/frontend/guiscreencontrollerWin32old.h
new file mode 100644
index 0000000..2328afc
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreencontrollerWin32old.h
@@ -0,0 +1,147 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenController
+//
+// Description:
+//
+//
+// Authors: Tony Chu,
+// Neil Haran
+//
+// Revisions Date Author Revision
+// 2002/07/30 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENCONTROLLER_H
+#define GUISCREENCONTROLLER_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <input/usercontrollerWin32.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenController : public CGuiScreen,
+ public ButtonMappedCallback
+{
+public:
+ CGuiScreenController( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenController();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+ virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y );
+ virtual void OnButtonMapped( const char* szNewInput );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ enum eControllerColumn
+ {
+ MASTER_LIST = 0,
+ MAP_PRIMARY,
+ MAP_SECONDARY,
+ NUM_COLUMNS,
+ NUM_MAPS = NUM_COLUMNS - 1
+ };
+
+ enum eMenuPages
+ {
+ MENU_PAGE_MAIN,
+ MENU_PAGE_KM,
+ MENU_PAGE_GAMEPAD,
+ NUM_MENU_PAGES,
+ NUM_CONTROLLER_PAGES = NUM_MENU_PAGES - 1,
+ MENU_PAGE_NONE
+ };
+
+ enum eMenuItem
+ {
+ // MAIN CONTROLLER MENU ITEMS
+ MENU_ITEM_KEYMOUSECONFIG = 0,
+ MENU_ITEM_GAMEPADCONFIG,
+ MENU_ITEM_NONE,
+ NUM_MAINMENU_LABELS = MENU_ITEM_NONE,
+
+ // KEYBOARD/MOUSE ITEMS
+ KM_MOVEUP = MENU_ITEM_NONE,
+ KM_MOVEDOWN,
+ KM_MOVELEFT,
+ KM_MOVERIGHT,
+ KM_FIRSTPERSON,
+ KM_ATTACK,
+ KM_JUMP,
+ KM_SPRINT,
+ KM_DOACTION,
+ KM_CAMERAZOOM,
+ KM_ACCELERATE,
+ KM_EBRAKE,
+ KM_HORN,
+ KM_RESETCAR,
+ KM_NONE,
+ NUM_KEYBOARDMOUSE_LABELS = KM_NONE - MENU_ITEM_NONE,
+
+ // GAMEPAD ITEMS
+ GAMEPAD_FIRSTPERSON = KM_NONE,
+ GAMEPAD_ATTACK,
+ GAMEPAD_JUMP,
+ GAMEPAD_SPRINT,
+ GAMEPAD_DOACTION,
+ GAMEPAD_CAMERAZOOM,
+ GAMEPAD_ACCELERATE,
+ GAMEPAD_EBRAKE,
+ GAMEPAD_HORN,
+ GAMEPAD_RESETCAR,
+ GAMEPAD_NONE,
+ NUM_GAMEPAD_LABELS = GAMEPAD_NONE - KM_NONE,
+
+ NUM_LABELS = NUM_MAINMENU_LABELS + NUM_KEYBOARDMOUSE_LABELS + NUM_GAMEPAD_LABELS,
+ NUM_MENU_ITEMS = NUM_MAINMENU_LABELS + NUM_KEYBOARDMOUSE_LABELS*NUM_COLUMNS + NUM_GAMEPAD_LABELS*NUM_COLUMNS
+ };
+
+private:
+ void UpdatePageLabels( eMenuPages page );
+ void SetSingleItemMenuPage( Scrooby::Text** pLabels,
+ int numMenuItems,
+ const char* strPage,
+ char* strGroup = "Menu",
+ char* szLabel = "Label",
+ int attributes = SELECTION_ENABLED | SELECTABLE | VALUES_WRAPPED );
+
+ void SetPageVisiblility( const char* strPage, bool bVisible );
+ int GetVirtualKey( int menuItem );
+ void RemapButton( eControllerColumn column, eControllerType type, int menuItem );
+
+private:
+ CGuiMenu* m_pMenu;
+ Scrooby::Text* m_pMenuLabels[ NUM_MAINMENU_LABELS ];
+ Scrooby::Text* m_pKMLabels[ NUM_COLUMNS ][ NUM_KEYBOARDMOUSE_LABELS ];
+ Scrooby::Text* m_pGamepadLabels[ NUM_COLUMNS ][ NUM_GAMEPAD_LABELS ];
+ Scrooby::Text* m_currentTextLabel;
+
+ eMenuPages m_currentPage;
+ int m_currentControllerID;
+ bool m_bMapInput;
+ bool m_bDisableBack;
+ int m_menuGroupStartIndex[NUM_MENU_PAGES];
+ int m_numControllerGroups;
+};
+
+#endif // GUISCREENCONTROLLER_H
diff --git a/game/code/presentation/gui/frontend/guiscreendisplay.cpp b/game/code/presentation/gui/frontend/guiscreendisplay.cpp
new file mode 100644
index 0000000..6a92fd4
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreendisplay.cpp
@@ -0,0 +1,346 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenDisplay
+//
+// Description: Implementation of the CGuiScreenDisplay class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/06/16 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreendisplay.h>
+#include <presentation/gui/guimenu.h>
+
+#include <data/config/gameconfigmanager.h>
+#include <main/win32platform.h>
+#include <memory/srrmemory.h>
+#include <render/RenderFlow/renderflow.h>
+
+#include <raddebug.hpp> // Foundation
+#include <screen.h>
+#include <page.h>
+#include <group.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+
+const char* DISPLAY_MENU_ITEMS[] =
+{
+ "Resolution",
+ "ColourDepth",
+ "DisplayMode",
+ "Gamma",
+ "ApplyChanges",
+
+ ""
+};
+
+const float SLIDER_ICON_SCALE = 0.5f;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenDisplay::CGuiScreenDisplay
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenDisplay::CGuiScreenDisplay
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_DISPLAY ),
+ m_pMenu( NULL ),
+ m_changedGamma( false )
+{
+MEMTRACK_PUSH_GROUP( "CGuiScreenDisplay" );
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Display" );
+ rAssert( pPage != NULL );
+
+ // Create a menu.
+ //
+ m_pMenu = new CGuiMenu( this, NUM_MENU_ITEMS );
+ rAssert( m_pMenu != NULL );
+
+ // Add menu items
+ //
+ char itemName[ 32 ];
+
+ for( int i = 0; i < MENU_ITEM_GAMMA; i++ )
+ {
+ Scrooby::Group* group = pPage->GetGroup( DISPLAY_MENU_ITEMS[ i ] );
+ rAssert( group != NULL );
+
+ sprintf( itemName, "%s_Value", DISPLAY_MENU_ITEMS[ i ] );
+ Scrooby::Text* pTextValue = group->GetText( itemName );
+
+ sprintf( itemName, "%s_ArrowL", DISPLAY_MENU_ITEMS[ i ] );
+ Scrooby::Sprite* pLArrow = group->GetSprite( itemName );
+
+ sprintf( itemName, "%s_ArrowR", DISPLAY_MENU_ITEMS[ i ] );
+ Scrooby::Sprite* pRArrow = group->GetSprite( itemName );
+
+ m_pMenu->AddMenuItem( group->GetText( DISPLAY_MENU_ITEMS[ i ] ),
+ pTextValue,
+ NULL,
+ NULL,
+ pLArrow,
+ pRArrow,
+ SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED );
+ }
+
+ // Add the gamma slider
+ Scrooby::Group* pgroup = pPage->GetGroup( "Gamma" );
+ rAssert(pgroup != NULL );
+
+ Scrooby::Text* pText = pgroup->GetText( "Gamma" );
+
+ Scrooby::Group* sliderGroup = pgroup->GetGroup( "Gamma_Slider" );
+ rAssert( sliderGroup != NULL );
+
+ sliderGroup->ResetTransformation();
+
+ m_pMenu->AddMenuItem( pText,
+ NULL,
+ NULL,
+ sliderGroup->GetSprite( "Gamma_Slider" ),
+ NULL,
+ NULL,
+ SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED );
+
+ m_pMenu->GetMenuItem( MENU_ITEM_GAMMA )->m_slider.m_type = Slider::HORIZONTAL_SLIDER_ABOUT_CENTER;
+
+ Scrooby::Sprite* soundOnIcon = pgroup->GetSprite( "Gamma_Icon" );
+ soundOnIcon->ScaleAboutCenter( SLIDER_ICON_SCALE );
+
+ // Add the apply changes button
+
+ pgroup = pPage->GetGroup( "Menu" );
+ rAssert( pgroup != NULL );
+
+ m_pMenu->AddMenuItem( pgroup->GetText( "ApplyChanges" ) );
+
+MEMTRACK_POP_GROUP("CGuiScreenDisplay");
+}
+
+
+//===========================================================================
+// CGuiScreenDisplay::~CGuiScreenDisplay
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenDisplay::~CGuiScreenDisplay()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenDisplay::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenDisplay::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ switch( param1 )
+ {
+ case MENU_ITEM_APPLY_CHANGES:
+ {
+ ApplySettings();
+ break;
+ }
+ }
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_VALUE_CHANGED:
+ {
+ rAssert( m_pMenu );
+ GuiMenuItem* currentItem = m_pMenu->GetMenuItem( param1 );
+ rAssert( currentItem );
+
+ switch( param1 )
+ {
+ case MENU_ITEM_GAMMA:
+ {
+ float gamma = 2 * currentItem->m_slider.m_value + 0.5f;
+ GetRenderFlow()->SetGamma( gamma );
+ m_changedGamma = true;
+
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+//===========================================================================
+// CGuiScreenDisplay::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenDisplay::InitIntro()
+{
+ // update settings
+ //
+ Win32Platform* plat = Win32Platform::GetInstance();
+
+ Win32Platform::Resolution res = plat->GetResolution();
+ m_pMenu->SetSelectionValue( MENU_ITEM_RESOLUTION,
+ res );
+
+ int bpp = plat->GetBPP();
+ m_pMenu->SetSelectionValue( MENU_ITEM_COLOUR_DEPTH,
+ bpp == 16 ? 0: 1 );
+
+ bool fullscreen = plat->IsFullscreen();
+ m_pMenu->SetSelectionValue( MENU_ITEM_DISPLAY_MODE,
+ fullscreen ? 1 : 0 );
+
+ GuiMenuItem* menuItem = m_pMenu->GetMenuItem( MENU_ITEM_GAMMA );
+ rAssert( menuItem );
+ menuItem->m_slider.SetValue( ( GetRenderFlow()->GetGamma() - 0.5f ) / 2.0f );
+}
+
+
+//===========================================================================
+// CGuiScreenDisplay::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenDisplay::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenDisplay::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenDisplay::InitOutro()
+{
+ // Save the config if we've changed the gamma settings
+ if( m_changedGamma )
+ {
+ GetGameConfigManager()->SaveConfigFile();
+ m_changedGamma = false;
+ }
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+//===========================================================================
+// CGuiScreenDisplay::ApplySettings
+//===========================================================================
+// Description: Applies the current display settings to teh game.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenDisplay::ApplySettings()
+{
+ // Retrieve the settings.
+ //
+ Win32Platform::Resolution res = static_cast< Win32Platform::Resolution >( m_pMenu->GetSelectionValue( MENU_ITEM_RESOLUTION ) );
+
+ int bpp = m_pMenu->GetSelectionValue( MENU_ITEM_COLOUR_DEPTH ) ? 32: 16;
+
+ bool fullscreen = m_pMenu->GetSelectionValue( MENU_ITEM_DISPLAY_MODE ) == 1;
+
+ // Set the resolution.
+ Win32Platform::GetInstance()->SetResolution( res, bpp, fullscreen );
+
+ // Save the change to the config file.
+ GetGameConfigManager()->SaveConfigFile();
+ m_changedGamma = false;
+}
diff --git a/game/code/presentation/gui/frontend/guiscreendisplay.h b/game/code/presentation/gui/frontend/guiscreendisplay.h
new file mode 100644
index 0000000..8b56a72
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreendisplay.h
@@ -0,0 +1,68 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenDisplay
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/06/16 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENDISPLAY_H
+#define GUISCREENDISPLAY_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenDisplay : public CGuiScreen
+{
+public:
+ CGuiScreenDisplay( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenDisplay();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ void ApplySettings();
+
+private:
+ enum eMenuItem
+ {
+ MENU_ITEM_RESOLUTION,
+ MENU_ITEM_COLOUR_DEPTH,
+ MENU_ITEM_DISPLAY_MODE,
+ MENU_ITEM_GAMMA,
+ MENU_ITEM_APPLY_CHANGES,
+
+ NUM_MENU_ITEMS
+ };
+
+ CGuiMenu* m_pMenu;
+ bool m_changedGamma;
+};
+
+#endif // GUISCREENDISPLAY_H
diff --git a/game/code/presentation/gui/frontend/guiscreenloadgame.cpp b/game/code/presentation/gui/frontend/guiscreenloadgame.cpp
new file mode 100644
index 0000000..0e49bc4
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenloadgame.cpp
@@ -0,0 +1,1034 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLoadGame
+//
+// Description: Implementation of the CGuiScreenLoadGame class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreenloadgame.h>
+#include <presentation/gui/frontend/guiscreenmainmenu.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/gui/guiscreenmessage.h>
+#include <presentation/gui/guiscreenprompt.h>
+
+#include <data/gamedatamanager.h>
+#include <data/savegameinfo.h>
+#include <data/memcard/memorycardmanager.h>
+#include <memory/srrmemory.h>
+
+#include <raddebug.hpp> // Foundation
+#include <page.h>
+#include <screen.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+#ifdef RAD_XBOX
+ char gGameFileName[NUM_GAME_SLOTS][radFileFilenameMax+1];
+#endif
+
+#ifdef RAD_PS2
+ const unsigned int AUTO_LOAD_MINIMUM_DISPLAY_TIME = 5000; // in msec
+#endif
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenLoadGame::CGuiScreenLoadGame
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLoadGame::CGuiScreenLoadGame
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent,
+ eGuiWindowID windowID
+)
+: CGuiScreen( pScreen, pParent, windowID ),
+ CGuiScreenLoadSave( pScreen ),
+ m_pMenu( NULL ),
+ m_pFullText( NULL ),
+ m_StatusPromptShown(false)
+
+{
+MEMTRACK_PUSH_GROUP( "CGUIScreenLoadGame" );
+ if( windowID == GUI_SCREEN_ID_LOAD_GAME )
+ {
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "GameSlots" );
+ rAssert( pPage );
+
+ // hide full text field
+ m_pFullText = pPage->GetText( "FullMessage" );
+ rAssert( m_pFullText != NULL );
+ m_pFullText->SetVisible(false);
+ m_pFullText->SetTextMode( Scrooby::TEXT_WRAP );
+
+ // Create a menu.
+ //
+ m_pMenu = new(GMA_LEVEL_FE) CGuiMenu( this, NUM_GAME_SLOTS );
+ rAssert( m_pMenu != NULL );
+
+ // Add menu items
+ //
+ for( unsigned int i = 0; i < NUM_GAME_SLOTS; i++ )
+ {
+ char objectName[ 32 ];
+ sprintf( objectName, "Slot%d", i );
+
+ m_pMenu->AddMenuItem( pPage->GetText( objectName ) );
+ }
+ }
+MEMTRACK_POP_GROUP( "CGUIScreenLoadGame" );
+}
+
+
+//===========================================================================
+// CGuiScreenLoadGame::~CGuiScreenLoadGame
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLoadGame::~CGuiScreenLoadGame()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenLoadGame::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLoadGame::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if (message == GUI_MSG_MESSAGE_UPDATE)
+ {
+ if (m_formatState)
+ {
+ m_elapsedFormatTime += param1;
+
+ if (m_elapsedFormatTime > m_minimumFormatTime && m_formatDone)
+ {
+ m_StatusPromptShown = true;
+ if( m_formatResult == Success )
+ {
+ m_guiManager->DisplayPrompt(PROMPT_FORMAT_SUCCESS_GC + PLATFORM_TEXT_INDEX, this, PROMPT_TYPE_CONTINUE); // format success
+ m_formatState = false;
+ }
+ else
+ {
+ m_guiManager->DisplayPrompt(PROMPT_FORMAT_FAIL_GC + PLATFORM_TEXT_INDEX, this, PROMPT_TYPE_CONTINUE); // format fail
+ m_formatState = false;
+ }
+ }
+ }
+ }
+ else if (message == GUI_MSG_PROMPT_UPDATE)
+ {
+ // update so status up to date
+ GetMemoryCardManager()->Update( param1 );
+ if (m_StatusPromptShown==false) { // check for user unplugging memcard if not showing status
+ int currentDrive = GetMemoryCardManager()->GetCurrentDriveIndex();
+ if( !GetMemoryCardManager()->IsCurrentDrivePresent(currentDrive) )
+ ReloadScreen();
+ }
+ }
+ else if( message == GUI_MSG_ON_DISPLAY_MESSAGE )
+ {
+ if (m_operation==LOAD)
+ {
+ // start the load game process
+ //
+ rAssert( m_currentSlot != -1 );
+#ifdef RAD_XBOX
+ GetGameDataManager()->LoadGame( m_currentSlot, this, gGameFileName[m_currentSlot] );
+#else
+ GetGameDataManager()->LoadGame( m_currentSlot, this );
+#endif
+ }
+ else
+ {
+ FormatCurrentDrive();
+ }
+ }
+ else if ( message == GUI_MSG_ERROR_PROMPT_RESPONSE )
+ {
+ this->HandleErrorResponse( static_cast<CGuiMenuPrompt::ePromptResponse>( param2 ) );
+ }
+ else if( message == GUI_MSG_MENU_PROMPT_RESPONSE )
+ {
+ switch( param1 )
+ {
+ case PROMPT_LOAD_CARD_EMPTY_GC:
+ case PROMPT_LOAD_CARD_EMPTY_PS2:
+ case PROMPT_LOAD_CARD_EMPTY_XBOX:
+ case PROMPT_LOAD_CARD_EMPTY_XBOX_HD:
+ this->GotoMemoryCardScreen( true );
+ break;
+
+ case PROMPT_LOAD_DELETE_CORRUPT_GC:
+ case PROMPT_LOAD_DELETE_CORRUPT_PS2:
+ case PROMPT_LOAD_DELETE_CORRUPT_XBOX:
+ case PROMPT_LOAD_DELETE_CORRUPT_XBOX_HD:
+ {
+ if (param2==CGuiMenuPrompt::RESPONSE_NO)
+ {
+ this->ReloadScreen();
+ }
+ else if (param2==CGuiMenuPrompt::RESPONSE_YES)
+ {
+ // get the filename
+ char filename[ radFileFilenameMax + 1 ];
+#ifdef RAD_XBOX
+ strcpy(filename, gGameFileName[m_currentSlot]);
+#else
+ GetGameDataManager()->FormatSavedGameFilename( filename,
+ sizeof( filename ),
+ m_currentSlot );
+#endif
+ radFileError err = GetGameDataManager()->DeleteGame(filename);
+ if (err==Success)
+ m_guiManager->DisplayPrompt(PROMPT_DELETE_CORRUPT_SUCCESS_GC + PLATFORM_TEXT_INDEX, this,
+ PROMPT_TYPE_CONTINUE);
+ else
+ m_guiManager->DisplayPrompt(PROMPT_DELETE_CORRUPT_FAIL_GC + PLATFORM_TEXT_INDEX, this,
+ PROMPT_TYPE_CONTINUE);
+
+ }
+
+ break;
+ }
+ case PROMPT_DELETE_CORRUPT_SUCCESS_GC:
+ case PROMPT_DELETE_CORRUPT_SUCCESS_PS2:
+ case PROMPT_DELETE_CORRUPT_SUCCESS_XBOX:
+
+ case PROMPT_DELETE_CORRUPT_FAIL_GC:
+ case PROMPT_DELETE_CORRUPT_FAIL_PS2:
+ case PROMPT_DELETE_CORRUPT_FAIL_XBOX:
+ this->ReloadScreen();
+ break;
+
+ case PROMPT_FORMAT_CONFIRM2_GC:
+ case PROMPT_FORMAT_CONFIRM2_PS2:
+ case PROMPT_FORMAT_CONFIRM2_XBOX: // really format
+ {
+ if (param2==CGuiMenuPrompt::RESPONSE_YES)
+ {
+ m_operation = FORMAT;
+ m_guiManager->DisplayMessage(CGuiScreenMessage::MSG_ID_FORMATTING_GC + PLATFORM_TEXT_INDEX, this);
+ }
+ else
+ {
+ this->GotoMemoryCardScreen( true );
+ }
+
+ break;
+ }
+ case PROMPT_FORMAT_SUCCESS_GC:
+ case PROMPT_FORMAT_SUCCESS_PS2:
+ case PROMPT_FORMAT_SUCCESS_XBOX: // format ok
+ {
+ this->GotoMemoryCardScreen( true );
+
+ break;
+ }
+ case PROMPT_FORMAT_FAIL_GC:
+ case PROMPT_FORMAT_FAIL_PS2:
+ case PROMPT_FORMAT_FAIL_XBOX: // format fail
+ {
+ GetMemoryCardManager()->ClearCurrentDrive();
+ this->GotoMemoryCardScreen( true );
+
+ break;
+ }
+ case PROMPT_LOAD_CONFIRM_GC:
+ case PROMPT_LOAD_CONFIRM_PS2:
+ case PROMPT_LOAD_CONFIRM_XBOX:
+ {
+ if( param2 == CGuiMenuPrompt::RESPONSE_YES )
+ {
+ this->LoadGame();
+ }
+ else
+ {
+ rAssert( param2 == CGuiMenuPrompt::RESPONSE_NO );
+
+ this->ReloadScreen();
+ }
+
+ break;
+ }
+
+ case PROMPT_LOAD_SUCCESSFUL:
+ {
+ CGuiScreen* promptScreen = (CGuiScreen*)m_guiManager->FindWindowByID( GUI_SCREEN_ID_GENERIC_PROMPT );
+ rAssert( promptScreen );
+ promptScreen->StartTransitionAnimation( 230, 260 );
+
+ // re-init main menu and default to "resume game" selection
+ //
+ CGuiScreenMainMenu* pScreen =
+ static_cast<CGuiScreenMainMenu*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_MAIN_MENU ) );
+ rAssert( pScreen != NULL );
+ pScreen->InitMenu();
+
+ m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN );
+
+ break;
+ }
+
+ default:
+ {
+ // handle normal menu condition, "continue", "retry"
+ this->HandleErrorResponse( static_cast<CGuiMenuPrompt::ePromptResponse>( param2 ) );
+
+ break;
+ }
+ }
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ m_currentSlot = param1; // // param1 = slot
+
+ SaveGameInfo saveGameInfo;
+ bool corrupt;
+ IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive();
+ bool saveGameExists = GetGameDataManager()->GetSaveGameInfo( currentDrive, m_currentSlot, &saveGameInfo, &corrupt );
+
+ if (corrupt)
+ {
+#ifdef RAD_GAMECUBE
+ int errorMessage = GetErrorMessageIndex( DataCorrupt, ERROR_DURING_LOADING );
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_DELETE );
+ m_operation = LOAD;
+#endif
+#ifdef RAD_PS2
+ rAssertMsg( false, "Corrupted save games should not have been selectable!" );
+#endif
+#ifdef RAD_XBOX
+ // for xbox don't ask to delete just put up a message
+ int errorMessage = GetErrorMessageIndex( DataCorrupt, ERROR_DURING_LOADING );
+ m_guiManager->DisplayErrorPrompt( errorMessage, this, ERROR_RESPONSE_CONTINUE );
+#endif
+ }
+ else
+ {
+ #ifdef RAD_GAMECUBE
+ m_guiManager->DisplayPrompt( PROMPT_LOAD_CONFIRM_GC, this );
+ #endif
+
+ #ifdef RAD_PS2
+ m_guiManager->DisplayPrompt( PROMPT_LOAD_CONFIRM_PS2, this );
+ #endif
+
+ #ifdef RAD_XBOX
+ m_guiManager->DisplayPrompt( PROMPT_LOAD_CONFIRM_XBOX, this );
+ #endif
+
+ #ifdef RAD_WIN32
+ m_guiManager->DisplayPrompt( PROMPT_LOAD_CONFIRM_XBOX, this ); // parallel xbox for now.
+ #endif
+ }
+
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+#ifdef RAD_XBOX
+ s_forceGotoMemoryCardScreen = true;
+ this->GotoMemoryCardScreen();
+#else
+ this->StartTransitionAnimation( 230, 260 );
+#endif
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+
+ if( m_ID == GUI_SCREEN_ID_LOAD_GAME )
+ {
+ CGuiScreenLoadSave::HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+void
+CGuiScreenLoadGame::OnLoadGameComplete( radFileError errorCode )
+{
+ m_lastError = errorCode;
+ m_StatusPromptShown = true;
+
+ if( errorCode == Success )
+ {
+ m_guiManager->DisplayPrompt( PROMPT_LOAD_SUCCESSFUL, this, PROMPT_TYPE_CONTINUE );
+ }
+ else
+ {
+ int errorMessage = GetErrorMessageIndex( errorCode, ERROR_DURING_LOADING );
+
+#ifdef RAD_GAMECUBE
+ switch( errorCode )
+ {
+ case Success:
+ {
+ rAssert( false );
+ break;
+ }
+ case MediaEncodingErr:
+ case MediaNotFormatted:
+ {
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_FORMAT );
+
+ }
+ case DataCorrupt:
+ {
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_DELETE );
+
+ break;
+ }
+ default:
+ {
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY );
+
+ break;
+ }
+ }
+#endif // RAD_GAMECUBE
+
+#ifdef RAD_PS2
+ switch( errorCode )
+ {
+ case Success:
+ {
+ rAssert( false );
+ break;
+ }
+/*
+ case DataCorrupt:
+ {
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ ERROR_RESPONSE_YES | ERROR_RESPONSE_NO );
+
+ break;
+ }
+*/
+ default:
+ {
+ m_guiManager->DisplayErrorPrompt( errorMessage, this, ERROR_RESPONSE_CONTINUE );
+
+ break;
+ }
+ }
+#endif // RAD_PS2
+
+#ifdef RAD_XBOX
+ switch( errorCode )
+ {
+ case Success:
+ {
+ rAssert( false );
+ break;
+ }
+ default:
+ {
+ if (errorCode==DataCorrupt) // no delete corrupt for xbox loading
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ ERROR_RESPONSE_CONTINUE );
+ else
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ ERROR_RESPONSE_CONTINUE );
+
+ break;
+ }
+ }
+#endif // RAD_XBOX
+
+#ifdef RAD_WIN32
+ switch( errorCode )
+ {
+ case Success:
+ {
+ rAssert( false );
+ break;
+ }
+ default:
+ {
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ ERROR_RESPONSE_CONTINUE );
+ break;
+ }
+ }
+#endif // RAD_WIN32
+ }
+}
+
+
+void
+CGuiScreenLoadGame::HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response )
+{
+ switch( response )
+ {
+ case (CGuiMenuPrompt::RESPONSE_CONTINUE):
+ {
+ if( m_operation == LOAD )
+ {
+ this->ReloadScreen();
+ }
+ else if( m_operation == FORMAT )
+ {
+ this->ReloadScreen();
+ }
+ else
+ {
+ this->GotoMemoryCardScreen( true );
+ }
+
+ break;
+ }
+ case (CGuiMenuPrompt::RESPONSE_RETRY):
+ {
+ if( m_operation == LOAD )
+ {
+ this->LoadGame();
+ }
+ else if( m_operation == FORMAT )
+ {
+ m_guiManager->DisplayMessage(CGuiScreenMessage::MSG_ID_FORMATTING_GC + PLATFORM_TEXT_INDEX, this);
+ }
+ else
+ {
+ this->ReloadScreen();
+ }
+
+ break;
+ }
+
+#ifdef RAD_GAMECUBE
+ case (CGuiMenuPrompt::RESPONSE_DELETE):
+ {
+ m_guiManager->DisplayPrompt( PROMPT_LOAD_DELETE_CORRUPT_GC, this );
+
+ break;
+ }
+#endif // RAD_GAMECUBE
+
+#if defined( RAD_GAMECUBE ) || defined( RAD_PS2 )
+ case (CGuiMenuPrompt::RESPONSE_YES):
+ {
+ // YES to delete corrupted file
+ //
+ char filename[ radFileFilenameMax + 1 ];
+#ifdef RAD_XBOX
+ strcpy( filename, gGameFileName[ m_currentSlot ] );
+#else
+ GetGameDataManager()->FormatSavedGameFilename( filename,
+ sizeof( filename ),
+ m_currentSlot );
+#endif
+ radFileError err = GetGameDataManager()->DeleteGame( filename );
+ if( err == Success )
+ {
+ m_guiManager->DisplayPrompt( PROMPT_DELETE_CORRUPT_SUCCESS_GC + PLATFORM_TEXT_INDEX,
+ this, PROMPT_TYPE_CONTINUE );
+ }
+ else
+ {
+ m_guiManager->DisplayPrompt( PROMPT_DELETE_CORRUPT_FAIL_GC + PLATFORM_TEXT_INDEX,
+ this, PROMPT_TYPE_CONTINUE );
+ }
+
+ break;
+ }
+ case (CGuiMenuPrompt::RESPONSE_NO):
+ {
+ // NO to delete corrupted file
+ //
+ this->ReloadScreen();
+
+ break;
+ }
+#endif // RAD_GAMECUBE || RAD_PS2
+
+ case (CGuiMenuPrompt::RESPONSE_FORMAT_GC):
+ case (CGuiMenuPrompt::RESPONSE_FORMAT_XBOX):
+ case (CGuiMenuPrompt::RESPONSE_FORMAT_PS2):
+ {
+ m_guiManager->DisplayPrompt(PROMPT_FORMAT_CONFIRM2_GC + PLATFORM_TEXT_INDEX,this);
+
+ break;
+ }
+ default:
+ {
+ rTunePrintf( "*** WARNING: Unhandled response for error [%d]!\n", m_lastError );
+ rAssert( false );
+
+ this->ReloadScreen();
+
+ break;
+ }
+ }
+
+ CGuiScreenLoadSave::HandleErrorResponse( response );
+}
+
+//===========================================================================
+// CGuiScreenLoadGame::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLoadGame::InitIntro()
+{
+ bool unformatted = false;
+ bool file_corrupt = false;
+ SaveGameInfo saveGameInfo;
+ m_StatusPromptShown = false;
+ m_operation = SCREEN_OP_IDLE;
+
+ m_pFullText->SetVisible(false);
+
+ IRadDrive::MediaInfo::MediaState mediaState;
+ if( s_forceGotoMemoryCardScreen || !GetMemoryCardManager()->IsCurrentDriveReady( true, &unformatted, &mediaState ) )
+ {
+ if (unformatted && !s_forceGotoMemoryCardScreen)
+ {
+#ifdef RAD_GAMECUBE
+ int errorMessage = GetErrorMessageIndex( mediaState );
+ m_guiManager->DisplayErrorPrompt( errorMessage,
+ this,
+ ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_FORMAT );
+
+ m_numTransitionsPending = -1; // disable all transitions
+
+ return;
+#endif
+ }
+ else
+ {
+ this->GotoMemoryCardScreen();
+ m_numTransitionsPending = -1; // disable all transitions
+
+ return;
+ }
+ }
+
+ this->UpdateCurrentMemoryDevice();
+
+ rAssert( m_pMenu );
+ m_pMenu->Reset();
+
+ IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive();
+
+ radDate mostRecentTimestamp;
+ mostRecentTimestamp.m_Year = 0;
+ bool has_savegame = false;
+ bool has_4_saves = false;
+
+ // update all save game slots display info
+ //
+ for( unsigned int i = 0; i < NUM_GAME_SLOTS; i++ )
+ {
+ bool saveGameExists = GetGameDataManager()->GetSaveGameInfo( currentDrive, i, &saveGameInfo, &file_corrupt );
+// saveGameExists = saveGameExists && saveGameInfo.CheckData();
+
+ Scrooby::Text* slotText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( i )->GetItem() );
+ rAssert( slotText != NULL );
+
+ HeapMgr()->PushHeap( GMA_LEVEL_FE );
+
+ if( saveGameExists )
+ {
+ if (i == NUM_GAME_SLOTS-1)
+ {
+ has_4_saves = true;
+ }
+ has_savegame = true;
+ if (file_corrupt)
+ {
+ UnicodeString corruptSlot;
+#ifdef RAD_XBOX
+ corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(XBOX)" ) );
+#endif
+#ifdef RAD_WIN32
+ corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(XBOX)" ) );
+#endif
+#ifdef RAD_PS2
+ corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(PS2)" ) );
+#endif
+#ifdef RAD_GAMECUBE
+ corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(GC)" ) );
+#endif
+ slotText->SetString(0,corruptSlot);
+ }
+ else
+ {
+ #ifdef RAD_XBOX
+ strcpy(gGameFileName[i], saveGameInfo.m_displayFilename); // cache the slot filename
+ #endif
+ slotText->SetString( 0, saveGameInfo.m_displayFilename );
+ }
+
+ // default to slot with most recent saved game file
+ //
+ const SaveGameInfoData* pData = saveGameInfo.GetData();
+ rAssert( pData != NULL );
+ if( SaveGameInfo::CompareTimeStamps( pData->m_timeStamp, mostRecentTimestamp ) > 0 )
+ {
+ memcpy( &mostRecentTimestamp, &pData->m_timeStamp, sizeof( radDate ) );
+
+ m_pMenu->Reset( i );
+ }
+ }
+ else
+ {
+ UnicodeString emptySlot;
+ emptySlot.ReadUnicode( GetTextBibleString( "EMPTY_SLOT" ) );
+ slotText->SetString( 0, emptySlot );
+ }
+ HeapMgr()->PopHeap(GMA_LEVEL_FE);
+
+ // enable slot selection only if save game exists
+ //
+#ifdef RAD_PS2
+ m_pMenu->SetMenuItemEnabled( i, saveGameExists && !file_corrupt );
+#else
+ m_pMenu->SetMenuItemEnabled( i, saveGameExists );
+#endif // RAD_PS2
+ }
+
+ if (has_savegame==false) // no file in card
+ {
+ int prompt_id = PROMPT_LOAD_CARD_EMPTY_GC+PLATFORM_TEXT_INDEX;
+#ifdef RAD_XBOX
+ if (GetMemoryCardManager()->GetCurrentDriveIndex()==0)
+ prompt_id = PROMPT_LOAD_CARD_EMPTY_XBOX_HD;
+#endif
+ m_guiManager->DisplayPrompt(prompt_id,this,PROMPT_TYPE_CONTINUE);
+ m_numTransitionsPending = -1; // disable all transitions
+ }
+ else
+ {
+#ifdef RAD_XBOX
+ // check if there are more than 4 files on hd
+ if ( has_4_saves
+ && GetGameDataManager()->GetSaveGameInfo( currentDrive, NUM_GAME_SLOTS, &saveGameInfo, &file_corrupt )
+ )
+ {
+ m_pFullText->SetIndex( 8 );
+ m_pFullText->SetVisible(true);
+
+ }
+#endif
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, true );
+ }
+}
+
+//===========================================================================
+// CGuiScreenLoadGame::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLoadGame::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenLoadGame::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLoadGame::InitOutro()
+{
+}
+
+void
+CGuiScreenLoadGame::GotoMemoryCardScreen( bool isFromPrompt )
+{
+#ifdef RAD_WIN32
+ if( isFromPrompt )
+ {
+ CGuiScreen* pScreen = static_cast<CGuiScreen*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_GENERIC_PROMPT ) );
+ rAssert( pScreen != NULL );
+ pScreen->StartTransitionAnimation( 230, 260 );
+ }
+ else
+ {
+ this->StartTransitionAnimation( 230, 260 );
+ }
+
+ m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN );
+#else
+ if( isFromPrompt )
+ {
+ s_forceGotoMemoryCardScreen = true;
+ this->ReloadScreen();
+ }
+ else
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MEMORY_CARD );
+ }
+#endif // RAD_WIN32
+}
+
+void CGuiScreenLoadGame::LoadGame()
+{
+ m_operation = LOAD;
+
+#ifdef RAD_GAMECUBE
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_LOADING_GAME_GC, this );
+#endif
+
+#ifdef RAD_PS2
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_LOADING_GAME_PS2, this );
+#endif
+
+#ifdef RAD_XBOX
+ if( m_currentDriveIndex == 0 ) // xbox hard disk
+ {
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_LOADING_GAME_XBOX_HD, this );
+ }
+ else // xbox memory unit
+ {
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_LOADING_GAME_XBOX, this );
+ }
+#endif
+
+#ifdef RAD_WIN32
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_LOADING_GAME_PC, this );
+#endif
+}
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+
+//===========================================================================
+// Public Member Functions (for CGuiScreenAutoLoad)
+//===========================================================================
+
+int CGuiScreenAutoLoad::s_autoLoadGameSlot = -1;
+
+CGuiScreenAutoLoad::CGuiScreenAutoLoad( Scrooby::Screen* pScreen, CGuiEntity* pParent )
+: CGuiScreenLoadGame( pScreen, pParent, GUI_SCREEN_ID_AUTO_LOAD )
+{
+}
+
+CGuiScreenAutoLoad::~CGuiScreenAutoLoad()
+{
+}
+
+void
+CGuiScreenAutoLoad::OnLoadGameComplete( radFileError errorCode )
+{
+ GetGameDataManager()->RestoreDefaultMinimumLoadSaveTime();
+
+ if( errorCode == Success )
+ {
+ m_pParent->HandleMessage( GUI_MSG_MEMCARD_CHECK_COMPLETED );
+ }
+ else
+ {
+ CGuiScreenLoadGame::OnLoadGameComplete( errorCode );
+ }
+}
+
+void
+CGuiScreenAutoLoad::InitIntro()
+{
+}
+
+void
+CGuiScreenAutoLoad::InitRunning()
+{
+ m_currentDriveIndex = GetMemoryCardManager()->GetCurrentDriveIndex();
+ rAssert( m_currentDriveIndex != -1 );
+
+ IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive();
+ if( currentDrive != NULL )
+ {
+ rReleasePrintf( "Auto-loading most recent saved game from drive %s\n",
+ currentDrive->GetDriveName() );
+ }
+
+ rAssert( s_autoLoadGameSlot != -1 );
+ m_currentSlot = s_autoLoadGameSlot;
+#ifdef RAD_XBOX
+ // for xbox we need to get the filename from slot information first before loading
+ SaveGameInfo saveGameInfo;
+ gGameFileName[m_currentSlot][0] = 0; // initialize to empty string
+ rAssert(m_currentSlot < NUM_GAME_SLOTS);
+ bool saveGameExists = GetGameDataManager()->GetSaveGameInfo( currentDrive, m_currentSlot, &saveGameInfo );
+ if( saveGameExists ) // game filename is cached in gGameFileName global
+ {
+ strcpy( gGameFileName[m_currentSlot], saveGameInfo.m_displayFilename);
+ }
+
+#endif
+
+ this->LoadGame();
+}
+
+void
+CGuiScreenAutoLoad::InitOutro()
+{
+}
+
+void
+CGuiScreenAutoLoad::HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response )
+{
+ switch( response )
+ {
+ case (CGuiMenuPrompt::RESPONSE_CONTINUE):
+ {
+ m_pParent->HandleMessage( GUI_MSG_MEMCARD_CHECK_COMPLETED );
+
+ break;
+ }
+ case (CGuiMenuPrompt::RESPONSE_RETRY):
+ {
+ this->LoadGame();
+
+ break;
+ }
+ default:
+ {
+ rTunePrintf( "*** WARNING: Unhandled response for error [%d]!\n", m_lastError );
+ rAssert( false );
+
+ m_pParent->HandleMessage( GUI_MSG_MEMCARD_CHECK_COMPLETED );
+
+ break;
+ }
+ }
+
+ CGuiScreenLoadSave::HandleErrorResponse( response );
+}
+
+void
+CGuiScreenAutoLoad::LoadGame()
+{
+ m_operation = LOAD;
+
+#ifdef RAD_GAMECUBE
+ // TC: GC does not require an auto-loading screen
+ //
+// m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_AUTO_LOADING_GAME_GC, this );
+ GetGameDataManager()->LoadGame( m_currentSlot, this );
+ GetGameDataManager()->SetMinimumLoadSaveTime( 0 );
+#endif
+
+#ifdef RAD_PS2
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_AUTO_LOADING_GAME_PS2, this );
+ GetGameDataManager()->SetMinimumLoadSaveTime( AUTO_LOAD_MINIMUM_DISPLAY_TIME );
+#endif
+
+#ifdef RAD_XBOX
+ if( m_currentDriveIndex == 0 ) // xbox hard disk
+ {
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_AUTO_LOADING_GAME_XBOX_HD, this );
+ }
+ else // xbox memory unit
+ {
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_AUTO_LOADING_GAME_XBOX, this );
+ }
+#endif
+
+#ifdef RAD_WIN32
+ rAssert( m_currentDriveIndex == 0 );
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_AUTO_LOADING_GAME_PC, this );
+#endif
+}
+
diff --git a/game/code/presentation/gui/frontend/guiscreenloadgame.h b/game/code/presentation/gui/frontend/guiscreenloadgame.h
new file mode 100644
index 0000000..f7902f6
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenloadgame.h
@@ -0,0 +1,92 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLoadGame
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/30 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENLOADGAME_H
+#define GUISCREENLOADGAME_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <presentation/gui/guiscreenmemorycard.h>
+#include <data/gamedatamanager.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenLoadGame : public CGuiScreen,
+ public CGuiScreenLoadSave,
+ public GameDataLoadCallback
+
+{
+public:
+ CGuiScreenLoadGame( Scrooby::Screen* pScreen, CGuiEntity* pParent,
+ eGuiWindowID windowID = GUI_SCREEN_ID_LOAD_GAME );
+ virtual ~CGuiScreenLoadGame();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ // Implements GameDataLoadCallback
+ //
+ virtual void OnLoadGameComplete( radFileError errorCode );
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+ void GotoMemoryCardScreen( bool isFromPrompt = false );
+ virtual void HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response );
+ virtual void LoadGame();
+
+private:
+ CGuiMenu* m_pMenu;
+ Scrooby::Text* m_pFullText;
+ bool m_StatusPromptShown;
+};
+
+class CGuiScreenAutoLoad : public CGuiScreenLoadGame
+{
+public:
+ CGuiScreenAutoLoad( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenAutoLoad();
+
+ virtual void OnLoadGameComplete( radFileError errorCode );
+
+ static void SetGameSlot( int slot ) { s_autoLoadGameSlot = slot; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+ virtual void HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response );
+ virtual void LoadGame();
+
+private:
+ static int s_autoLoadGameSlot;
+
+};
+
+#endif // GUISCREENLOADGAME_H
diff --git a/game/code/presentation/gui/frontend/guiscreenmainmenu.cpp b/game/code/presentation/gui/frontend/guiscreenmainmenu.cpp
new file mode 100644
index 0000000..405ed42
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenmainmenu.cpp
@@ -0,0 +1,1649 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMainMenu
+//
+// Description: Implementation of the CGuiScreenMainMenu class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/11/20 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreenmainmenu.h>
+#include <presentation/gui/frontend/guiscreenplaymovie.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/guiscreenmemorycard.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guiscreenprompt.h>
+
+#include <constants/movienames.h>
+#include <data/gamedatamanager.h>
+#include <data/persistentworldmanager.h>
+#include <events/eventmanager.h>
+#include <input/inputmanager.h>
+#include <memory/srrmemory.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <mission/rewards/rewardsmanager.h>
+#include <render/rendermanager/rendermanager.h>
+#include <render/rendermanager/renderlayer.h>
+
+#include <p3d/view.hpp>
+
+#include <raddebug.hpp> // Foundation
+#include <radtime.hpp>
+#include <radkey.hpp>
+#include <radmath/random.hpp>
+#include <p3d/anim/multicontroller.hpp>
+
+#include <stdlib.h>
+#include <group.h>
+#include <layer.h>
+#include <page.h>
+#include <pure3dobject.h>
+#include <screen.h>
+#include <text.h>
+
+#include <string.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//#define PLAY_GAGS_SEQUENTIALLY
+//#define PLAY_ONLY_HOMER_GAGS
+
+const float FIRST_TIME_FADE_IN_TIME = 500.0f;
+
+const unsigned int MIN_GAGS_CYCLE_TIME = 15; // in seconds
+const unsigned int MAX_GAGS_CYCLE_TIME = 30; // in seconds
+const unsigned int GAGS_RANDOM_NUMBER_MODULO = 97;
+
+const tColour FE_BLUE_SKY_COLOUR( 128, 255, 255 );
+
+struct HomerGagAnimation
+{
+ float startFrame;
+ float endFrame;
+};
+
+HomerGagAnimation HOMER_GAG_ANIMATION[] =
+{
+ { 0.0f, 75.0f },
+ { 75.0f, 145.0f },
+ { 145.0f, 215.0f },
+ { 215.0f, 355.0f },
+ { 355.0f, 475.0f },
+
+ { -1.0f, -1.0f } // dummy terminator
+};
+
+int NUM_HOMER_GAG_ANIMATIONS =
+ sizeof( HOMER_GAG_ANIMATION ) / sizeof( HOMER_GAG_ANIMATION[ 0 ] ) - 1;
+
+const radKey32 FE_GAGS[] =
+{
+ ::radMakeKey32( "FE_Gag_Homer" ),
+ ::radMakeKey32( "FE_Gag_Grandpa" ),
+ ::radMakeKey32( "FE_Gag_Moleman" ),
+ ::radMakeKey32( "FE_Gag_Frink" ),
+ ::radMakeKey32( "FE_Gag_Barney" ),
+ ::radMakeKey32( "FE_Gag_Nick" ),
+ ::radMakeKey32( "FE_Gag_Snake" ),
+ ::radMakeKey32( "FE_Gag_Maggie" ),
+
+ ::radMakeKey32( "FE_Gag_UNKNOWN" )
+};
+
+const radKey32 FE_GAGS_FOR_HOMER[] =
+{
+ ::radMakeKey32( "FE_Gag_Homer_ScratchHead" ),
+ ::radMakeKey32( "FE_Gag_Homer_ScratchBum" ),
+ ::radMakeKey32( "FE_Gag_Homer_Yawn" ),
+ ::radMakeKey32( "FE_Gag_Homer_Nightmare" ),
+ ::radMakeKey32( "FE_Gag_Homer_Stretch" ),
+
+ ::radMakeKey32( "FE_Gag_UNKNOWN" )
+};
+
+enum eMainMenuItem
+{
+ MENU_ITEM_MAIN_MENU,
+/*
+ MENU_ITEM_NEW_GAME,
+ MENU_ITEM_RESUME_GAME,
+ MENU_ITEM_LOAD_GAME,
+ MENU_ITEM_COLLECTIBLE_CARDS,
+ MENU_ITEM_OPTIONS,
+*/
+
+#ifdef SRR2_LEVEL_SELECTION
+ MENU_ITEM_LEVEL,
+#endif
+
+ NUM_MAIN_MENU_ITEMS
+};
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenMainMenu::CGuiScreenMainMenu
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMainMenu::CGuiScreenMainMenu
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+:
+ CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MAIN_MENU ),
+ m_pMenu( NULL ),
+ m_gags( NULL ),
+ m_currentGagIndex( -1 ),
+ m_nextGagIndex( -1 ),
+ m_nextHomerGagIndex( -1 ),
+ m_gagsElapsedTime( 0 ),
+ m_gagsCycleTime( 1000 * MIN_GAGS_CYCLE_TIME ),
+ m_homer( NULL ),
+ m_raceCar( NULL ),
+ m_homerIdleAnim( NULL ),
+ m_tvFrame( NULL )
+{
+MEMTRACK_PUSH_GROUP( "CGUIScreenMainMenu" );
+ memset( m_glowingItems, 0, sizeof( m_glowingItems ) );
+
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "MainMenu" );
+ rAssert( pPage != NULL );
+
+/*
+ // get accept button icon
+ //
+ if( m_buttonIcons[ BUTTON_ICON_ACCEPT ] == NULL )
+ {
+ m_buttonIcons[ BUTTON_ICON_ACCEPT ] = pPage->GetGroup( "AcceptLabel" );
+ rAssert( m_buttonIcons[ BUTTON_ICON_ACCEPT ] != NULL );
+ }
+*/
+
+ // Create a menu.
+ //
+ m_pMenu = new CGuiMenu( this, NUM_MAIN_MENU_ITEMS, GUI_TEXT_MENU );
+ rAssert( m_pMenu != NULL );
+
+ // Add menu items
+ //
+ Scrooby::Text* otherMainMenu = NULL;
+
+#ifdef RAD_WIN32
+ m_pMenu->AddMenuItem( pPage->GetText( "MainMenu_PC" ),
+ pPage->GetText( "MainMenu_PC" ),
+ NULL,
+ NULL,
+ pPage->GetSprite( "MainMenu_LArrow" ),
+ pPage->GetSprite( "MainMenu_RArrow" ) );
+
+ otherMainMenu = pPage->GetText( "MainMenu" );
+#else
+ m_pMenu->AddMenuItem( pPage->GetText( "MainMenu" ),
+ pPage->GetText( "MainMenu" ),
+ NULL,
+ NULL,
+ pPage->GetSprite( "MainMenu_LArrow" ),
+ pPage->GetSprite( "MainMenu_RArrow" ) );
+
+ otherMainMenu = pPage->GetText( "MainMenu_PC" );
+#endif
+
+ if( otherMainMenu != NULL )
+ {
+ otherMainMenu->SetVisible( false );
+ }
+
+ // wrap main menu text
+ //
+ Scrooby::Text* mainMenuText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_ITEM_MAIN_MENU )->GetItem() );
+ rAssert( mainMenuText != NULL );
+ mainMenuText->SetTextMode( Scrooby::TEXT_WRAP );
+
+#ifdef RAD_DEMO
+ m_pMenu->SetSelectionValueCount( MENU_ITEM_MAIN_MENU, NUM_MAIN_MENU_SELECTIONS );
+ m_pMenu->SetSelectionValue( MENU_ITEM_MAIN_MENU, MAIN_MENU_PLAY_LEVEL_2 );
+
+ HeapMgr()->PushHeap( GMA_LEVEL_FE );
+ mainMenuText->SetString( MAIN_MENU_PLAY_LEVEL_2, "PLAY LEVEL 2" ); // TC: [TODO] localization??
+ mainMenuText->SetString( MAIN_MENU_PLAY_LEVEL_7, "PLAY LEVEL 7" ); // TC: [TODO] localization??
+ HeapMgr()->PopHeap( GMA_LEVEL_FE );
+#endif
+
+ // scale up main menu text a bit
+ //
+// m_pMenu->GetMenuItem( MENU_ITEM_MAIN_MENU )->GetItem()->ScaleAboutCenter( 1.2f );
+
+ Scrooby::Page* levelPage = m_pScroobyScreen->GetPage( "Level" );
+ if( levelPage != NULL )
+ {
+#ifdef SRR2_LEVEL_SELECTION
+ m_pMenu->AddMenuItem( levelPage->GetText( "Level" ),
+ levelPage->GetText( "Level" ),
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED );
+
+ #ifndef RAD_DEBUG
+ // hide level/car selection menu by default
+ // in Tune and Release builds
+ //
+ this->ToggleLevelMenu();
+ #endif
+#else
+ Scrooby::Group* levelMenu = levelPage->GetGroup( "Menu" );
+ rAssert( levelMenu != NULL );
+ levelMenu->SetVisible( false );
+#endif
+ }
+
+ // Retrieve drawing elements from 3dFE page
+ //
+ pPage = m_pScroobyScreen->GetPage( "3dFE" );
+ rAssert( pPage != NULL );
+ m_homer = pPage->GetPure3dObject( "Homer" );
+ m_raceCar = pPage->GetPure3dObject( "RaceCar" );
+
+ // get glowing items
+ //
+#ifdef RAD_DEMO
+ m_glowingItems[ MAIN_MENU_PLAY_LEVEL_2 ] = pPage->GetPure3dObject( "Glow4" );
+ m_glowingItems[ MAIN_MENU_PLAY_LEVEL_7 ] = pPage->GetPure3dObject( "Glow4" );
+ m_glowingItems[ MAIN_MENU_OPTIONS ] = pPage->GetPure3dObject( "Glow2" );
+
+ Scrooby::Pure3dObject* glowingItem = NULL;
+
+ glowingItem = pPage->GetPure3dObject( "Glow0" );
+ rAssert( glowingItem != NULL );
+ glowingItem->SetVisible( false );
+
+ glowingItem = pPage->GetPure3dObject( "Glow1" );
+ rAssert( glowingItem != NULL );
+ glowingItem->SetVisible( false );
+
+ glowingItem = pPage->GetPure3dObject( "Glow3" );
+ rAssert( glowingItem != NULL );
+ glowingItem->SetVisible( false );
+
+ glowingItem = pPage->GetPure3dObject( "Glow5" );
+ rAssert( glowingItem != NULL );
+ glowingItem->SetVisible( false );
+#else
+ for( int i = 0; i < NUM_MAIN_MENU_SELECTIONS; i++ )
+ {
+ char name[ 16 ];
+ sprintf( name, "Glow%d", i );
+ m_glowingItems[ i ] = pPage->GetPure3dObject( name );
+ }
+#endif
+
+ this->TurnOnGlowItems( 0 ); // all off, by default
+
+ // 3D FE Gags
+ //
+ m_gags = m_pScroobyScreen->GetPage( "3dFEGags" );
+ rAssert( m_gags );
+
+ // Retrieve drawing elements from TVFrame page
+ //
+ pPage = m_pScroobyScreen->GetPage( "TVFrame" );
+ rAssert( pPage );
+ m_tvFrame = pPage->GetLayer( "TVFrame" );
+
+ // correct TV frame proportion and size on GC and PS2 and pc
+ //
+ Scrooby::Sprite* tvFrame = pPage->GetSprite( "TVFrame" );
+ if( tvFrame != NULL )
+ {
+ tvFrame->ResetTransformation();
+
+#ifdef RAD_GAMECUBE
+ tvFrame->ScaleAboutCenter( 1.1f, 1.0f, 1.0f );
+#endif
+
+#ifdef RAD_PS2
+ tvFrame->ScaleAboutCenter( 1.07f );
+#endif
+
+#ifdef RAD_WIN32
+ tvFrame->ScaleAboutCenter( 1.03f );
+#endif
+ }
+MEMTRACK_POP_GROUP( "CGUIScreenMainMenu" );
+}
+
+
+//===========================================================================
+// CGuiScreenMainMenu::~CGuiScreenMainMenu
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMainMenu::~CGuiScreenMainMenu()
+{
+ if( m_nextGagIndex == -1 )
+ {
+ // stop any FE gag dialog that was triggered and may still be playing
+ //
+ GetEventManager()->TriggerEvent( EVENT_FE_GAG_STOP );
+ }
+
+ if( m_homerIdleAnim != NULL )
+ {
+ m_homerIdleAnim->Release();
+ m_homerIdleAnim = NULL;
+ }
+
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+
+ // restore black clear colour
+ //
+ GetRenderManager()->mpLayer(RenderEnums::GUI)->pView( 0 )->SetClearColour( tColour( 0, 0, 0 ) );
+}
+
+
+//===========================================================================
+// CGuiScreenMainMenu::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMainMenu::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( message == GUI_MSG_MENU_PROMPT_RESPONSE )
+ {
+#ifndef RAD_WIN32
+ rAssert( param1 == PROMPT_CONFIRM_NEW_GAME );
+#endif
+
+ if( param1 == PROMPT_CONFIRM_NEW_GAME )
+ {
+ switch( param2 )
+ {
+ case CGuiMenuPrompt::RESPONSE_YES:
+ {
+#ifdef SRR2_LEVEL_SELECTION
+ int level = m_pMenu->GetSelectionValue( MENU_ITEM_LEVEL );
+ this->OnNewGameSelected( static_cast<RenderEnums::LevelEnum>( level ) );
+#else
+ this->OnNewGameSelected();
+#endif // SRR2_LEVEL_SELECTION
+
+ CGuiScreen* pScreen = static_cast<CGuiScreen*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_GENERIC_PROMPT ) );
+ rAssert( pScreen != NULL );
+ pScreen->StartTransitionAnimation( 0, 53 );
+
+ break;
+ }
+ case CGuiMenuPrompt::RESPONSE_NO:
+ {
+ this->ReloadScreen();
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Invalid prompt response!" );
+
+ break;
+ }
+ }
+ }
+#ifdef RAD_WIN32
+ else if( param1 == PROMPT_CONFIRM_QUIT )
+ {
+ switch( param2 )
+ {
+ case (CGuiMenuPrompt::RESPONSE_YES):
+ {
+ // send message to front-end manager to quit front-end and
+ // exit the game.
+ //
+ m_pParent->HandleMessage( GUI_MSG_QUIT_GAME );
+
+ break;
+ }
+
+ case (CGuiMenuPrompt::RESPONSE_NO):
+ {
+ this->ReloadScreen();
+
+ break;
+ }
+
+ default:
+ {
+ rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" );
+
+ break;
+ }
+ }
+ }
+#endif
+ }
+
+ if( m_firstTimeEntered &&
+ message == GUI_MSG_WINDOW_ENTER )
+ {
+ if( CGuiScreenIntroTransition::s_introTransitionPlayed )
+ {
+ this->SetFadingEnabled( false );
+ }
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ this->UpdateRunning( param1 );
+
+ break;
+ }
+#ifdef SRR2_LEVEL_SELECTION
+ // show/hide level and car selection menu (for Tune and Release)
+ //
+ case GUI_MSG_CONTROLLER_L1:
+ case GUI_MSG_CONTROLLER_R1:
+ {
+ this->ToggleLevelMenu();
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_START:
+ {
+ if( m_pMenu->GetSelection() == MENU_ITEM_LEVEL )
+ {
+ rAssert( m_pMenu != NULL );
+ m_pMenu->Reset();
+ m_pMenu->SetSelectionValue( 0, MAIN_MENU_NEW_GAME );
+ }
+
+ break;
+ }
+#endif
+ case GUI_MSG_MENU_SELECTION_VALUE_CHANGED:
+ {
+ if( param1 == MENU_ITEM_MAIN_MENU )
+ {
+ // turn on new glow item
+ //
+ this->TurnOnGlowItems( (1 << param2) );
+
+#ifndef RAD_DEMO
+ if( param2 == MAIN_MENU_MINI_GAME ) // special case for mini-game
+ {
+ if( !GetCharacterSheetManager()->IsMiniGameUnlocked() &&
+ !CommandLineOptions::Get( CLO_SKIP_FE ) )
+ {
+ // don't turn on glowing track
+ //
+ this->TurnOnGlowItems( 0 );
+
+ // grey out selection
+ //
+ m_pMenu->GetMenuItem( MENU_ITEM_MAIN_MENU )->GetItemValue()->SetColour( tColour( 128, 128, 128 ) );
+
+ // hide accept button icon
+ //
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, false );
+#ifdef RAD_WIN32
+ GetInputManager()->GetFEMouse()->SetClickable( false );
+#endif
+
+ }
+ }
+ else
+ {
+ // restore menu selection colour and accept button icon
+ //
+ tColour menuHighlightColour = m_pMenu->GetHighlightColour();
+ m_pMenu->GetMenuItem( MENU_ITEM_MAIN_MENU )->GetItemValue()->SetColour( menuHighlightColour );
+
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, true );
+#ifdef RAD_WIN32
+ GetInputManager()->GetFEMouse()->SetClickable( true );
+#endif
+ }
+#endif // !RAD_DEMO
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ if( !this->IsButtonVisible( BUTTON_ICON_ACCEPT ) )
+ {
+ return;
+ }
+#ifdef RAD_DEMO
+ if( m_pMenu->GetSelectionValue( MENU_ITEM_MAIN_MENU ) == MAIN_MENU_PLAY_LEVEL_2 ||
+ m_pMenu->GetSelectionValue( MENU_ITEM_MAIN_MENU ) == MAIN_MENU_PLAY_LEVEL_7 )
+#else
+ if( m_pMenu->GetSelectionValue( MENU_ITEM_MAIN_MENU ) == MAIN_MENU_NEW_GAME ||
+ m_pMenu->GetSelectionValue( MENU_ITEM_MAIN_MENU ) == MAIN_MENU_RESUME_GAME )
+#endif
+ {
+ GetInputManager()->RegisterControllerID( 0, param1 );
+ GetGuiSystem()->SetPrimaryController(param1);
+ }
+
+#ifndef RAD_DEMO
+ if( m_pMenu->GetSelectionValue( MENU_ITEM_MAIN_MENU ) == MAIN_MENU_MINI_GAME )
+ {
+ GetGuiSystem()->SetPrimaryController(param1);
+ }
+#endif // !RAD_DEMO
+
+ break;
+ }
+#ifdef RAD_WIN32
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ this->OnQuitGameSelected();
+
+ break;
+ }
+#endif
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ rAssert( param1 == MENU_ITEM_MAIN_MENU );
+ rAssert( m_pMenu != NULL );
+ int menuSelection = m_pMenu->GetSelectionValue( param1 );
+
+ switch( menuSelection )
+ {
+#ifdef RAD_DEMO
+ case MAIN_MENU_PLAY_LEVEL_2:
+ {
+ this->OnNewGameSelected( RenderEnums::L2, RenderEnums::M1 );
+
+ break;
+ }
+ case MAIN_MENU_PLAY_LEVEL_7:
+ {
+ this->OnNewGameSelected( RenderEnums::L7, RenderEnums::M1 );
+
+ break;
+ }
+#else
+ case MAIN_MENU_NEW_GAME:
+ {
+ if( GetGameDataManager()->IsGameLoaded() )
+ {
+ // prompt user to confirm first
+ //
+ m_guiManager->DisplayPrompt( PROMPT_CONFIRM_NEW_GAME, this );
+ }
+ else
+ {
+#ifdef SRR2_LEVEL_SELECTION
+ int level = m_pMenu->GetSelectionValue( MENU_ITEM_LEVEL );
+ this->OnNewGameSelected( static_cast<RenderEnums::LevelEnum>( level ) );
+#else
+ this->OnNewGameSelected();
+#endif // SRR2_LEVEL_SELECTION
+ }
+
+ break;
+ }
+ case MAIN_MENU_RESUME_GAME:
+ {
+ this->OnResumeGameSelected();
+
+ break;
+ }
+ case MAIN_MENU_MINI_GAME:
+ {
+ this->OnMiniGameSelected();
+
+ break;
+ }
+ case MAIN_MENU_LOAD_GAME:
+ {
+#ifdef RAD_XBOX
+ // Xbox TCR Requirement: always prompt user to select memory
+ // device before loading/saving
+ //
+ CGuiScreenLoadSave::s_forceGotoMemoryCardScreen = true;
+#endif // RAD_XBOX
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_LOAD_GAME );
+
+ this->StartTransitionAnimation( 200, 230 );
+
+ break;
+ }
+ case MAIN_MENU_CARD_GALLERY:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SCRAP_BOOK );
+
+ this->StartTransitionAnimation( 320, 350 );
+
+ break;
+ }
+#endif // RAD_DEMO
+ case MAIN_MENU_OPTIONS:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_OPTIONS );
+
+ this->StartTransitionAnimation( 80, 110 );
+
+ break;
+ }
+#ifdef RAD_WIN32
+ case MAIN_MENU_QUIT_GAME:
+ {
+ this->OnQuitGameSelected();
+
+ break;
+ }
+#endif
+ default:
+ {
+ rAssertMsg( false, "Invalid main menu selection!" );
+
+ break;
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ if( m_pMenu != NULL )
+ {
+ // relay message to menu
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+ else if( m_state == GUI_WINDOW_STATE_INTRO )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ this->UpdateIntro( param1 );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ else if( m_state == GUI_WINDOW_STATE_OUTRO )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ this->UpdateOutro( param1 );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+void
+CGuiScreenMainMenu::InitMenu()
+{
+#ifndef RAD_DEMO
+ bool isGameLoaded = GetGameDataManager()->IsGameLoaded();
+
+ rAssert( m_pMenu != NULL );
+ m_pMenu->SetSelectionValueCount( MENU_ITEM_MAIN_MENU,
+ isGameLoaded ? NUM_MAIN_MENU_SELECTIONS : NUM_MAIN_MENU_SELECTIONS - 1 );
+
+ m_pMenu->SetSelectionValue( MENU_ITEM_MAIN_MENU,
+ isGameLoaded ? MAIN_MENU_RESUME_GAME : MAIN_MENU_NEW_GAME );
+#endif // !RAD_DEMO
+}
+
+//===========================================================================
+// CGuiScreenMainMenu::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMainMenu::InitIntro()
+{
+ if( m_firstTimeEntered )
+ {
+ this->SetFadeTime( FIRST_TIME_FADE_IN_TIME );
+ this->InitMenu();
+
+ // set clear colour to a blue sky colour
+ //
+ GetRenderManager()->mpLayer(RenderEnums::GUI)->pView( 0 )->SetClearColour( FE_BLUE_SKY_COLOUR );
+ }
+}
+
+//===========================================================================
+// CGuiScreenMainMenu::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMainMenu::InitRunning()
+{
+ if( m_firstTimeEntered )
+ {
+ this->SetFadingEnabled( true );
+ this->RestoreDefaultFadeTime();
+
+ m_screenCover = NULL;
+ }
+
+ // turn on current glow item
+ //
+ rAssert( m_pMenu != NULL );
+ this->TurnOnGlowItems( (1 << m_pMenu->GetSelectionValue( MENU_ITEM_MAIN_MENU )) );
+}
+
+//===========================================================================
+// CGuiScreenMainMenu::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMainMenu::InitOutro()
+{
+ if( m_nextGagIndex == -1 )
+ {
+ // stop any FE gag dialog that was triggered and may still be playing
+ //
+ GetEventManager()->TriggerEvent( EVENT_FE_GAG_STOP );
+ }
+
+ // turn off all glow items
+ //
+ this->TurnOnGlowItems( 0 );
+}
+
+//===========================================================================
+// CGuiScreenMainMenu::UpdateIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMainMenu::UpdateIntro( unsigned int elapsedTime )
+{
+ if( m_firstTimeEntered )
+ {
+ // hide duplicate homer
+ //
+ if( m_gags != NULL )
+ {
+ Scrooby::Pure3dObject* p3dGag = m_gags->GetPure3dObject( "Gag0" );
+ rAssert( p3dGag );
+ if( p3dGag->GetMultiController() != NULL )
+ {
+ p3dGag->SetVisible( false );
+ }
+ }
+ }
+}
+
+//===========================================================================
+// CGuiScreenMainMenu::UpdateRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMainMenu::UpdateRunning( unsigned int elapsedTime )
+{
+ GetMemoryCardManager()->Update( elapsedTime );
+ this->UpdateGags( elapsedTime );
+}
+
+//===========================================================================
+// CGuiScreenMainMenu::UpdateOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMainMenu::UpdateOutro( unsigned int elapsedTime )
+{
+ int currentMenuSelection = m_pMenu->GetSelectionValue( MENU_ITEM_MAIN_MENU );
+
+#ifdef RAD_DEMO
+ if( currentMenuSelection == MAIN_MENU_PLAY_LEVEL_2 ||
+ currentMenuSelection == MAIN_MENU_PLAY_LEVEL_7 )
+#else
+ if( currentMenuSelection == MAIN_MENU_NEW_GAME ||
+ currentMenuSelection == MAIN_MENU_RESUME_GAME ||
+ currentMenuSelection == MAIN_MENU_MINI_GAME )
+#endif
+ {
+ rAssert( m_p3dObject != NULL );
+
+ tMultiController* multiController = m_p3dObject->GetMultiController();
+ if( multiController != NULL )
+ {
+ const float NUM_FADE_OUT_FRAMES = 15.0f;
+ float currentFrame = multiController->GetFrame();
+ float numRemainingFrames = multiController->GetNumFrames() - currentFrame;
+
+ if( numRemainingFrames < NUM_FADE_OUT_FRAMES )
+ {
+ // fade out TV frame
+ //
+ if( m_tvFrame != NULL )
+ {
+ float alpha = numRemainingFrames / NUM_FADE_OUT_FRAMES;
+
+ // decrease fade rate for low alpha values
+ alpha *= alpha;
+
+ if( alpha > 0.0f && alpha < 1.0f )
+ {
+ m_tvFrame->SetAlpha( alpha );
+ }
+ else
+ {
+ m_tvFrame->SetAlpha( 0.0f );
+ }
+ }
+
+ // TC [HACK]: To prevent any clipping in homer's mouth
+ // in the last few frames.
+ //
+ if( numRemainingFrames < 1.0f )
+ {
+ this->RestoreScreenCover();
+ }
+ }
+
+#ifndef RAD_DEMO
+ if( currentMenuSelection == MAIN_MENU_MINI_GAME )
+ {
+ const float NUM_RACE_CAR_FRAMES_FOR_BLENDING = 11.0f;
+
+ rAssert( m_raceCar != NULL );
+ if( currentFrame < 1.0f )
+ {
+ // get number of frames remaining in race car animation
+ //
+ tMultiController* raceMultiController = m_raceCar->GetMultiController();
+ rAssert( raceMultiController != NULL );
+
+ int currentRaceFrame = (int)raceMultiController->GetFrame() % (int)raceMultiController->GetNumFrames();
+ float numRemainingRaceFrames = raceMultiController->GetNumFrames() - currentRaceFrame;
+ raceMultiController->SetRelativeSpeed( numRemainingRaceFrames / NUM_RACE_CAR_FRAMES_FOR_BLENDING );
+ }
+ else if( currentFrame > NUM_RACE_CAR_FRAMES_FOR_BLENDING )
+ {
+ // hide duplicate race car
+ //
+ m_raceCar->SetVisible( false );
+ }
+ }
+#endif // !RAD_DEMO
+ }
+ }
+}
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+//===========================================================================
+// CGuiScreenMainMenu::UpdateGags
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMainMenu::UpdateGags( unsigned int elapsedTime )
+{
+ static float NUM_BLEND_FRAMES = 10.0f;
+
+ // if the homer gag animation is running
+ //
+ if( m_homerIdleAnim != NULL && m_homer != NULL )
+ {
+ // check if homer gag animation is done
+ //
+ tMultiController* homerMultiController = m_homer->GetMultiController();
+ if( homerMultiController != NULL )
+ {
+ tAnimationFrameController* homerFrameController =
+ (tAnimationFrameController*)homerMultiController->GetTrack( 0 );
+ rAssert( homerFrameController );
+
+ if( homerFrameController->LastFrameReached() > 0 )
+ {
+ // ok, last frame has been reached on homer gag animation;
+ // restore the homer idle animation
+ //
+ if( m_homerIdleAnim != NULL )
+ {
+ homerFrameController->SetAnimation( m_homerIdleAnim, 0.0f, 0.0f );
+
+ m_homerIdleAnim->Release();
+ m_homerIdleAnim = NULL;
+ }
+
+ // restore homer idle animation frame range
+ //
+ homerMultiController->SetFrameRange( 0.0f, 60.0f );
+ homerMultiController->Reset();
+ }
+ }
+ }
+
+ // advance gag timer
+ //
+ m_gagsElapsedTime += elapsedTime;
+
+ const unsigned int FE_GAG_PREP_TIME = 2000; // in msec
+ if( m_gagsElapsedTime > (m_gagsCycleTime - FE_GAG_PREP_TIME) )
+ {
+ if( m_nextGagIndex == -1 )
+ {
+ // prepare for next gag
+ //
+#ifdef PLAY_ONLY_HOMER_GAGS
+ m_nextGagIndex = 0;
+#else
+ #ifdef PLAY_GAGS_SEQUENTIALLY
+ m_nextGagIndex = (m_currentGagIndex + 1) % m_gags->GetNumberOfLayers();
+ #else
+ int random = (rand() / 10) % GAGS_RANDOM_NUMBER_MODULO;
+ m_nextGagIndex = random % m_gags->GetNumberOfLayers();
+
+ if( CommandLineOptions::Get( CLO_FE_GAGS_TEST ) )
+ {
+ rReleasePrintf( "Next FE Gag Index = %d (Random Number = %d)\n", m_nextGagIndex, random );
+ }
+ #endif
+#endif
+ if( m_nextGagIndex != 0 )
+ {
+ GetEventManager()->TriggerEvent( EVENT_FE_GAG_INIT, reinterpret_cast<void*>( FE_GAGS[ m_nextGagIndex ] ) );
+ }
+ else // multiple homer gags
+ {
+ // pick a random homer animation
+ //
+#ifdef PLAY_GAGS_SEQUENTIALLY
+ m_nextHomerGagIndex = (m_nextHomerGagIndex + 1) % NUM_HOMER_GAG_ANIMATIONS;
+#else
+ int random = (rand() / 10) % GAGS_RANDOM_NUMBER_MODULO;
+ m_nextHomerGagIndex = random % NUM_HOMER_GAG_ANIMATIONS;
+
+ if( CommandLineOptions::Get( CLO_FE_GAGS_TEST ) )
+ {
+ rReleasePrintf( " Next Homer Gag Index = %d (Random Number = %d)\n", m_nextHomerGagIndex, random );
+ }
+#endif
+
+ GetEventManager()->TriggerEvent( EVENT_FE_GAG_INIT, reinterpret_cast<void*>( FE_GAGS_FOR_HOMER[ m_nextHomerGagIndex ] ) );
+ }
+ }
+ }
+
+ if( m_gagsElapsedTime > m_gagsCycleTime )
+ {
+ if( m_gags != NULL )
+ {
+ Scrooby::Layer* currentGagLayer = NULL;
+
+ // hide previous gag layer, if exists
+ //
+ if( m_currentGagIndex != -1 )
+ {
+ currentGagLayer = m_gags->GetLayerByIndex( m_currentGagIndex );
+ currentGagLayer->SetVisible( false );
+ }
+
+ m_currentGagIndex = m_nextGagIndex;
+ m_nextGagIndex = -1;
+
+ // get the pure3d gag
+ //
+ char objectName[ 8 ];
+ sprintf( objectName, "Gag%d", m_currentGagIndex );
+ Scrooby::Pure3dObject* p3dGag = m_gags->GetPure3dObject( objectName );
+
+ // reset gag animation
+ //
+ rAssert( p3dGag );
+ tMultiController* multiController = p3dGag->GetMultiController();
+ if( multiController != NULL )
+ {
+ multiController->Reset();
+ }
+
+ // show current gag layer
+ //
+ currentGagLayer = m_gags->GetLayerByIndex( m_currentGagIndex );
+ rAssert( currentGagLayer );
+ currentGagLayer->SetVisible( true );
+
+ // start FE gag dialog
+ //
+ GetEventManager()->TriggerEvent( EVENT_FE_GAG_START );
+
+ if( m_currentGagIndex == 0 )
+ {
+ // special case for homer gag animation
+ //
+ if( m_homer != NULL && multiController != NULL )
+ {
+ tAnimationFrameController* frameController =
+ (tAnimationFrameController*)multiController->GetTrack( 0 );
+ rAssert( frameController );
+
+ // get homer gag animation
+ tAnimation* homerAnim = frameController->GetAnimation();
+ rAssert( homerAnim );
+ homerAnim->SetCyclic( false ); // don't cycle when done
+
+ tMultiController* homerMultiController = m_homer->GetMultiController();
+ if( homerMultiController != NULL )
+ {
+ homerMultiController->SetFrameRange( HOMER_GAG_ANIMATION[ m_nextHomerGagIndex ].startFrame,
+ HOMER_GAG_ANIMATION[ m_nextHomerGagIndex ].endFrame );
+
+ tAnimationFrameController* homerFrameController =
+ (tAnimationFrameController*)homerMultiController->GetTrack( 0 );
+ rAssert( homerFrameController );
+
+ // save reference to homer idle animation
+ //
+ m_homerIdleAnim = homerFrameController->GetAnimation();
+ rAssert( m_homerIdleAnim != NULL );
+ m_homerIdleAnim->AddRef();
+
+ // switch to the homer gag animation
+ homerFrameController->SetAnimation( homerAnim, 0.0f, NUM_BLEND_FRAMES );
+ }
+ }
+ }
+ }
+
+ // set new random gag cycle time
+ //
+ if( CommandLineOptions::Get( CLO_FE_GAGS_TEST ) )
+ {
+ m_gagsCycleTime = 1000 * MIN_GAGS_CYCLE_TIME;
+ }
+ else
+ {
+ m_gagsCycleTime = 1000 * (MIN_GAGS_CYCLE_TIME + rand() % (MAX_GAGS_CYCLE_TIME - MIN_GAGS_CYCLE_TIME + 1));
+ }
+
+ // reset gag timer
+ //
+ m_gagsElapsedTime = 0;
+ }
+}
+
+//===========================================================================
+// CGuiScreenMainMenu::StopHomerIdleAnimation
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMainMenu::StopHomerIdleAnimation()
+{
+/*
+ if( m_homer != NULL )
+ {
+ // reset Homer's snoring animation so that the camera
+ // can pan right into his mouth
+ //
+ tMultiController* multiController = m_homer->GetMultiController();
+ if( multiController != NULL )
+ {
+ tAnimationFrameController* frameController = (tAnimationFrameController*)multiController->GetTrack( 0 );
+ rAssert( frameController );
+
+ if( m_homerIdleAnim == NULL )
+ {
+ m_homerIdleAnim = frameController->GetAnimation();
+ rAssert( m_homerIdleAnim );
+ }
+
+ m_homerIdleAnim->SetCyclic( false );
+
+ static float NUM_BLEND_FRAMES = 10.0f;
+ frameController->SetAnimation( m_homerIdleAnim,
+ m_homerIdleAnim->GetNumFrames() - NUM_BLEND_FRAMES,
+ NUM_BLEND_FRAMES );
+
+ m_homerIdleAnim = NULL;
+ }
+ }
+*/
+}
+
+//===========================================================================
+// CGuiScreenMainMenu::TurnOnGlowItems
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: items - bitmask representing which ones to turn on glowing
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMainMenu::TurnOnGlowItems( unsigned int items )
+{
+#ifdef RAD_DEMO
+ if( items > 0 )
+ {
+ bool isOptionsSelected = ( (items & (1 << MAIN_MENU_OPTIONS)) > 0 );
+ m_glowingItems[ MAIN_MENU_PLAY_LEVEL_2 ]->SetVisible( !isOptionsSelected );
+ m_glowingItems[ MAIN_MENU_OPTIONS ]->SetVisible( isOptionsSelected );
+
+ return;
+ }
+#endif
+
+#ifdef RAD_WIN32
+ for( int i = 0; i < NUM_MAIN_MENU_SELECTIONS; i++ )
+ {
+ bool isOn = (items & (1 << i)) > 0;
+ int which = i < MAIN_MENU_QUIT_GAME ? i : i - 1;
+ if( m_glowingItems[ which ] != NULL && i != MAIN_MENU_QUIT_GAME )
+ {
+ m_glowingItems[ which ]->SetVisible( isOn );
+ }
+ }
+#else
+ for( int i = 0; i < NUM_MAIN_MENU_SELECTIONS; i++ )
+ {
+ bool isOn = (items & (1 << i)) > 0;
+ if( m_glowingItems[ i ] != NULL )
+ {
+ m_glowingItems[ i ]->SetVisible( isOn );
+ }
+ }
+#endif
+}
+
+void
+CGuiScreenMainMenu::OnNewGameSelected( RenderEnums::LevelEnum level,
+ RenderEnums::MissionEnum mission )
+{
+ bool showNewGameMovie = false;
+
+#ifdef RAD_RELEASE
+ #ifndef RAD_DEMO
+ showNewGameMovie = !CommandLineOptions::Get( CLO_SKIP_MOVIE );
+ #endif
+#endif
+
+ if( showNewGameMovie )
+ {
+ // play new game movie
+ //
+ rAssert( m_guiManager );
+ CGuiScreenPlayMovie* playMovieScreen = static_cast<CGuiScreenPlayMovie*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME ) );
+ rAssert( playMovieScreen );
+
+ playMovieScreen->SetMovieToPlay( MovieNames::MOVIE1, false, true );
+
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME );
+ }
+ else
+ {
+ // send message to front-end manager to quit front-end and
+ // start single player story mode
+ //
+ m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 1 ); // 1 = one player
+ }
+
+ this->StartTransitionAnimation( 0, 53 );
+
+ this->StopHomerIdleAnimation();
+
+ if( GetGameDataManager()->IsGameLoaded() )
+ {
+ // reset all game data
+ //
+ GetGameDataManager()->ResetGame();
+
+ //reset the rewards manager and relock the rewards
+ //
+ GetRewardsManager()->ClearRewards();
+ }
+
+ GetCharacterSheetManager()->SetCurrentMission( level, mission );
+
+ // restore black clear colour
+ //
+ GetRenderManager()->mpLayer(RenderEnums::GUI)->pView( 0 )->SetClearColour( tColour( 0, 0, 0 ) );
+}
+
+void
+CGuiScreenMainMenu::OnResumeGameSelected()
+{
+ // send message to front-end manager to quit front-end and
+ // start single player story mode
+ //
+ m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 1 ); // 1 = one player
+
+ this->StartTransitionAnimation( 140, 170 );
+}
+
+void
+CGuiScreenMainMenu::OnMiniGameSelected()
+{
+ // send message to front-end manager to quit front-end and
+ // start mini-game mode
+ //
+ m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 2 ); // 2 = mini-game
+
+ this->StartTransitionAnimation( 880, 913 );
+}
+
+#ifdef RAD_WIN32
+void
+CGuiScreenMainMenu::OnQuitGameSelected()
+{
+ rAssert( m_guiManager != NULL );
+ m_guiManager->DisplayPrompt( PROMPT_CONFIRM_QUIT, this );
+}
+#endif
+
+#ifdef SRR2_LEVEL_SELECTION
+void
+CGuiScreenMainMenu::ToggleLevelMenu()
+{
+ Scrooby::Page* levelPage = m_pScroobyScreen->GetPage( "Level" );
+ if( levelPage != NULL )
+ {
+ Scrooby::Group* levelMenu = levelPage->GetGroup( "Menu" );
+ rAssert( levelMenu );
+
+ bool toggle = !levelMenu->IsVisible();
+
+ // display menu on/off
+ levelMenu->SetVisible( toggle );
+
+ // enable/disable menu selections
+ for( int i = MENU_ITEM_LEVEL; i <= MENU_ITEM_LEVEL; i++ )
+ {
+ m_pMenu->SetMenuItemEnabled( i, toggle );
+ }
+ }
+}
+#endif // SRR2_LEVEL_SELECTION
+
+//===========================================================================
+// Public Member Functions (for CGuiScreenIntroTransition)
+//===========================================================================
+
+bool CGuiScreenIntroTransition::s_introTransitionPlayed = false;
+
+//===========================================================================
+// CGuiScreenIntroTransition::CGuiScreenIntroTransition
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenIntroTransition::CGuiScreenIntroTransition
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_INTRO_TRANSITION ),
+ m_introState( WAITING_FOR_MULTICONTROLLER ),
+ m_homer( NULL ),
+ m_tvFrame( NULL ),
+ m_gags( NULL )
+{
+ this->SetFadingEnabled( false );
+
+ // Retrieve drawing elements from 3dFE page
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "3dFE" );
+ rAssert( pPage );
+ m_homer = pPage->GetPure3dObject( "Homer" );
+
+ // Retrieve drawing elements from TVFrame page
+ //
+ pPage = m_pScroobyScreen->GetPage( "TVFrame" );
+ rAssert( pPage );
+ m_tvFrame = pPage->GetLayer( "TVFrame" );
+
+ // 3D FE Gags
+ //
+ m_gags = m_pScroobyScreen->GetPage( "3dFEGags" );
+ rAssert( m_gags );
+
+ s_introTransitionPlayed = false;
+}
+
+
+//===========================================================================
+// CGuiScreenIntroTransition::~CGuiScreenIntroTransition
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenIntroTransition::~CGuiScreenIntroTransition()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenIntroTransition::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenIntroTransition::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+
+ if( m_state == GUI_WINDOW_STATE_INTRO &&
+ message == GUI_MSG_UPDATE )
+ {
+ switch( m_introState )
+ {
+ case WAITING_FOR_MULTICONTROLLER:
+ {
+ if( s_p3dMultiController != NULL )
+ {
+ m_numTransitionsPending--;
+
+ this->StartTransitionAnimation( 721, 770, false );
+
+ if( m_screenCover != NULL )
+ {
+ m_screenCover->SetVisible( false );
+ }
+
+ m_introState = RUNNING_INTRO_ANIMATION;
+ }
+ else
+ {
+ if( m_screenCover != NULL )
+ {
+ m_screenCover->SetAlpha( 1.0f );
+ }
+ }
+
+ break;
+ }
+
+ default:
+ {
+ if( m_tvFrame != NULL )
+ {
+ rAssert( m_p3dObject );
+
+ tMultiController* multiController = m_p3dObject->GetMultiController();
+ rAssert( multiController );
+
+ const float NUM_FADE_IN_FRAMES = 20.0f;
+ float numRemainingFrames = multiController->GetNumFrames() -
+ multiController->GetFrame();
+
+ if( numRemainingFrames < NUM_FADE_IN_FRAMES )
+ {
+ float alpha = 1.0f - numRemainingFrames / NUM_FADE_IN_FRAMES;
+
+ // decrease fade rate for low alpha values
+ alpha *= alpha;
+
+ if( alpha < 1.0f )
+ {
+ // fade in TV frame
+ //
+ if( m_tvFrame != NULL )
+ {
+ m_tvFrame->SetAlpha( alpha );
+ }
+
+ // fade in foreground layers
+ //
+ this->SetAlphaForLayers( alpha,
+ m_foregroundLayers,
+ m_numForegroundLayers );
+ }
+ }
+ }
+
+ break;
+ }
+ }
+
+ // hide duplicate homer
+ //
+ if( m_gags != NULL )
+ {
+ Scrooby::Pure3dObject* p3dGag = m_gags->GetPure3dObject( "Gag0" );
+ rAssert( p3dGag );
+ if( p3dGag->GetMultiController() != NULL )
+ {
+ p3dGag->SetVisible( false );
+ }
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenIntroTransition::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenIntroTransition::InitIntro()
+{
+ // wait for retrieval of pure3d multicontroller
+ m_numTransitionsPending++;
+
+ if( m_tvFrame != NULL )
+ {
+ m_tvFrame->SetAlpha( 0.0f );
+
+ this->SetAlphaForLayers( 0.0f,
+ m_foregroundLayers,
+ m_numForegroundLayers );
+ }
+
+ CGuiScreenMainMenu* pScreen = static_cast<CGuiScreenMainMenu*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_MAIN_MENU ) );
+ rAssert( pScreen != NULL );
+ pScreen->InitMenu();
+}
+
+
+//===========================================================================
+// CGuiScreenIntroTransition::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenIntroTransition::InitRunning()
+{
+ s_introTransitionPlayed = true;
+
+ if( m_tvFrame != NULL )
+ {
+ m_tvFrame->SetAlpha( 1.0f );
+
+ this->SetAlphaForLayers( 1.0f,
+ m_foregroundLayers,
+ m_numForegroundLayers );
+ }
+
+ // goto main menu
+ //
+ rAssert( m_pParent );
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ GUI_SCREEN_ID_MAIN_MENU,
+ CLEAR_WINDOW_HISTORY );
+}
+
+
+//===========================================================================
+// CGuiScreenIntroTransition::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenIntroTransition::InitOutro()
+{
+}
+
diff --git a/game/code/presentation/gui/frontend/guiscreenmainmenu.h b/game/code/presentation/gui/frontend/guiscreenmainmenu.h
new file mode 100644
index 0000000..733fa58
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenmainmenu.h
@@ -0,0 +1,157 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMainMenu
+//
+// Description:
+//
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/11/20 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMAINMENU_H
+#define GUISCREENMAINMENU_H
+
+#ifndef FINAL
+ #ifndef RAD_DEMO
+ #define SRR2_LEVEL_SELECTION // for SRR2 level selection
+ #endif
+#endif
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+#include <render/enums/renderenums.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+class tAnimation;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMainMenu : public CGuiScreen
+{
+public:
+ CGuiScreenMainMenu( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenMainMenu();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ void InitMenu();
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+ void UpdateIntro( unsigned int elapsedTime );
+ void UpdateRunning( unsigned int elapsedTime );
+ void UpdateOutro( unsigned int elapsedTime );
+
+private:
+ enum eMainMenuSelection
+ {
+#ifdef RAD_DEMO
+ MAIN_MENU_PLAY_LEVEL_2,
+ MAIN_MENU_PLAY_LEVEL_7,
+ MAIN_MENU_OPTIONS,
+#else
+ MAIN_MENU_LOAD_GAME,
+ MAIN_MENU_CARD_GALLERY,
+ MAIN_MENU_OPTIONS,
+ MAIN_MENU_MINI_GAME,
+ #ifdef RAD_WIN32
+ MAIN_MENU_QUIT_GAME,
+ #endif
+ MAIN_MENU_NEW_GAME,
+ MAIN_MENU_RESUME_GAME,
+#endif
+
+ NUM_MAIN_MENU_SELECTIONS
+ };
+
+ void UpdateGags( unsigned int elapsedTime );
+ void StopHomerIdleAnimation();
+ void TurnOnGlowItems( unsigned int items );
+
+ void OnNewGameSelected( RenderEnums::LevelEnum level = RenderEnums::L1,
+ RenderEnums::MissionEnum mission = RenderEnums::M1 );
+
+ void OnResumeGameSelected();
+ void OnMiniGameSelected();
+
+#ifdef RAD_WIN32
+ void OnQuitGameSelected();
+#endif
+
+#ifdef SRR2_LEVEL_SELECTION
+ void ToggleLevelMenu();
+#endif
+
+ CGuiMenu* m_pMenu;
+
+ Scrooby::Page* m_gags;
+ int m_currentGagIndex;
+ int m_nextGagIndex;
+ int m_nextHomerGagIndex;
+ unsigned int m_gagsElapsedTime;
+ unsigned int m_gagsCycleTime;
+
+ Scrooby::Pure3dObject* m_homer;
+ Scrooby::Pure3dObject* m_raceCar;
+ tAnimation* m_homerIdleAnim;
+ Scrooby::Layer* m_tvFrame;
+
+ Scrooby::Pure3dObject* m_glowingItems[ NUM_MAIN_MENU_SELECTIONS ];
+
+};
+
+
+class CGuiScreenIntroTransition: public CGuiScreen
+{
+public:
+ CGuiScreenIntroTransition( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenIntroTransition();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ static bool s_introTransitionPlayed;
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ enum eState
+ {
+ WAITING_FOR_MULTICONTROLLER,
+ RUNNING_INTRO_ANIMATION,
+
+ NUM_STATES
+ };
+
+ eState m_introState;
+ Scrooby::Pure3dObject* m_homer;
+ Scrooby::Layer* m_tvFrame;
+ Scrooby::Page* m_gags;
+
+};
+
+#endif // GUISCREENMAINMENU_H
diff --git a/game/code/presentation/gui/frontend/guiscreenmissiongallery.cpp b/game/code/presentation/gui/frontend/guiscreenmissiongallery.cpp
new file mode 100644
index 0000000..e0d9113
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenmissiongallery.cpp
@@ -0,0 +1,860 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMissionGallery
+//
+// Description: Implementation of the CGuiScreenMissionGallery class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/19 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreenmissiongallery.h>
+#include <presentation/gui/frontend/guiscreenscrapbookcontents.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guiscreenprompt.h>
+
+#include <cheats/cheatinputsystem.h>
+#include <events/eventmanager.h>
+#include <input/inputmanager.h>
+#include <memory/srrmemory.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+
+#include <p3d/inventory.hpp>
+#include <raddebug.hpp> // Foundation
+
+#include <screen.h>
+#include <page.h>
+#include <layer.h>
+#include <group.h>
+#include <sprite.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const char* MISSION_GALLERY_IMAGES_DIR = "art\\frontend\\dynaload\\images\\scrapbook\\";
+const char* MISSION_GALLERY_INVENTORY_SECTION = "FE_MissionGallery";
+const float MISSION_IMAGE_SCALE = 0.4f;
+const float MISSION_VIEW_TRANSITION_TIME = 250.0f; // in msec
+const float MISSION_VIEW_PROJECTILE_GRAVITY = 0.005f; // in m/ms/ms
+const int MISSION_VIEW_POS_X = 180;
+const int MISSION_VIEW_POS_Y = 120;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenMissionGallery::CGuiScreenMissionGallery
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMissionGallery::CGuiScreenMissionGallery
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MISSION_GALLERY ),
+ m_pMenu( NULL ),
+ m_menuGroup( NULL ),
+ m_isMissionImagesLoaded( false ),
+ m_screenState( SCREEN_STATE_NORMAL ),
+ m_elapsedTime( 0 ),
+ m_projectileVelocity( 0.0f, 0.0f, 0.0f ),
+ m_missionInfo( NULL ),
+ m_missionNum( NULL ),
+ m_missionTitle( NULL ),
+ m_selectedMission( -1 )
+{
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "MissionGallery" );
+ rAssert( pPage != NULL );
+
+ // create a 2D sprite menu
+ //
+ m_pMenu = new CGuiMenu2D( this, NUM_MISSIONS_PER_LEVEL, 4, GUI_SPRITE_MENU, MENU_SFX_NONE );
+ rAssert( m_pMenu != NULL );
+ m_pMenu->SetGreyOutEnabled( false );
+
+ m_menuGroup = pPage->GetGroup( "Menu" );
+ rAssert( m_menuGroup != NULL );
+
+ // add sprites to menu
+ //
+ for( int i = 0; i < NUM_MISSIONS_PER_LEVEL; i++ )
+ {
+ char name[ 16 ];
+ sprintf( name, "Mission%d", i );
+
+ m_pMenu->AddMenuItem( m_menuGroup->GetSprite( name ) );
+ }
+
+ // add menu cursor
+ //
+ m_pMenu->SetCursor( m_menuGroup->GetSprite( "MissionFrame" ) );
+
+ // TC: [TEMP] due to placeholder image
+ //
+ m_menuGroup->GetSprite( "MissionFrame" )->RotateAboutCenter( 90.0f );
+
+ // get view mission layer and text drawables
+ //
+ m_missionInfo = pPage->GetLayer( "ViewMission" );
+ m_missionNum = pPage->GetText( "MissionNum" );
+ m_missionTitle = pPage->GetText( "MissionTitle" );
+
+ // add view mission layer to list of foreground layers
+ //
+ if( m_numForegroundLayers < MAX_FOREGROUND_LAYERS )
+ {
+ m_foregroundLayers[ m_numForegroundLayers ] = m_missionInfo;
+ m_numForegroundLayers++;
+ }
+
+ if( this->IsWideScreenDisplay() )
+ {
+ m_missionInfo->ResetTransformation();
+ this->ApplyWideScreenCorrectionScale( m_missionInfo );
+ }
+
+ // wrap mission title
+ //
+ rAssert( m_missionTitle != NULL );
+ m_missionTitle->SetTextMode( Scrooby::TEXT_WRAP );
+
+ // add outline to mission number and title
+ //
+ Scrooby::Text* missionNum = pPage->GetText( "MissionNum" );
+ if( missionNum != NULL )
+ {
+ missionNum->SetDisplayOutline( true );
+ }
+ m_missionTitle->SetDisplayOutline( true );
+
+ // create inventory section for mission galllery resources
+ //
+ p3d::inventory->AddSection( MISSION_GALLERY_INVENTORY_SECTION );
+}
+
+
+//===========================================================================
+// CGuiScreenMissionGallery::~CGuiScreenMissionGallery
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMissionGallery::~CGuiScreenMissionGallery()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+
+ // destroy mission gallery inventory section
+ //
+ p3d::inventory->DeleteSection( MISSION_GALLERY_INVENTORY_SECTION );
+}
+
+
+//===========================================================================
+// CGuiScreenMissionGallery::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionGallery::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( message == GUI_MSG_MENU_PROMPT_RESPONSE )
+ {
+ rAssert( param1 == PROMPT_CONFIRM_START_MISSION );
+
+ if( param2 == CGuiMenuPrompt::RESPONSE_YES )
+ {
+ this->OnStartMission();
+ }
+ else
+ {
+ rAssert( param2 == CGuiMenuPrompt::RESPONSE_NO );
+
+// m_selectedMission = -1;
+ GetInputManager()->UnregisterControllerID( 0 );
+ this->ReloadScreen();
+ }
+ }
+
+ if( m_screenState == SCREEN_STATE_GOTO_VIEW ||
+ m_screenState == SCREEN_STATE_BACK_VIEW )
+ {
+ if( message == GUI_MSG_UPDATE )
+ {
+ this->OnUpdate( param1 );
+ }
+
+ return;
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ if( m_screenState == SCREEN_STATE_VIEWING )
+ {
+ if( message == GUI_MSG_CONTROLLER_SELECT )
+ {
+ if( this->IsButtonVisible( BUTTON_ICON_ACCEPT ) )
+ {
+ GetInputManager()->RegisterControllerID( 0, param1 );
+
+ m_guiManager->DisplayPrompt( PROMPT_CONFIRM_START_MISSION, this );
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT ); // sound effect
+ }
+ }
+ else if( message == GUI_MSG_CONTROLLER_BACK )
+ {
+ m_screenState = SCREEN_STATE_BACK_VIEW;
+ m_elapsedTime = 0;
+
+ m_selectedMission = -1;
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); // sound effect
+ }
+
+ if( this->IsControllerMessage( message ) )
+ {
+ return;
+ }
+ }
+
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ this->OnUpdate( param1 );
+
+ break;
+ }
+/*
+ case GUI_MSG_MENU_SELECTION_CHANGED:
+ {
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, static_cast<int>( param1 ) != MISSION_8 );
+
+ break;
+ }
+*/
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ m_selectedMission = static_cast<int>( param1 );
+
+// m_guiManager->DisplayPrompt( PROMPT_CONFIRM_START_MISSION, this );
+ this->OnMenuSelectionMade( param1 );
+#ifdef RAD_WIN32
+ // Hide/disable all other menu items.
+ this->SetVisibilityForAllOtherMenuItems( false );
+#endif
+ break;
+ }
+/*
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ if( this->IsButtonVisible( BUTTON_ICON_ACCEPT ) )
+ {
+ GetInputManager()->RegisterControllerID( 0, param1 );
+ }
+ else
+ {
+ return;
+ }
+
+ break;
+ }
+*/
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ //
+ if( m_pMenu != NULL && m_screenState == SCREEN_STATE_NORMAL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+ else if( m_state == GUI_WINDOW_STATE_OUTRO )
+ {
+ if( message == GUI_MSG_UPDATE && m_numTransitionsPending <= 0 )
+ {
+ if( m_isMissionImagesLoaded && m_selectedMission == -1 )
+ {
+ this->UnloadMissionImages();
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenMissionGallery::OnProcessRequestsComplete
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void
+CGuiScreenMissionGallery::OnProcessRequestsComplete( void* pUserData )
+{
+ m_numTransitionsPending--;
+
+ // show mission images
+ //
+ m_menuGroup->SetAlpha( 1.0f );
+
+ p3d::pddi->DrawSync();
+
+ // push and select inventory section for searching
+ //
+ p3d::inventory->PushSection();
+ p3d::inventory->SelectSection( MISSION_GALLERY_INVENTORY_SECTION );
+ bool currentSectionOnly = p3d::inventory->GetCurrentSectionOnly();
+ p3d::inventory->SetCurrentSectionOnly( true );
+
+ // update all mission images
+ //
+ CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ rAssert( scrapBookContents != NULL );
+
+ rAssert( m_pMenu != NULL );
+ for( int i = 0; i < NUM_MISSIONS_PER_LEVEL; i++ )
+ {
+ if( (m_pMenu->GetMenuItem( i )->m_attributes & SELECTION_ENABLED) > 0 )
+ {
+ char name[ 16 ];
+ sprintf( name, "mis%02d_%02d.png", scrapBookContents->GetCurrentLevel() + 1, i + 1 );
+ tSprite* pSprite = p3d::find<tSprite>( name );
+ if( pSprite != NULL )
+ {
+ Scrooby::Sprite* missionImage = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() );
+ rAssert( missionImage != NULL );
+ missionImage->SetRawSprite( pSprite, true );
+
+ missionImage->ResetTransformation();
+ missionImage->ScaleAboutCenter( MISSION_IMAGE_SCALE );
+ }
+ else
+ {
+ rAssertMsg( false, "Mission bitmap not found!" );
+ }
+ }
+ }
+
+ // pop inventory section and restore states
+ //
+ p3d::inventory->SetCurrentSectionOnly( currentSectionOnly );
+ p3d::inventory->PopSection();
+
+ m_isMissionImagesLoaded = true;
+}
+
+//===========================================================================
+// CGuiScreenMissionGallery::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionGallery::InitIntro()
+{
+ if( !m_isMissionImagesLoaded )
+ {
+ int numImagesToLoad = this->LoadMissionImages();
+ }
+/*
+ // reset menu to first selection
+ //
+ if( numImagesToLoad > 0 )
+ {
+ rAssert( m_pMenu != NULL );
+ m_pMenu->Reset();
+ }
+*/
+ m_elapsedTime = 0;
+}
+
+
+//===========================================================================
+// CGuiScreenMissionGallery::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionGallery::InitRunning()
+{
+ if( m_screenState != SCREEN_STATE_VIEWING )
+ {
+ // hide mission info layer by default
+ //
+ rAssert( m_missionInfo != NULL );
+ m_missionInfo->SetVisible( false );
+ m_missionInfo->SetAlpha( 0.0f );
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMissionGallery::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionGallery::InitOutro()
+{
+// this->UnloadMissionImages();
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenMissionGallery::OnUpdate( unsigned int elapsedTime )
+{
+ if( m_screenState == SCREEN_STATE_NORMAL )
+ {
+ // pulse cursor alpha
+ //
+ Scrooby::Drawable* cursor = m_pMenu->GetCursor();
+ if( cursor != NULL )
+ {
+ const unsigned int PULSE_PERIOD = 1000;
+
+ float alpha = GuiSFX::Pulse( (float)m_elapsedTime,
+ (float)PULSE_PERIOD,
+ 0.75f,
+ 0.25f,
+ -rmt::PI_BY2 );
+
+ cursor->SetAlpha( alpha );
+
+ m_elapsedTime += elapsedTime;
+ m_elapsedTime %= PULSE_PERIOD;
+ }
+ }
+ else if( m_screenState == SCREEN_STATE_GOTO_VIEW )
+ {
+ // transition mission image from normal menu position
+ // to viewing position
+ //
+ m_elapsedTime += elapsedTime;
+
+ rAssert( m_pMenu != NULL );
+ int currentSelection = m_pMenu->GetSelection();
+
+ Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( currentSelection )->GetItem();
+ rAssert( pDrawable != NULL );
+
+ pDrawable->ResetTransformation();
+
+ if( m_elapsedTime < (unsigned int)MISSION_VIEW_TRANSITION_TIME )
+ {
+ float percentageDone = m_elapsedTime / MISSION_VIEW_TRANSITION_TIME;
+
+ pDrawable->ScaleAboutCenter( MISSION_IMAGE_SCALE + percentageDone * (1.0f - MISSION_IMAGE_SCALE) );
+
+ GuiSFX::Projectile( pDrawable,
+ (float)m_elapsedTime,
+ MISSION_VIEW_TRANSITION_TIME,
+ m_projectileVelocity,
+ false,
+ MISSION_VIEW_PROJECTILE_GRAVITY );
+
+ // fade out rest of the menu items
+ //
+ this->SetMenuAlpha( 1.0f - rmt::Sqrt( percentageDone ) );
+
+ // fade in mission info layer
+ //
+ rAssert( m_missionInfo != NULL );
+ m_missionInfo->SetAlpha( percentageDone * percentageDone );
+ }
+ else
+ {
+ GuiSFX::Projectile( pDrawable,
+ MISSION_VIEW_TRANSITION_TIME,
+ MISSION_VIEW_TRANSITION_TIME,
+ m_projectileVelocity,
+ false,
+ MISSION_VIEW_PROJECTILE_GRAVITY );
+
+ this->SetMenuAlpha( 0.0f );
+
+ rAssert( m_missionInfo != NULL );
+ m_missionInfo->SetAlpha( 1.0f );
+
+ m_screenState = SCREEN_STATE_VIEWING;
+ }
+ }
+ else if( m_screenState == SCREEN_STATE_BACK_VIEW )
+ {
+ // transition mission image from viewing position back to
+ // normal menu position
+ //
+ m_elapsedTime += elapsedTime;
+
+ rAssert( m_pMenu != NULL );
+ int currentSelection = m_pMenu->GetSelection();
+
+ Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( currentSelection )->GetItem();
+ rAssert( pDrawable != NULL );
+
+ pDrawable->ResetTransformation();
+
+ if( m_elapsedTime < (unsigned int)MISSION_VIEW_TRANSITION_TIME )
+ {
+ float percentageDone = m_elapsedTime / MISSION_VIEW_TRANSITION_TIME;
+
+ pDrawable->ScaleAboutCenter( MISSION_IMAGE_SCALE + (1.0f - percentageDone) * (1.0f - MISSION_IMAGE_SCALE) );
+
+ GuiSFX::Projectile( pDrawable,
+ (float)m_elapsedTime,
+ MISSION_VIEW_TRANSITION_TIME,
+ m_projectileVelocity,
+ true,
+ MISSION_VIEW_PROJECTILE_GRAVITY );
+
+ // fade back in rest of the menu items
+ //
+ this->SetMenuAlpha( percentageDone * percentageDone );
+
+ // fade in mission info layer
+ //
+ rAssert( m_missionInfo != NULL );
+ m_missionInfo->SetAlpha( 1.0f - rmt::Sqrt( percentageDone ) );
+ }
+ else
+ {
+ pDrawable->ScaleAboutCenter( MISSION_IMAGE_SCALE );
+
+ GuiSFX::Projectile( pDrawable,
+ MISSION_VIEW_TRANSITION_TIME,
+ MISSION_VIEW_TRANSITION_TIME,
+ m_projectileVelocity,
+ true,
+ MISSION_VIEW_PROJECTILE_GRAVITY );
+
+ // show menu cursor
+ //
+ rAssert( m_pMenu != NULL );
+ m_pMenu->GetCursor()->SetVisible( true );
+
+ // show level bar
+ //
+ CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ rAssert( scrapBookContents != NULL );
+ scrapBookContents->SetLevelBarVisible( true );
+
+ this->SetMenuAlpha( 1.0f );
+
+ rAssert( m_missionInfo != NULL );
+ m_missionInfo->SetAlpha( 0.0f );
+
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, true );
+
+ // hide mission info layer
+ //
+ rAssert( m_missionInfo != NULL );
+ m_missionInfo->SetVisible( false );
+
+ m_elapsedTime = 0;
+ m_screenState = SCREEN_STATE_NORMAL;
+
+#ifdef RAD_WIN32
+ // Show/enable all hidden menu items.
+ this->SetVisibilityForAllOtherMenuItems( true );
+#endif
+ }
+ }
+}
+
+void
+CGuiScreenMissionGallery::SetMenuAlpha( float alpha )
+{
+ rAssert( m_pMenu != NULL );
+ int currentSelection = m_pMenu->GetSelection();
+
+ for( int i = 0; i < NUM_MISSIONS_PER_LEVEL; i++ )
+ {
+ if( i != currentSelection )
+ {
+ Scrooby::Drawable* missionImage = m_pMenu->GetMenuItem( i )->GetItem();
+ rAssert( missionImage != NULL );
+ missionImage->SetAlpha( alpha );
+ }
+ }
+}
+
+void
+CGuiScreenMissionGallery::OnMenuSelectionMade( int selection )
+{
+ m_screenState = SCREEN_STATE_GOTO_VIEW;
+ m_elapsedTime = 0;
+
+ CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ rAssert( scrapBookContents != NULL );
+
+ // hide menu cursor
+ //
+ rAssert( m_pMenu != NULL );
+ m_pMenu->GetCursor()->SetVisible( false );
+
+ // hide level bar
+ //
+ scrapBookContents->SetLevelBarVisible( false );
+
+ // show mission info layer
+ //
+ rAssert( m_missionInfo != NULL );
+ m_missionInfo->SetVisible( true );
+
+ if( selection == MISSION_8 ) // bonus mission
+ {
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, false );
+ }
+
+ // update mission number and title
+ //
+ rAssert( m_missionNum != NULL );
+ m_missionNum->SetIndex( selection );
+
+ int missionTitleIndex = scrapBookContents->GetCurrentLevel() * NUM_MISSIONS_PER_LEVEL + selection;
+ rAssert( m_missionTitle != NULL );
+ m_missionTitle->SetIndex( missionTitleIndex );
+
+ // calculate the initial projectile velocity
+ //
+ Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( selection )->GetItem();
+ rAssert( pDrawable != NULL );
+
+ int startPosX = 0;
+ int startPosY = 0;
+ pDrawable->GetOriginPosition( startPosX, startPosY );
+
+ m_projectileVelocity.x = (MISSION_VIEW_POS_X - startPosX) / MISSION_VIEW_TRANSITION_TIME;
+ m_projectileVelocity.y = (MISSION_VIEW_POS_Y - startPosY - 0.5f * MISSION_VIEW_PROJECTILE_GRAVITY * MISSION_VIEW_TRANSITION_TIME * MISSION_VIEW_TRANSITION_TIME) / MISSION_VIEW_TRANSITION_TIME;
+}
+
+void
+CGuiScreenMissionGallery::OnStartMission()
+{
+ CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ rAssert( scrapBookContents != NULL );
+ unsigned int level = scrapBookContents->GetCurrentLevel();
+
+ int mission = m_selectedMission;
+
+ // special case for level 1 due to tutorial mission being m0
+ //
+ if( level == 0 )
+ {
+ mission++;
+ }
+
+ GetCharacterSheetManager()->SetCurrentMission( static_cast<RenderEnums::LevelEnum>( level ),
+ static_cast<RenderEnums::MissionEnum>( mission ) );
+
+ // hide mission info layer
+ //
+ rAssert( m_missionInfo != NULL );
+ m_missionInfo->SetVisible( false );
+
+ if( m_isMissionImagesLoaded )
+ {
+ this->UnloadMissionImages();
+ }
+
+ // send message to front-end manager to quit front-end and
+ // start single player story mode
+ //
+ m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 1 ); // 1 = one player
+}
+
+int
+CGuiScreenMissionGallery::LoadMissionImages()
+{
+ // load mission bitmaps for current level
+ //
+ CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ rAssert( scrapBookContents != NULL );
+
+ int numImagesToLoad = 0;
+
+ rAssert( m_pMenu != NULL );
+
+ for( int i = 0; i < NUM_MISSIONS_PER_LEVEL; i++ )
+ {
+ Scrooby::BoundedDrawable* missionImage = m_pMenu->GetMenuItem( i )->GetItem();
+ rAssert( missionImage != NULL );
+ missionImage->SetAlpha( 1.0f ); // restore alpha by default
+
+ bool isUnlocked = false;
+
+ if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_MISSIONS ) )
+ {
+ isUnlocked = true;
+ }
+ else
+ {
+ if( i == NUM_MISSIONS_PER_LEVEL - 1 )
+ {
+ isUnlocked = GetCharacterSheetManager()->QueryBonusMissionCompleted( static_cast<RenderEnums::LevelEnum>( scrapBookContents->GetCurrentLevel() ) );
+ }
+ else
+ {
+ int missionIndex = scrapBookContents->GetCurrentLevel() == 0 ? i + 1 : i;
+ MissionRecord* pMissionRecord = GetCharacterSheetManager()->QueryMissionStatus( static_cast<RenderEnums::LevelEnum>( scrapBookContents->GetCurrentLevel() ), missionIndex );
+ rAssert( pMissionRecord != NULL );
+ if( pMissionRecord->mCompleted )
+ {
+ isUnlocked = true;
+ }
+ else if( pMissionRecord->mSkippedMission )
+ {
+ isUnlocked = true;
+
+ missionImage->SetAlpha( 0.5f ); // 50% alpha for skipped missions
+ }
+ }
+ }
+
+ m_pMenu->SetMenuItemEnabled( i, isUnlocked );
+
+ if( isUnlocked )
+ {
+ char filename[ 64 ];
+ sprintf( filename, "%smis%02d_%02d.p3d",
+ MISSION_GALLERY_IMAGES_DIR,
+ scrapBookContents->GetCurrentLevel() + 1,
+ i + 1 );
+
+ GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D,
+ filename,
+ GMA_LEVEL_FE,
+ MISSION_GALLERY_INVENTORY_SECTION,
+ MISSION_GALLERY_INVENTORY_SECTION );
+
+ numImagesToLoad++;
+ }
+ }
+
+ if( numImagesToLoad > 0 )
+ {
+ GetLoadingManager()->AddCallback( this );
+
+ // hide images until they're loaded
+ //
+ m_menuGroup->SetAlpha( 0.0f );
+
+ m_numTransitionsPending++;
+ }
+
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, numImagesToLoad > 0 );
+
+ return numImagesToLoad;
+}
+
+void
+CGuiScreenMissionGallery::UnloadMissionImages()
+{
+ p3d::pddi->DrawSync();
+
+ // clear all mission images
+ //
+ rAssert( m_pMenu != NULL );
+ for( int i = 0; i < NUM_MISSIONS_PER_LEVEL; i++ )
+ {
+ Scrooby::Sprite* missionImage = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() );
+ rAssert( missionImage != NULL );
+ missionImage->SetRawSprite( NULL, true );
+ missionImage->ResetTransformation();
+
+ m_pMenu->SetMenuItemEnabled( i, false );
+ }
+
+ // unload mission bitmaps
+ //
+ p3d::inventory->RemoveSectionElements( MISSION_GALLERY_INVENTORY_SECTION );
+
+ m_isMissionImagesLoaded = false;
+}
+
+#ifdef RAD_WIN32
+void CGuiScreenMissionGallery::SetVisibilityForAllOtherMenuItems( bool bVisible )
+{
+ for( int i = 0; i < NUM_MISSIONS_PER_LEVEL; i++ )
+ {
+ if( i != m_selectedMission )
+ m_pMenu->GetMenuItem(i)->GetItem()->SetVisible( bVisible );
+ }
+}
+#endif
diff --git a/game/code/presentation/gui/frontend/guiscreenmissiongallery.h b/game/code/presentation/gui/frontend/guiscreenmissiongallery.h
new file mode 100644
index 0000000..7f1a112
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenmissiongallery.h
@@ -0,0 +1,108 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMissionGallery
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/19 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMISSIONGALLERY_H
+#define GUISCREENMISSIONGALLERY_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <loading/loadingmanager.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu2D;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMissionGallery : public CGuiScreen,
+ public LoadingManager::ProcessRequestsCallback
+{
+public:
+ CGuiScreenMissionGallery( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenMissionGallery();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+ // Implements LoadingManager::ProcessRequestsCallback
+ //
+ virtual void OnProcessRequestsComplete( void* pUserData );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ void OnUpdate( unsigned int elapsedTime );
+ void SetMenuAlpha( float alpha );
+ void OnMenuSelectionMade( int selection );
+ void OnStartMission();
+#ifdef RAD_WIN32
+ void SetVisibilityForAllOtherMenuItems( bool bDisable );
+#endif
+
+ int LoadMissionImages();
+ void UnloadMissionImages();
+
+ enum eMenuItem
+ {
+ MISSION_1,
+ MISSION_2,
+ MISSION_3,
+ MISSION_4,
+ MISSION_5,
+ MISSION_6,
+ MISSION_7,
+ MISSION_8,
+
+ NUM_MISSIONS_PER_LEVEL
+ };
+
+ CGuiMenu2D* m_pMenu;
+ Scrooby::Group* m_menuGroup;
+
+ bool m_isMissionImagesLoaded : 1;
+
+ enum eScreenState
+ {
+ SCREEN_STATE_NORMAL,
+ SCREEN_STATE_GOTO_VIEW,
+ SCREEN_STATE_VIEWING,
+ SCREEN_STATE_BACK_VIEW,
+
+ NUM_SCREEN_STATES
+ };
+
+ eScreenState m_screenState;
+ unsigned int m_elapsedTime;
+ rmt::Vector m_projectileVelocity;
+
+ Scrooby::Layer* m_missionInfo;
+ Scrooby::Text* m_missionNum;
+ Scrooby::Text* m_missionTitle;
+
+ int m_selectedMission;
+
+};
+
+#endif // GUISCREENMISSIONGALLERY_H
diff --git a/game/code/presentation/gui/frontend/guiscreenmultichoosechar.cpp b/game/code/presentation/gui/frontend/guiscreenmultichoosechar.cpp
new file mode 100644
index 0000000..3370019
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenmultichoosechar.cpp
@@ -0,0 +1,349 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMultiChooseChar
+//
+// Description: Implementation of the CGuiScreenMultiChooseChar class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreenmultichoosechar.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guisystem.h>
+
+#include <memory/srrmemory.h>
+
+#include <raddebug.hpp> // Foundation
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+/*
+static const char* MENU_ITEMS[] =
+{
+ "Character"
+};
+
+static const int NUM_MENU_ITEMS = sizeof( MENU_ITEMS ) / sizeof( MENU_ITEMS[ 0 ] );
+
+/*
+static const char* MENU_CURSOR = "Cursor";
+*/
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenMultiChooseChar::CGuiScreenMultiChooseChar
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMultiChooseChar::CGuiScreenMultiChooseChar
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+:
+ CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MULTIPLAYER_CHOOSE_CHARACTER )
+{
+ memset( m_pMenu, 0, sizeof( m_pMenu ) );
+
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage;
+ pPage = m_pScroobyScreen->GetPage( "MultiChooseCharacter" );
+ rAssert( pPage );
+
+ // Get character selection for all players
+ //
+ char itemName[ 32 ];
+ for( int i = 0; i < MAX_PLAYERS; i++ )
+ {
+ sprintf( itemName, "Character%d", i );
+ m_pCharacter[ i ] = pPage->GetSprite( itemName );
+
+ rAssert( m_pCharacter[ i ] );
+ }
+
+/*
+ Scrooby::Text* pText = NULL;
+ char menuItemName[ 32 ];
+
+ // Create and add menu items for all players
+ //
+ for( int i = 0; i < MAX_PLAYERS; i++ )
+ {
+ m_pMenu[ i] = new(GMA_LEVEL_FE) CGuiMenu( this, NUM_MENU_ITEMS );
+ rAssert( m_pMenu[ i ] != NULL );
+
+ for( int j = 0; j < NUM_MENU_ITEMS; j++ )
+ {
+ sprintf( menuItemName, "%s%d", MENU_ITEMS[ j ], i );
+ pText = pPage->GetText( menuItemName );
+ rAssert( pText );
+
+ m_pMenu[ i ]->AddMenuItem( pText );
+ }
+ }
+
+/*
+ // Set menu cursor
+ //
+ Scrooby::Sprite* pSprite = pPage->GetSprite( MENU_CURSOR );
+ rAssert( pSprite != NULL );
+ m_pMenu->SetCursor( pSprite );
+*/
+}
+
+
+//===========================================================================
+// CGuiScreenMultiChooseChar::~CGuiScreenMultiChooseChar
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMultiChooseChar::~CGuiScreenMultiChooseChar()
+{
+ for( int i = 0; i < MAX_PLAYERS; i++ )
+ {
+ if( m_pMenu[ i ] != NULL )
+ {
+ delete m_pMenu[ i ];
+ m_pMenu[ i ] = NULL;
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMultiChooseChar::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiChooseChar::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ // send message to front-end manager to quit front-end and
+ // start multiplayer head-to-head
+ //
+ m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 2 ); // 2 = two players
+
+ this->StartTransitionAnimation( 600, 640 );
+
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ this->StartTransitionAnimation( 420, 450 );
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( this->IsControllerMessage( message ) )
+ {
+ int controllerId = param1;
+/*
+ // register player 2, if not already done so and if controller ID different from player 1
+ if( GetGuiSystem()->GetControllerId( PLAYER_2 ) == -1 &&
+ GetGuiSystem()->GetControllerId( PLAYER_1 ) != controllerId )
+ {
+ GetGuiSystem()->RegisterControllerId( PLAYER_2, controllerId );
+ }
+*/
+ // send controller messages only to corresponding player menu
+ for( int i = 0; i < MAX_PLAYERS; i++ )
+ {
+ if( GetGuiSystem()->GetControllerId( static_cast<ePlayer>( i ) ) == controllerId )
+ {
+/*
+ rAssert( m_pMenu[ i ] != NULL );
+ m_pMenu[ i ]->HandleMessage( message, param1, param2 );
+*/
+ this->HandleControllerMessage( i, message );
+
+ break;
+ }
+ }
+ }
+/*
+ else
+ {
+ // send all other messages to all menus
+ for( int i = 0; i < MAX_PLAYERS; i++ )
+ {
+ rAssert( m_pMenu[ i ] != NULL );
+ m_pMenu[ i ]->HandleMessage( message, param1, param2 );
+ }
+ }
+*/
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenMultiChooseChar::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiChooseChar::InitIntro()
+{
+ // get character selection (for all players)
+ for( int i = 0; i < MAX_PLAYERS; i++ )
+ {
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMultiChooseChar::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiChooseChar::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenMultiChooseChar::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiChooseChar::InitOutro()
+{
+ // set character selection (for all players)
+ for( int i = 0; i < MAX_PLAYERS; i++ )
+ {
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMultiChooseChar::HandleControllerMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiChooseChar::HandleControllerMessage( int player, eGuiMessage message )
+{
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_LEFT:
+ {
+ // decrement character selection
+ rAssert( m_pCharacter[ player ] );
+
+ int newIndex = m_pCharacter[ player ]->GetIndex() - 1;
+ if( newIndex < 0 )
+ {
+ newIndex = m_pCharacter[ player ]->GetNumOfImages() - 1;
+ }
+
+ m_pCharacter[ player ]->SetIndex( newIndex );
+
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_RIGHT:
+ {
+ // increment character selection
+ rAssert( m_pCharacter[ player ] );
+
+ int newIndex = (m_pCharacter[ player ]->GetIndex() + 1) % m_pCharacter[ player ]->GetNumOfImages();
+
+ m_pCharacter[ player ]->SetIndex( newIndex );
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/frontend/guiscreenmultichoosechar.h b/game/code/presentation/gui/frontend/guiscreenmultichoosechar.h
new file mode 100644
index 0000000..b206e2c
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenmultichoosechar.h
@@ -0,0 +1,62 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMultiChooseChar
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMULTICHOOSECHAR_H
+#define GUISCREENMULTICHOOSECHAR_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+#include <constants/maxplayers.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+namespace Scrooby
+{
+ class Screen;
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMultiChooseChar : public CGuiScreen
+{
+public:
+ CGuiScreenMultiChooseChar( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenMultiChooseChar();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+ void HandleControllerMessage( int player, eGuiMessage message );
+
+private:
+ CGuiMenu* m_pMenu[ MAX_PLAYERS ];
+ Scrooby::Sprite* m_pCharacter[ MAX_PLAYERS ];
+
+};
+
+#endif // GUISCREENMULTICHOOSECHAR_H
diff --git a/game/code/presentation/gui/frontend/guiscreenmultisetup.cpp b/game/code/presentation/gui/frontend/guiscreenmultisetup.cpp
new file mode 100644
index 0000000..1fd3aff
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenmultisetup.cpp
@@ -0,0 +1,235 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMultiSetup
+//
+// Description: Implementation of the CGuiScreenMultiSetup class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/16 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreenmultisetup.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guisystem.h>
+
+#include <memory/srrmemory.h>
+
+#include <raddebug.hpp> // Foundation
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+static const char* MULTI_SETUP_MENU_ITEMS[] =
+{
+ "NumFlags",
+ "Base"
+};
+
+static const int NUM_MULTI_SETUP_MENU_ITEMS = sizeof( MULTI_SETUP_MENU_ITEMS ) / sizeof( MULTI_SETUP_MENU_ITEMS[ 0 ] );
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenMultiSetup::CGuiScreenMultiSetup
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMultiSetup::CGuiScreenMultiSetup
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+:
+ CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MULTIPLAYER_SETUP ),
+ m_pMenu( NULL )
+{
+MEMTRACK_PUSH_GROUP( "CGUIScreenMultiSetup" );
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage;
+ pPage = m_pScroobyScreen->GetPage( "MultiSetup" );
+ rAssert( pPage );
+
+ // Create a menu.
+ //
+ m_pMenu = new(GMA_LEVEL_FE) CGuiMenu( this, NUM_MULTI_SETUP_MENU_ITEMS );
+ rAssert( m_pMenu != NULL );
+
+ // Add menu items
+ //
+ Scrooby::Text* pText = NULL;
+ Scrooby::Text* pTextValue = NULL;
+ char itemValue[ 32 ];
+
+ for( int i = 0; i < NUM_MULTI_SETUP_MENU_ITEMS; i++ )
+ {
+ pText = pPage->GetText( MULTI_SETUP_MENU_ITEMS[ i ] );
+ rAssert( pText );
+
+ // if text value exists
+ sprintf( itemValue, "%s_Value", MULTI_SETUP_MENU_ITEMS[ i ] );
+ pTextValue = pPage->GetText( itemValue );
+
+ m_pMenu->AddMenuItem( pText, pTextValue );
+ }
+MEMTRACK_POP_GROUP();
+}
+
+
+//===========================================================================
+// CGuiScreenMultiSetup::~CGuiScreenMultiSetup
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMultiSetup::~CGuiScreenMultiSetup()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMultiSetup::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiSetup::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MULTIPLAYER_CHOOSE_CHARACTER );
+
+ this->StartTransitionAnimation( 390, 420 );
+
+ // register controller ID for player 1
+ GetGuiSystem()->RegisterControllerId( PLAYER_1, param1 );
+
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ this->StartTransitionAnimation( 290, 320 );
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenMultiSetup::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiSetup::InitIntro()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenMultiSetup::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiSetup::InitRunning()
+{
+ // unregister all player controller ID's
+ GetGuiSystem()->UnregisterControllerId( ALL_PLAYERS );
+}
+
+
+//===========================================================================
+// CGuiScreenMultiSetup::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiSetup::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/frontend/guiscreenmultisetup.h b/game/code/presentation/gui/frontend/guiscreenmultisetup.h
new file mode 100644
index 0000000..41287fb
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenmultisetup.h
@@ -0,0 +1,58 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMultiSetup
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/16 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMULTISETUP_H
+#define GUISCREENMULTISETUP_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+namespace Scrooby
+{
+ class Screen;
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMultiSetup : public CGuiScreen
+{
+public:
+ CGuiScreenMultiSetup( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenMultiSetup();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ CGuiMenu* m_pMenu;
+
+};
+
+#endif // GUISCREENMULTISETUP_H
diff --git a/game/code/presentation/gui/frontend/guiscreenoptions.cpp b/game/code/presentation/gui/frontend/guiscreenoptions.cpp
new file mode 100644
index 0000000..261b030
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenoptions.cpp
@@ -0,0 +1,609 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenOptions
+//
+// Description: Implementation of the CGuiScreenOptions class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreenoptions.h>
+#include <presentation/gui/frontend/guiscreenplaymovie.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guiscreenmessage.h>
+#include <presentation/gui/guiscreenprompt.h>
+
+#include <cheats/cheatinputsystem.h>
+#include <cheats/cheats.h>
+#include <memory/srrmemory.h>
+
+#include <raddebug.hpp> // Foundation
+#include <layer.h>
+#include <page.h>
+#include <screen.h>
+#include <group.h>
+#include <text.h>
+
+#ifdef RAD_PS2
+ #include <main/ps2platform.h>
+#endif
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const unsigned int NUM_CHEAT_DISPLAY_LINES = 16;
+const int PROGRESSIVE_MODE_TEST_TIME = 5000; // in msec
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenOptions::CGuiScreenOptions
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenOptions::CGuiScreenOptions
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_OPTIONS ),
+ m_pMenu( NULL ),
+ m_cheatsPage( NULL ),
+ m_cheatsOverlay( NULL ),
+ m_startingCheatID( 0 ),
+ m_elapsedProgressiveModeTestTime( -1 )
+{
+MEMTRACK_PUSH_GROUP( "CGUIScreenOptions" );
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Options" );
+ rAssert( pPage != NULL );
+
+ // Create a menu.
+ //
+ m_pMenu = new CGuiMenu( this, NUM_MENU_ITEMS );
+ rAssert( m_pMenu != NULL );
+
+ // Add menu items
+ //
+ Scrooby::Group* pGroup = pPage->GetGroup( "Menu" );
+ rAssert( pGroup != NULL );
+
+#ifdef RAD_WIN32
+ m_pMenu->AddMenuItem( pGroup->GetText( "Display" ) );
+#endif
+ m_pMenu->AddMenuItem( pGroup->GetText( "Controller" ) );
+ m_pMenu->AddMenuItem( pGroup->GetText( "Sound" ) );
+ m_pMenu->AddMenuItem( pGroup->GetText( "ViewMovies" ) );
+ m_pMenu->AddMenuItem( pGroup->GetText( "ViewCredits" ) );
+
+#ifndef RAD_WIN32
+ Scrooby::Text* display = pGroup->GetText( "Display" );
+ if( display != NULL )
+ {
+ display->SetVisible( false );
+ }
+#endif
+
+ m_pMenu->AddMenuItem( pGroup->GetText( "DisplayMode" ),
+ pGroup->GetText( "DisplayMode_Value" ),
+ NULL,
+ NULL,
+ pGroup->GetSprite( "DisplayMode_ArrowL" ),
+ pGroup->GetSprite( "DisplayMode_ArrowR" ),
+ SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED );
+
+#ifdef RAD_DEMO
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_VIEW_MOVIES, false );
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_VIEW_CREDITS, false );
+#endif
+
+/*
+#ifdef RAD_RELEASE
+ // hide 'view movies' in release build
+ //
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_VIEW_MOVIES, false, true );
+#else
+ // center menu items
+ //
+ pGroup->ResetTransformation();
+ pGroup->Translate( 0, 30 );
+#endif
+*/
+
+ // TC: no more display mode menu item on PS2, this is now done during bootup
+ // w/ specific button combo pressed and a display prompt
+ //
+//#ifndef RAD_PS2
+ // hide display mode menu item for non-PS2 platforms
+ //
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_DISPLAY_MODE, false, true );
+
+ #ifndef RAD_WIN32
+ // re-center menu items
+ //
+ pGroup->ResetTransformation();
+ pGroup->Translate( 0, -30 );
+ #endif
+//#endif // !RAD_PS2
+
+ // get cheats page, if included
+ //
+ m_cheatsPage = m_pScroobyScreen->GetPage( "Cheats" );
+ if( m_cheatsPage != NULL )
+ {
+ m_cheatsOverlay = m_cheatsPage->GetLayerByIndex( 0 );
+ }
+
+ // register self as cheat callback
+ //
+ GetCheatInputSystem()->RegisterCallback( this );
+MEMTRACK_POP_GROUP( "CGUIScreenOptions" );
+}
+
+
+//===========================================================================
+// CGuiScreenOptions::~CGuiScreenOptions
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenOptions::~CGuiScreenOptions()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+
+ // unregister self as cheat callback
+ //
+ GetCheatInputSystem()->UnregisterCallback( this );
+}
+
+
+//===========================================================================
+// CGuiScreenOptions::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenOptions::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_MOTHER_OF_ALL_CHEATS ) )
+ {
+ if( m_cheatsOverlay != NULL )
+ {
+ // show/hide cheats overlay, depending on whether or not
+ // cheat input is activated on any of the controllers
+ //
+ bool isCheatInputActivated = false;
+ int numUserInputHandlers = GetGuiSystem()->GetNumUserInputHandlers();
+ for( int i = 0; i < numUserInputHandlers; i++ )
+ {
+ if( GetGuiSystem()->GetUserInputHandler( i ) != NULL &&
+ GetCheatInputSystem()->IsActivated( i ) )
+ {
+ isCheatInputActivated = true;
+
+ break;
+ }
+ }
+
+ m_cheatsOverlay->SetVisible( isCheatInputActivated );
+ }
+
+ if( message == GUI_MSG_CONTROLLER_RIGHT &&
+ GetCheatInputSystem()->IsActivated( param1 ) )
+ {
+ // toggle cheat list
+ //
+ m_startingCheatID += NUM_CHEAT_DISPLAY_LINES;
+ if( m_startingCheatID >= NUM_CHEATS )
+ {
+ // wrap to the beginning
+ m_startingCheatID = 0;
+ }
+
+ this->UpdateCheatsDisplay( m_startingCheatID );
+ }
+ }
+
+ if( this->IsControllerMessage( message ) &&
+ GetCheatInputSystem()->IsActivated( param1 ) )
+ {
+ // ignore all controller inputs when cheat input system is activated
+ return;
+ }
+
+ if( message == GUI_MSG_MENU_PROMPT_RESPONSE )
+ {
+ if( param1 == PROMPT_DISPLAY_PROGRESSIVE_SCAN_PS2 )
+ {
+ if( param2 == CGuiMenuPrompt::RESPONSE_YES )
+ {
+ // begin progressive scan test
+ //
+ this->ProgressiveModeTestBegin();
+ }
+ else
+ {
+ // don't switch display mode and return to options screen
+ //
+ this->ReloadScreen();
+ }
+ }
+ else if( param1 == PROMPT_DISPLAY_PROGRESSIVE_SCAN_CONFIRM )
+ {
+ if( param2 == CGuiMenuPrompt::RESPONSE_YES )
+ {
+#ifdef RAD_PS2
+ PS2Platform::GetInstance()->SetProgressiveMode( true );
+#endif
+ rTunePrintf( "Current display mode confirmed: PROGRESSIVE.\n" );
+ }
+ else
+ {
+ rTunePrintf( "Current display mode confirmed: INTERLACED.\n" );
+ }
+
+ // return to options screen
+ //
+ this->ReloadScreen();
+ }
+ else
+ rTuneAssert(!"not handled");
+ }
+ else if( message == GUI_MSG_MESSAGE_UPDATE || message == GUI_MSG_PROMPT_UPDATE ) // update from message/prompt screen
+ {
+ if( m_elapsedProgressiveModeTestTime != -1 )
+ {
+ m_elapsedProgressiveModeTestTime += static_cast<int>( param1 );
+
+ if( m_elapsedProgressiveModeTestTime > PROGRESSIVE_MODE_TEST_TIME )
+ {
+ this->OnProgressiveModeTestEnd();
+ }
+ }
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_MENU_SELECTION_CHANGED:
+ {
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, param1 != MENU_ITEM_DISPLAY_MODE );
+
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_VALUE_CHANGED:
+ {
+ if( param1 == MENU_ITEM_DISPLAY_MODE )
+ {
+ if( param2 == 1 ) // progressive mode
+ {
+ // display confirmation prompt
+ //
+ m_guiManager->DisplayPrompt( PROMPT_DISPLAY_PROGRESSIVE_SCAN_PS2, this );
+ }
+ else // interlaced mode
+ {
+#ifdef RAD_PS2
+ PS2Platform::GetInstance()->SetProgressiveMode( false );
+#endif
+ }
+ }
+
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ switch( param1 )
+ {
+ case MENU_ITEM_CONTROLLER:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_CONTROLLER );
+
+ this->StartTransitionAnimation( 530, 560 );
+
+ break;
+ }
+ case MENU_ITEM_SOUND:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SOUND );
+
+ this->StartTransitionAnimation( 660, 690 );
+
+ break;
+ }
+ case MENU_ITEM_VIEW_MOVIES:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_VIEW_MOVIES );
+
+ this->StartTransitionAnimation( 914, 944 );
+
+ break;
+ }
+ case MENU_ITEM_VIEW_CREDITS:
+ {
+/*
+ rAssert( m_guiManager );
+ CGuiScreenPlayMovie* playMovieScreen = static_cast<CGuiScreenPlayMovie*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_VIEW_CREDITS ) );
+ rAssert( playMovieScreen );
+ playMovieScreen->SetMovieToPlay( MovieNames::CREDITS );
+*/
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_VIEW_CREDITS );
+
+ this->StartTransitionAnimation( 600, 630 );
+
+ break;
+ }
+#ifdef RAD_WIN32
+ case MENU_ITEM_DISPLAY:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_DISPLAY );
+
+ break;
+ }
+#endif
+ default:
+ {
+ break;
+ }
+ }
+
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ this->StartTransitionAnimation( 110, 140 );
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenOptions::OnCheatEntered
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void
+CGuiScreenOptions::OnCheatEntered( eCheatID cheatID, bool isEnabled )
+{
+ this->UpdateCheatsDisplay( m_startingCheatID );
+
+ if( cheatID == CHEAT_ID_MOTHER_OF_ALL_CHEATS && !isEnabled )
+ {
+ if( m_cheatsOverlay != NULL )
+ {
+ m_cheatsOverlay->SetVisible( false );
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenOptions::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenOptions::InitIntro()
+{
+#ifndef RAD_E3
+ GetCheatInputSystem()->SetEnabled( true );
+#endif
+
+ rAssert( m_pMenu != NULL );
+ if( m_pMenu->GetSelection() == MENU_ITEM_DISPLAY_MODE )
+ {
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, false );
+ }
+
+#ifdef RAD_PS2
+ // update current display mode
+ //
+ m_pMenu->SetSelectionValue( MENU_ITEM_DISPLAY_MODE,
+ PS2Platform::GetInstance()->GetProgressiveMode() ? 1 : 0 );
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenOptions::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenOptions::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenOptions::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenOptions::InitOutro()
+{
+#ifndef RAD_E3
+ GetCheatInputSystem()->SetEnabled( false );
+#endif
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenOptions::UpdateCheatsDisplay( int cheatID )
+{
+ if( m_cheatsPage != NULL )
+ {
+ // update cheats info
+ //
+ CheatsDB* cheatsDB = GetCheatInputSystem()->GetCheatsDB();
+ rAssert( cheatsDB != NULL );
+
+ for( unsigned int i = 0; i < NUM_CHEAT_DISPLAY_LINES; i++ )
+ {
+ char name[ 32 ];
+ sprintf( name, "Cheat%d", i );
+ Scrooby::Text* pText = m_cheatsPage->GetText( name );
+ rAssert( pText != NULL );
+
+ HeapMgr()->PushHeap( GMA_LEVEL_FE );
+
+ if( cheatID < NUM_CHEATS )
+ {
+ char cheatInfo[ 64 ];
+
+ const Cheat* cheat = cheatsDB->GetCheat( static_cast<eCheatID>( cheatID ) );
+ if( cheat != NULL )
+ {
+ CheatsDB::PrintCheatInfo( cheat, cheatInfo );
+
+ if( GetCheatInputSystem()->IsCheatEnabled( static_cast<eCheatID>( cheatID ) ) )
+ {
+ strcat( cheatInfo, " (!)" ); // exclamation mark denotes cheat enabled
+ }
+ }
+ else
+ {
+ // display un-registered cheat
+ //
+ sprintf( cheatInfo,
+ "Cheat ID [%02d]: *** Not Registered! ***", cheatID );
+/*
+ // ignore/skip un-registered cheat and don't display anything
+ //
+ pText->SetString( 0, " " );
+ i--;
+*/
+ }
+
+ pText->SetString( 0, cheatInfo );
+ }
+ else
+ {
+ pText->SetString( 0, " " );
+ }
+
+ HeapMgr()->PopHeap( GMA_LEVEL_FE );
+
+ cheatID++;
+ }
+ }
+}
+
+void
+CGuiScreenOptions::ProgressiveModeTestBegin()
+{
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_PROGRESSIVE_SCAN_TEST, this );
+ m_elapsedProgressiveModeTestTime = 0;
+
+ rTunePrintf( "Testing progressive scan display ... ...\n" );
+
+#ifdef RAD_PS2
+ PS2Platform::GetInstance()->SetProgressiveMode( true );
+#endif
+}
+
+void
+CGuiScreenOptions::OnProgressiveModeTestEnd()
+{
+ m_guiManager->DisplayPrompt( PROMPT_DISPLAY_PROGRESSIVE_SCAN_CONFIRM, this );
+ m_elapsedProgressiveModeTestTime = -1;
+
+ rTunePrintf( "Progressive scan test completed.\n" );
+
+#ifdef RAD_PS2
+ PS2Platform::GetInstance()->SetProgressiveMode( false );
+#endif
+}
+
diff --git a/game/code/presentation/gui/frontend/guiscreenoptions.h b/game/code/presentation/gui/frontend/guiscreenoptions.h
new file mode 100644
index 0000000..a625163
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenoptions.h
@@ -0,0 +1,82 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenOptions
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENOPTIONS_H
+#define GUISCREENOPTIONS_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <cheats/cheatinputsystem.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenOptions : public CGuiScreen,
+ public ICheatEnteredCallback
+{
+public:
+ CGuiScreenOptions( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenOptions();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual void OnCheatEntered( eCheatID cheatID, bool isEnabled );
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ void UpdateCheatsDisplay( int cheatID );
+
+ void ProgressiveModeTestBegin();
+ void OnProgressiveModeTestEnd();
+
+ enum eMenuItem
+ {
+#ifdef RAD_WIN32
+ MENU_ITEM_DISPLAY,
+#endif
+ MENU_ITEM_CONTROLLER,
+ MENU_ITEM_SOUND,
+ MENU_ITEM_VIEW_MOVIES,
+ MENU_ITEM_VIEW_CREDITS,
+ MENU_ITEM_DISPLAY_MODE,
+
+ NUM_MENU_ITEMS
+ };
+
+ CGuiMenu* m_pMenu;
+
+ Scrooby::Page* m_cheatsPage;
+ Scrooby::Layer* m_cheatsOverlay;
+ int m_startingCheatID;
+
+ int m_elapsedProgressiveModeTestTime;
+
+};
+
+#endif // GUISCREENOPTIONS_H
diff --git a/game/code/presentation/gui/frontend/guiscreenplaymovie.cpp b/game/code/presentation/gui/frontend/guiscreenplaymovie.cpp
new file mode 100644
index 0000000..ca74357
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenplaymovie.cpp
@@ -0,0 +1,460 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPlayMovie
+//
+// Description: Implementation of the CGuiScreenPlayMovie class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreenplaymovie.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/gui/utility/specialfx.h>
+
+#include <presentation/presentation.h>
+#include <presentation/fmvplayer/fmvplayer.h>
+#include <presentation/fmvplayer/fmvuserinputhandler.h>
+
+#include <memory/srrmemory.h>
+#include <render/rendermanager/rendermanager.h>
+#include <render/rendermanager/renderlayer.h>
+
+#include <screen.h>
+#include <page.h>
+#include <text.h>
+
+#include <p3d/view.hpp>
+
+#include <raddebug.hpp> // Foundation
+#include <radmovie2.hpp>
+
+#include <sound/soundmanager.h>
+
+#include <input/inputmanager.h>
+
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenPlayMovie::CGuiScreenPlayMovie
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPlayMovie::CGuiScreenPlayMovie
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent,
+ eGuiWindowID windowID
+)
+: CGuiScreen( pScreen, pParent, windowID ),
+ m_demoText( NULL ),
+ m_elapsedTime( 0 ),
+ m_IsSkippable(true)
+// m_tvFrame( NULL )
+{
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Demo" );
+ if( pPage != NULL )
+ {
+ m_demoText = pPage->GetText( "Demo" );
+ rAssert( m_demoText != NULL );
+ }
+
+/*
+ // background TV frame layer
+ //
+ m_tvFrame = pPage->GetLayer( "TVFrame" );
+*/
+
+ if( windowID == GUI_SCREEN_ID_PLAY_MOVIE )
+ {
+ // invert fading; ie. fade out during transition in, and vice versa
+ //
+ m_inverseFading = true;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenPlayMovie::~CGuiScreenPlayMovie
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPlayMovie::~CGuiScreenPlayMovie()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenPlayMovie::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPlayMovie::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ GetPresentationManager()->Update( param1 );
+
+ if( m_demoText != NULL )
+ {
+ m_elapsedTime += param1;
+
+ const unsigned int BLINK_PERIOD = 250;
+ bool blinked = GuiSFX::Blink( m_demoText,
+ (float)m_elapsedTime,
+ (float)BLINK_PERIOD );
+ if( blinked )
+ {
+ m_elapsedTime %= BLINK_PERIOD;
+ }
+ }
+/*
+ if( m_state == GUI_WINDOW_STATE_OUTRO )
+ {
+ if( m_numTransitionsPending <= 0 )
+ {
+ // restore the background TV frame
+ //
+ if( m_tvFrame != NULL )
+ {
+ m_tvFrame->SetVisible( true );
+ }
+ }
+ }
+*/
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ // don't allow user to back out of screen, must be done
+ // by skipping movie
+ //
+ return;
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+void
+CGuiScreenPlayMovie::SetMovieToPlay( const char* movieName, bool IsSkippable, bool KillMusic, bool IsLocalized )
+{
+ rAssert( movieName != NULL );
+
+ FMVEvent* pEvent = NULL;
+ GetPresentationManager()->QueueFMV( &pEvent, this );
+
+ strcpy( pEvent->fileName, movieName );
+ pEvent->SetRenderLayer( RenderEnums::PresentationSlot );
+ pEvent->SetAutoPlay( false );
+ pEvent->SetClearWhenDone( true );
+ pEvent->SetSkippable(IsSkippable);
+
+#ifdef PAL
+ if( IsLocalized )
+ {
+ switch( CGuiTextBible::GetCurrentLanguage() )
+ {
+ case Scrooby::XL_FRENCH:
+ {
+ pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_FRENCH );
+
+ break;
+ }
+ case Scrooby::XL_GERMAN:
+ {
+ pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_GERMAN );
+
+ break;
+ }
+ case Scrooby::XL_SPANISH:
+ {
+ pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_SPANISH );
+
+ break;
+ }
+ default:
+ {
+ rAssert( CGuiTextBible::GetCurrentLanguage() == Scrooby::XL_ENGLISH );
+ pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_ENGLISH );
+
+ break;
+ }
+ }
+ }
+ else
+#endif // PAL
+ {
+ pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_ENGLISH );
+ }
+
+ if( KillMusic )
+ {
+ pEvent->KillMusic();
+ }
+}
+
+
+//=============================================================================
+// CGuiScreenPlayMovie::OnPresentationEventBegin
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( PresentationEvent* pEvent )
+//
+// Return: void
+//
+//=============================================================================
+void CGuiScreenPlayMovie::OnPresentationEventBegin( PresentationEvent* pEvent )
+{
+ GetSoundManager()->StopForMovie();
+}
+
+
+//=============================================================================
+// CGuiScreenPlayMovie::OnPresentationEventLoadComplete
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( PresentationEvent* pEvent )
+//
+// Return: void
+//
+//=============================================================================
+void CGuiScreenPlayMovie::OnPresentationEventLoadComplete( PresentationEvent* pEvent )
+{
+}
+
+
+//=============================================================================
+// CGuiScreenPlayMovie::OnPresentationEventEnd
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( PresentationEvent* pEvent )
+//
+// Return: void
+//
+//=============================================================================
+void CGuiScreenPlayMovie::OnPresentationEventEnd( PresentationEvent* pEvent )
+{
+ if( GetPresentationManager()->IsQueueEmpty() )
+ {
+ GetSoundManager()->ResumeAfterMovie();
+
+ if( m_ID == GUI_SCREEN_ID_PLAY_MOVIE_INTRO )
+ {
+ // finished playing intro movie, now go to main menu
+ //
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ GUI_SCREEN_ID_INTRO_TRANSITION,
+ CLEAR_WINDOW_HISTORY );
+ }
+ else if( m_ID == GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME )
+ {
+ // finished playing new game movie, now quit the FE
+ //
+ m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 1 ); // 1 = one player
+ }
+ else
+ {
+ rAssert( m_guiManager );
+ eGuiWindowID previousScreen = m_guiManager->GetPreviousScreen();
+ if( previousScreen == GUI_SCREEN_ID_VIEW_MOVIES )
+ {
+ this->StartTransitionAnimation( 1005, 1035 );
+ }
+ else if( previousScreen == GUI_SCREEN_ID_OPTIONS )
+ {
+ this->StartTransitionAnimation( 630, 660 );
+ }
+
+ m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN );
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenPlayMovie::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPlayMovie::InitIntro()
+{
+ rAssertMsg( !GetPresentationManager()->IsQueueEmpty(),
+ "ERROR: *** No movies were queued for playing!" );
+
+ if( m_demoText != NULL )
+ {
+ m_demoText->SetVisible( false );
+ m_elapsedTime = 0;
+ }
+
+#ifdef RAD_WIN32
+ GetInputManager()->GetFEMouse()->SetInGameMode( true );
+#endif
+
+/*
+ // hide background TV frame so we can fade in/out the foreground one
+ //
+ if( m_tvFrame != NULL )
+ {
+ m_tvFrame->SetVisible( false );
+ }
+*/
+}
+
+
+//===========================================================================
+// CGuiScreenPlayMovie::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPlayMovie::InitRunning()
+{
+ if( m_ID == GUI_SCREEN_ID_PLAY_MOVIE_DEMO )
+ {
+ // disable screen clearing for GUI render layer
+ //
+ GetRenderManager()->mpLayer( RenderEnums::GUI )->pView( 0 )->SetClearMask( PDDI_BUFFER_DEPTH | PDDI_BUFFER_STENCIL );
+ }
+ else
+ {
+ GetRenderManager()->mpLayer( RenderEnums::GUI )->Chill();
+ }
+
+ GetPresentationManager()->GetFMVPlayer()->Play();
+
+#ifdef FINAL
+ if( m_ID == GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME )
+ {
+ // disable skipping of new game movie
+ //
+ FMVUserInputHandler* userInputHandler = GetPresentationManager()->GetFMVPlayer()->GetUserInputHandler();
+ rAssert( userInputHandler != NULL );
+ userInputHandler->SetEnabled( false );
+ }
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenPlayMovie::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPlayMovie::InitOutro()
+{
+ if( m_ID == GUI_SCREEN_ID_PLAY_MOVIE_DEMO )
+ {
+ // enable screen clearing
+ //
+ GetRenderManager()->mpLayer(RenderEnums::GUI)->pView( 0 )->SetClearMask( PDDI_BUFFER_ALL );
+ }
+ else
+ {
+ GetRenderManager()->mpLayer( RenderEnums::GUI )->Warm();
+ }
+
+#ifdef RAD_WIN32
+ GetInputManager()->GetFEMouse()->SetInGameMode( false );
+#endif
+
+#ifdef FINAL
+ if( m_ID == GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME )
+ {
+ // re-enable FMV user inputs
+ //
+ FMVUserInputHandler* userInputHandler = GetPresentationManager()->GetFMVPlayer()->GetUserInputHandler();
+ rAssert( userInputHandler != NULL );
+ userInputHandler->SetEnabled( true );
+ }
+#endif
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/frontend/guiscreenplaymovie.h b/game/code/presentation/gui/frontend/guiscreenplaymovie.h
new file mode 100644
index 0000000..40c8c3a
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenplaymovie.h
@@ -0,0 +1,70 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPlayMovie
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENPLAYMOVIE_H
+#define GUISCREENPLAYMOVIE_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <presentation/presevents/presentationevent.h>
+#include <constants/movienames.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenPlayMovie : public CGuiScreen,
+ public PresentationEvent::PresentationEventCallBack
+{
+public:
+ CGuiScreenPlayMovie( Scrooby::Screen* pScreen, CGuiEntity* pParent,
+ eGuiWindowID windowID = GUI_SCREEN_ID_PLAY_MOVIE );
+ virtual ~CGuiScreenPlayMovie();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ void SetMovieToPlay( const char* movieName, bool IsSkippable = true,
+ bool KillMusic = false,
+ bool IsLocalized = true );
+
+ // Implements PresentationEvent::PresentationEventCallBack
+ //
+ virtual void OnPresentationEventBegin( PresentationEvent* pEvent );
+ virtual void OnPresentationEventLoadComplete( PresentationEvent* pEvent );
+ virtual void OnPresentationEventEnd( PresentationEvent* pEvent );
+
+ void SetSkippable(bool IsSkippable) {m_IsSkippable = IsSkippable;}
+ bool GetSkippable(void) const {return m_IsSkippable;}
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ Scrooby::Text* m_demoText;
+ unsigned int m_elapsedTime;
+ bool m_IsSkippable : 1;
+};
+
+#endif // GUISCREENPLAYMOVIE_H
diff --git a/game/code/presentation/gui/frontend/guiscreenscrapbook.cpp b/game/code/presentation/gui/frontend/guiscreenscrapbook.cpp
new file mode 100644
index 0000000..c41b52d
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenscrapbook.cpp
@@ -0,0 +1,266 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenScrapBook
+//
+// Description: Implementation of the CGuiScreenScrapBook class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/10 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreenscrapbook.h>
+#include <presentation/gui/guimenu.h>
+
+#include <memory/srrmemory.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+
+// Scrooby
+//
+#include <screen.h>
+#include <page.h>
+#include <group.h>
+#include <text.h>
+
+// ATG
+//
+#include <raddebug.hpp>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenScrapBook::CGuiScreenScrapBook
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenScrapBook::CGuiScreenScrapBook
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SCRAP_BOOK ),
+ m_pMenu( NULL ),
+ m_krustySticker( NULL )
+{
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "ScrapBook" );
+ rAssert( pPage != NULL );
+
+ // get krusty sticker overlay
+ //
+ m_krustySticker = pPage->GetGroup( "KrustySticker" );
+ rAssert( m_krustySticker != NULL );
+ m_krustySticker->SetVisible( false ); // hide by default
+
+#ifdef PAL
+ m_krustySticker->ScaleAboutPoint( 0.9f, 0, 0 );
+#endif
+
+ // create menu
+ //
+ m_pMenu = new CGuiMenu( this, NUM_MENU_ITEMS );
+ rAssert( m_pMenu != NULL );
+
+ // add menu items
+ //
+ Scrooby::Group* pGroup = pPage->GetGroup( "Menu" );
+ rAssert( pGroup != NULL );
+ m_pMenu->AddMenuItem( pGroup->GetText( "OpenBook" ) );
+ Scrooby::Text* gameStats = pGroup->GetText( "GameStats" );
+ m_pMenu->AddMenuItem( gameStats );
+
+#ifdef PAL
+ rAssert( gameStats != NULL );
+ gameStats->SetTextMode( Scrooby::TEXT_WRAP );
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenScrapBook::~CGuiScreenScrapBook
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenScrapBook::~CGuiScreenScrapBook()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenScrapBook::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenScrapBook::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ this->OnMenuSelectionMade( static_cast<eMenuItem>( param1 ) );
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ this->StartTransitionAnimation( 350, 380 );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ //
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenScrapBook::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenScrapBook::InitIntro()
+{
+ // update percent game complete
+ //
+ float percentComplete = GetCharacterSheetManager()->QueryPercentGameCompleted();
+
+ // show krusty sticker only if game percent complete is 100%
+ //
+ rAssert( m_krustySticker != NULL );
+ m_krustySticker->SetVisible( percentComplete > 99.999f );
+}
+
+
+//===========================================================================
+// CGuiScreenScrapBook::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenScrapBook::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenScrapBook::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenScrapBook::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenScrapBook::OnMenuSelectionMade( eMenuItem selection )
+{
+ switch( selection )
+ {
+ case MENU_OPEN_BOOK:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS );
+
+ break;
+ }
+ case MENU_GAME_STATS:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SCRAP_BOOK_STATS );
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Invalid menu selection!" );
+
+ break;
+ }
+ }
+
+ this->StartTransitionAnimation( 810, 830 );
+}
+
diff --git a/game/code/presentation/gui/frontend/guiscreenscrapbook.h b/game/code/presentation/gui/frontend/guiscreenscrapbook.h
new file mode 100644
index 0000000..d18d988
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenscrapbook.h
@@ -0,0 +1,64 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenScrapBook
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/10 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENSCRAPBOOK_H
+#define GUISCREENSCRAPBOOK_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenScrapBook : public CGuiScreen
+{
+public:
+ CGuiScreenScrapBook( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenScrapBook();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ enum eMenuItem
+ {
+ MENU_OPEN_BOOK,
+ MENU_GAME_STATS,
+
+ NUM_MENU_ITEMS
+ };
+
+ void OnMenuSelectionMade( eMenuItem selection );
+
+ CGuiMenu* m_pMenu;
+ Scrooby::Group* m_krustySticker;
+
+};
+
+#endif // GUISCREENSCRAPBOOK_H
diff --git a/game/code/presentation/gui/frontend/guiscreenscrapbookcontents.cpp b/game/code/presentation/gui/frontend/guiscreenscrapbookcontents.cpp
new file mode 100644
index 0000000..b1daa4d
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenscrapbookcontents.cpp
@@ -0,0 +1,674 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenScrapBookContents
+//
+// Description: Implementation of the CGuiScreenScrapBookContents class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/10 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreenscrapbookcontents.h>
+#include <presentation/gui/frontend/guiscreenplaymovie.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/guiuserinputhandler.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guitextbible.h>
+
+#include <cards/cardgallery.h>
+#include <events/eventmanager.h>
+#include <input/inputmanager.h>
+#include <memory/srrmemory.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <mission/rewards/rewardsmanager.h>
+#include <render/enums/renderenums.h>
+
+// Scrooby
+//
+#include <screen.h>
+#include <page.h>
+#include <layer.h>
+#include <group.h>
+#include <text.h>
+#include <sprite.h>
+
+// ATG
+//
+#include <raddebug.hpp>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const char* MOVIES_INGAME[] =
+{
+ MovieNames::MOVIE2, // level 1
+ MovieNames::MOVIE3, // level 2
+ MovieNames::MOVIE8, // level 3 - I & S movie!
+ MovieNames::MOVIE4, // level 4
+ MovieNames::MOVIE5, // level 5
+ MovieNames::MOVIE6, // level 6
+ MovieNames::MOVIE7, // level 7
+
+ "" // dummy terminator
+};
+
+const float LEVEL_BAR_CORRECTION_SCALE = 2.0f;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenScrapBookContents::CGuiScreenScrapBookContents
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenScrapBookContents::CGuiScreenScrapBookContents
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ),
+ m_pMenu( NULL ),
+ m_levelBarGroup( NULL ),
+ m_levelSelection( NULL ),
+ m_LTrigger( NULL ),
+ m_RTrigger( NULL ),
+ m_LTriggerBgd( NULL ),
+ m_RTriggerBgd( NULL ),
+ m_currentLevel( 0 ),
+ m_sparkles( NULL )
+{
+ memset( m_menuImages, 0, sizeof( m_menuImages ) );
+
+ // Retrieve the Scrooby drawing elements (from LevelBar.pag)
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "LevelBar" );
+ rAssert( pPage != NULL );
+
+ m_levelBarGroup = pPage->GetGroup( "LevelBar" );
+ rAssert( m_levelBarGroup != NULL );
+
+ // apply image correction scale
+ //
+ Scrooby::Sprite* levelBarBgd = m_levelBarGroup->GetSprite( "LevelBar" );
+ if( levelBarBgd != NULL )
+ {
+ levelBarBgd->ResetTransformation();
+ levelBarBgd->ScaleAboutCenter( LEVEL_BAR_CORRECTION_SCALE );
+ }
+
+ // get level bar elements
+ //
+ m_levelSelection = m_levelBarGroup->GetText( "Level" );
+ rAssert( m_levelSelection != NULL );
+ m_levelSelection->ResetTransformation();
+ m_levelSelection->ScaleAboutCenter( 0.75f );
+
+ m_LTrigger = m_levelBarGroup->GetGroup( "LTrigger" );
+ rAssert( m_LTrigger != NULL );
+
+ m_RTrigger = m_levelBarGroup->GetGroup( "RTrigger" );
+ rAssert( m_RTrigger != NULL );
+
+#ifdef RAD_PS2
+ // PS2 only, scale up L1 and R1 button images
+ //
+ m_LTrigger->ResetTransformation();
+ m_LTrigger->ScaleAboutCenter( 1.25f, 1.15f, 1.0f );
+ m_RTrigger->ResetTransformation();
+ m_RTrigger->ScaleAboutCenter( 1.25f, 1.15f, 1.0f );
+#endif
+
+#ifdef RAD_XBOX
+ switch( CGuiTextBible::GetCurrentLanguage() )
+ {
+ case Scrooby::XL_FRENCH:
+ {
+ m_LTrigger->GetSprite( "LTrigger" )->SetIndex( 2 );
+ m_RTrigger->GetSprite( "RTrigger" )->SetIndex( 1 );
+
+ break;
+ }
+ case Scrooby::XL_SPANISH:
+ {
+ m_LTrigger->GetSprite( "LTrigger" )->SetIndex( 1 );
+ m_RTrigger->GetSprite( "RTrigger" )->SetIndex( 1 );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+#endif // RAD_XBOX
+
+ m_LTriggerBgd = m_LTrigger->GetSprite( "LTriggerBgd" );
+ m_RTriggerBgd = m_RTrigger->GetSprite( "RTriggerBgd" );
+
+#ifdef RAD_WIN32
+ m_LTriggerBgd->ScaleAboutCenter( 0.5 );
+ m_RTriggerBgd->ScaleAboutCenter( 0.5 );
+#endif
+
+ // Retrieve the Scrooby drawing elements (from ScrapBookContents.pag)
+ //
+ pPage = m_pScroobyScreen->GetPage( "ScrapBookContents" );
+ rAssert( pPage != NULL );
+
+ // create a 2D menu
+ //
+ m_pMenu = new CGuiMenu2D( this, NUM_MENU_ITEMS, 3 );
+ rAssert( m_pMenu != NULL );
+
+ // add menu items
+ //
+ Scrooby::Group* pGroup = pPage->GetGroup( "Menu" );
+ rAssert( pGroup != NULL );
+ m_pMenu->AddMenuItem( pGroup->GetText( "StoryMissions" ),
+ pGroup->GetText( "StoryMissions_Unlocked" ) );
+ m_pMenu->AddMenuItem( pGroup->GetText( "CharacterClothing" ),
+ pGroup->GetText( "CharacterClothing_Unlocked" ) );
+ m_pMenu->AddMenuItem( pGroup->GetText( "Vehicles" ),
+ pGroup->GetText( "Vehicles_Unlocked" ) );
+ m_pMenu->AddMenuItem( pGroup->GetText( "Dummy" ),
+ NULL, NULL, NULL, NULL, NULL, ALL_ATTRIBUTES_OFF );
+ m_pMenu->AddMenuItem( pGroup->GetText( "CollectorCards" ),
+ pGroup->GetText( "CollectorCards_Unlocked" ) );
+ m_pMenu->AddMenuItem( pGroup->GetText( "Dummy" ),
+ NULL, NULL, NULL, NULL, NULL, ALL_ATTRIBUTES_OFF );
+// m_pMenu->AddMenuItem( pGroup->GetText( "Movies" ),
+// pGroup->GetText( "Movies_Unlocked" ) );
+
+ // get menu images
+ //
+ m_menuImages[ MENU_STORY_MISSIONS ] = pGroup->GetSprite( "StoryMissions" );
+ m_menuImages[ MENU_CHARACTER_CLOTHING ] = pGroup->GetSprite( "CharacterClothing" );
+ m_menuImages[ MENU_VEHICLES ] = pGroup->GetSprite( "Vehicles" );
+ m_menuImages[ MENU_COLLECTOR_CARDS ] = pGroup->GetSprite( "CollectorCards" );
+// m_menuImages[ MENU_MOVIES ] = pGroup->GetSprite( "Movies" );
+
+ // shrink down bottom row images
+ //
+ const float MENU_IMAGE_SCALE = 0.75f;
+ rAssert( m_menuImages[ MENU_COLLECTOR_CARDS ] != NULL );
+ m_menuImages[ MENU_COLLECTOR_CARDS ]->ResetTransformation();
+ m_menuImages[ MENU_COLLECTOR_CARDS ]->ScaleAboutCenter( MENU_IMAGE_SCALE );
+
+ // get sparkles overlay
+ //
+ pPage = m_pScroobyScreen->GetPage( "3dFE" );
+ rAssert( pPage != NULL );
+ m_sparkles = pPage->GetLayer( "ScrapBookSparkles" );
+}
+
+//===========================================================================
+// CGuiScreenScrapBookContents::~CGuiScreenScrapBookContents
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenScrapBookContents::~CGuiScreenScrapBookContents()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+#ifdef RAD_WIN32
+//===========================================================================
+// CGuiScreenScrapBookContents::CheckCursorAgainstHotspots
+//===========================================================================
+// Description: Checks cursor position against its list of hotspots.
+//
+// Constraints: None.
+//
+// Parameters: float x - The x position of cursor in P3D coordinates.
+// float y - The y position of cursor in P3D coordinates.
+//
+// Return: N/A.
+//
+//===========================================================================
+eFEHotspotType CGuiScreenScrapBookContents::CheckCursorAgainstHotspots( float x, float y )
+{
+ eFEHotspotType hotSpotType = CGuiScreen::CheckCursorAgainstHotspots( x, y );
+ if( hotSpotType == HOTSPOT_NONE )
+ {
+ if( m_LTriggerBgd )
+ {
+ if( m_LTriggerBgd->IsPointInBoundingRect( x, y ) )
+ {
+ hotSpotType = HOTSPOT_LTRIGGER;
+ }
+ }
+ if( m_RTriggerBgd )
+ {
+ if( m_RTriggerBgd->IsPointInBoundingRect( x, y ) )
+ {
+ hotSpotType = HOTSPOT_RTRIGGER;
+ }
+ }
+
+ }
+ return hotSpotType;
+}
+#endif
+
+//===========================================================================
+// CGuiScreenScrapBookContents::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenScrapBookContents::HandleMessage( eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2 )
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ // toggle L/R trigger icon backgrounds
+ //
+ if( m_LTriggerBgd != NULL && m_RTriggerBgd != NULL )
+ {
+ m_LTriggerBgd->SetIndex( 0 );
+ m_RTriggerBgd->SetIndex( 0 );
+
+ if( !m_pMenu->HasSelectionBeenMade() )
+ {
+ int numUserInputHandlers = GetGuiSystem()->GetNumUserInputHandlers();
+ for( int i = 0; i < numUserInputHandlers; i++ )
+ {
+ CGuiUserInputHandler* userInputHandler = GetGuiSystem()->GetUserInputHandler( i );
+ if( userInputHandler != NULL )
+ {
+ if( userInputHandler->IsButtonDown( GuiInput::L1 )
+#ifdef RAD_WIN32
+ || GetInputManager()->GetFEMouse()->LeftButtonDownOn() == HOTSPOT_LTRIGGER
+#endif
+ )
+ {
+ rAssert( m_LTriggerBgd->GetNumOfImages() > 1 );
+ m_LTriggerBgd->SetIndex( 1 );
+ }
+
+ if( userInputHandler->IsButtonDown( GuiInput::R1 )
+#ifdef RAD_WIN32
+ || GetInputManager()->GetFEMouse()->LeftButtonDownOn() == HOTSPOT_RTRIGGER
+#endif
+ )
+ {
+ rAssert( m_RTriggerBgd->GetNumOfImages() > 1 );
+ m_RTriggerBgd->SetIndex( 1 );
+ }
+ }
+ }
+ }
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_L1:
+ {
+ if( !m_pMenu->HasSelectionBeenMade() )
+ {
+ // decrement level selection
+ //
+ this->OnLevelSelectionChange( -1 );
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_R1:
+ {
+ if( !m_pMenu->HasSelectionBeenMade() )
+ {
+ // increment level selection
+ //
+ this->OnLevelSelectionChange( +1 );
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ }
+
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ this->OnMenuSelectionMade( static_cast<eMenuItem>( param1 ) );
+
+ break;
+ }
+/*
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ if( m_currentLevel == RenderEnums::L3 &&
+ m_pMenu->GetSelection() == MENU_MOVIES )
+ {
+ GetInputManager()->RegisterControllerID( 0, param1 );
+ }
+
+ break;
+ }
+*/
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ this->StartTransitionAnimation( 830, 850 );
+
+ // hide sparkles
+ //
+ if( m_sparkles != NULL )
+ {
+ m_sparkles->SetVisible( false );
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ //
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+//===========================================================================
+// CGuiScreenScrapBookContents::SetLevelBarVisible
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenScrapBookContents::SetLevelBarVisible( bool isVisible )
+{
+ rAssert( m_levelBarGroup != NULL );
+ m_levelBarGroup->SetVisible( isVisible );
+}
+
+//===========================================================================
+// CGuiScreenScrapBookContents::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenScrapBookContents::InitIntro()
+{
+ // this is needed here to update all the unlocked n/N values
+ //
+ this->OnLevelSelectionChange( 0 );
+
+ // show L/R trigger buttons
+ //
+ rAssert( m_LTrigger != NULL && m_RTrigger != NULL );
+ m_LTrigger->SetVisible( true );
+ m_RTrigger->SetVisible( true );
+}
+
+//===========================================================================
+// CGuiScreenScrapBookContents::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenScrapBookContents::InitRunning()
+{
+ // show sparkles only if game percent complete is 100%
+ //
+ float percentComplete = GetCharacterSheetManager()->QueryPercentGameCompleted();
+ if( m_sparkles != NULL )
+ {
+ // TC: [TODO] verify sparkles look OK
+ //
+// m_sparkles->SetVisible( percentComplete == 100.0f );
+ }
+}
+
+//===========================================================================
+// CGuiScreenScrapBookContents::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenScrapBookContents::InitOutro()
+{
+}
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenScrapBookContents::OnLevelSelectionChange( int delta )
+{
+ m_currentLevel = (m_currentLevel + RenderEnums::numLevels + delta) % RenderEnums::numLevels;
+ rAssert( m_levelSelection );
+
+ // update level selection bar
+ //
+ m_levelSelection->SetIndex( m_currentLevel );
+
+ // update menu images and unlocked values
+ //
+ for( int i = 0; i < NUM_MENU_ITEMS; i++ )
+ {
+ if( m_menuImages[ i ] != NULL )
+ {
+ m_menuImages[ i ]->SetIndex( m_currentLevel );
+ }
+ }
+
+ // update unlocked values
+ //
+ HeapMgr()->PushHeap( GMA_LEVEL_FE );
+
+ char buffer[ 8 ];
+ Scrooby::Text* unlockedText = NULL;
+ rAssert( m_pMenu != NULL );
+
+ // missions
+ int numMissionsCompleted = GetCharacterSheetManager()->QueryNumMissionsCompleted( static_cast<RenderEnums::LevelEnum>( m_currentLevel ) );
+ if( GetCharacterSheetManager()->QueryBonusMissionCompleted( static_cast<RenderEnums::LevelEnum>( m_currentLevel ) ) )
+ {
+ numMissionsCompleted++;
+ }
+
+ sprintf( buffer, "%d / %d",
+ numMissionsCompleted,
+ 8 ); // m_currentLevel == 6 ? 5 : 7 );
+ unlockedText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_STORY_MISSIONS )->GetItemValue() );
+ rAssert( unlockedText != NULL );
+ unlockedText->SetString( 0, buffer );
+
+ // clothing
+ sprintf( buffer, "%d / %d",
+ GetCharacterSheetManager()->QueryNumSkinsUnlocked( static_cast<RenderEnums::LevelEnum>( m_currentLevel ) ),
+ 3 );
+ unlockedText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_CHARACTER_CLOTHING )->GetItemValue() );
+ rAssert( unlockedText != NULL );
+ unlockedText->SetString( 0, buffer );
+
+ // vehicles
+ int numVehiclesUnlocked = GetCharacterSheetManager()->QueryNumCarUnlocked( static_cast<RenderEnums::LevelEnum>( m_currentLevel ) );
+ if( GetRewardsManager()->GetReward( m_currentLevel, Reward::eDefaultCar )->RewardStatus() )
+ {
+ numVehiclesUnlocked++;
+ }
+ sprintf( buffer, "%d / %d",
+ numVehiclesUnlocked,
+ 6 );
+ unlockedText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_VEHICLES )->GetItemValue() );
+ rAssert( unlockedText != NULL );
+ unlockedText->SetString( 0, buffer );
+
+ // cards
+ sprintf( buffer, "%d / %d",
+ GetCharacterSheetManager()->QueryNumCardsCollected( static_cast<RenderEnums::LevelEnum>( m_currentLevel ) ),
+ NUM_CARDS_PER_LEVEL );
+ unlockedText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_COLLECTOR_CARDS )->GetItemValue() );
+ rAssert( unlockedText != NULL );
+ unlockedText->SetString( 0, buffer );
+
+/*
+ // movies
+ bool isMovieUnlocked = GetCharacterSheetManager()->QueryFMVUnlocked( static_cast<RenderEnums::LevelEnum>( m_currentLevel ) );
+ if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_MOVIES ) )
+ {
+ isMovieUnlocked = true;
+ }
+
+ sprintf( buffer, "%d / %d",
+ isMovieUnlocked ? 1 : 0,
+ 1 );
+ unlockedText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_MOVIES )->GetItemValue() );
+ rAssert( unlockedText != NULL );
+ unlockedText->SetString( 0, buffer );
+
+ m_pMenu->SetMenuItemEnabled( MENU_MOVIES, isMovieUnlocked );
+*/
+
+ HeapMgr()->PopHeap( GMA_LEVEL_FE );
+}
+
+void
+CGuiScreenScrapBookContents::OnMenuSelectionMade( eMenuItem selection )
+{
+ switch( selection )
+ {
+ case MENU_STORY_MISSIONS:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MISSION_GALLERY );
+
+ break;
+ }
+ case MENU_CHARACTER_CLOTHING:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SKIN_GALLERY );
+
+ break;
+ }
+ case MENU_VEHICLES:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_VEHICLE_GALLERY );
+
+ break;
+ }
+ case MENU_COLLECTOR_CARDS:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_CARD_GALLERY );
+
+ break;
+ }
+/*
+ case MENU_MOVIES:
+ {
+ if( m_currentLevel != RenderEnums::L3 )
+ {
+ rAssert( m_guiManager );
+ CGuiScreenPlayMovie* playMovieScreen = static_cast<CGuiScreenPlayMovie*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_PLAY_MOVIE ) );
+ rAssert( playMovieScreen );
+
+ rAssert( MOVIES_INGAME[ m_currentLevel ] != "" );
+ playMovieScreen->SetMovieToPlay( MOVIES_INGAME[ m_currentLevel ] );
+
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_PLAY_MOVIE );
+ }
+ else // special case for level 3
+ {
+ // TC: [TODO] Need to find out from D.Evenson which mission in L3 to start
+ //
+ GetCharacterSheetManager()->SetCurrentMission( static_cast<RenderEnums::LevelEnum>( m_currentLevel ),
+ static_cast<RenderEnums::MissionEnum>( RenderEnums::M1 ) );
+
+ // send message to front-end manager to quit front-end and
+ // start single player story mode
+ //
+ m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 1 ); // 1 = one player
+ }
+
+ break;
+ }
+*/
+ default:
+ {
+ rAssertMsg( false, "Invalid menu selection!" );
+
+ break;
+ }
+ }
+
+ // hide L/R trigger buttons
+ //
+ rAssert( m_LTrigger != NULL && m_RTrigger != NULL );
+ m_LTrigger->SetVisible( false );
+ m_RTrigger->SetVisible( false );
+}
+
diff --git a/game/code/presentation/gui/frontend/guiscreenscrapbookcontents.h b/game/code/presentation/gui/frontend/guiscreenscrapbookcontents.h
new file mode 100644
index 0000000..d3a6d0f
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenscrapbookcontents.h
@@ -0,0 +1,97 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenScrapBookContents
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/10 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENSCRAPBOOKCONTENTS_H
+#define GUISCREENSCRAPBOOKCONTENTS_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu2D;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenScrapBookContents : public CGuiScreen
+{
+public:
+ CGuiScreenScrapBookContents( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenScrapBookContents();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+ unsigned int GetCurrentLevel() const;
+ void SetLevelBarVisible( bool isVisible );
+#ifdef RAD_WIN32
+ virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y );
+#endif
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ enum eMenuItem
+ {
+ MENU_STORY_MISSIONS,
+ MENU_CHARACTER_CLOTHING,
+ MENU_VEHICLES,
+ MENU_DUMMY_3,
+ MENU_COLLECTOR_CARDS,
+ MENU_DUMMY_5,
+// MENU_MOVIES,
+
+ NUM_MENU_ITEMS
+ };
+
+ void OnLevelSelectionChange( int delta );
+ void OnMenuSelectionMade( eMenuItem selection );
+
+ CGuiMenu2D* m_pMenu;
+
+ Scrooby::Sprite* m_menuImages[ NUM_MENU_ITEMS ];
+
+ Scrooby::Group* m_levelBarGroup;
+ Scrooby::Text* m_levelSelection;
+ Scrooby::Group* m_LTrigger;
+ Scrooby::Group* m_RTrigger;
+ Scrooby::Sprite* m_LTriggerBgd;
+ Scrooby::Sprite* m_RTriggerBgd;
+ unsigned int m_currentLevel;
+
+ Scrooby::Layer* m_sparkles;
+
+};
+
+//===========================================================================
+// Inlines
+//===========================================================================
+
+inline unsigned int CGuiScreenScrapBookContents::GetCurrentLevel() const
+{
+ return m_currentLevel;
+}
+
+#endif // GUISCREENSCRAPBOOKCONTENTS_H
diff --git a/game/code/presentation/gui/frontend/guiscreenscrapbookstats.cpp b/game/code/presentation/gui/frontend/guiscreenscrapbookstats.cpp
new file mode 100644
index 0000000..857dc2f
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenscrapbookstats.cpp
@@ -0,0 +1,284 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenScrapBookStats
+//
+// Description: Implementation of the CGuiScreenScrapBookStats class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/10 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreenscrapbookstats.h>
+
+#include <cards/cardgallery.h>
+#include <memory/srrmemory.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <mission/rewards/rewardsmanager.h>
+#include <render/enums/renderenums.h>
+
+// Scrooby
+//
+#include <screen.h>
+#include <page.h>
+#include <group.h>
+#include <text.h>
+
+// ATG
+//
+#include <raddebug.hpp>
+
+#include <string.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenScrapBookStats::CGuiScreenScrapBookStats
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenScrapBookStats::CGuiScreenScrapBookStats
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SCRAP_BOOK_STATS ),
+ m_percentGameComplete( NULL )
+{
+ memset( m_gameStats, 0, sizeof( m_gameStats ) );
+
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "ScrapBookStats" );
+ rAssert( pPage != NULL );
+
+ // scale down game stats text bit
+ //
+ Scrooby::Text* gameStats = pPage->GetText( "GameStats" );
+ if( gameStats != NULL )
+ {
+ gameStats->ResetTransformation();
+ gameStats->ScaleAboutCenter( 0.75f );
+ }
+
+ Scrooby::Group* pGroup = pPage->GetGroup( "Stats" );
+ rAssert( pGroup != NULL );
+
+ m_gameStats[ STAT_STORY_MISSIONS ] = pGroup->GetText( "StoryMissions_Unlocked" );
+ m_gameStats[ STAT_BONUS_MISSIONS ] = pGroup->GetText( "BonusMissions_Unlocked" );
+ m_gameStats[ STAT_STREET_RACES ] = pGroup->GetText( "StreetRaces_Unlocked" );
+ m_gameStats[ STAT_CARDS ] = pGroup->GetText( "Cards_Unlocked" );
+ m_gameStats[ STAT_CLOTHING ] = pGroup->GetText( "Clothing_Unlocked" );
+ m_gameStats[ STAT_VEHICLES ] = pGroup->GetText( "Vehicles_Unlocked" );
+ m_gameStats[ STAT_WASPS ] = pGroup->GetText( "Wasps_Unlocked" );
+ m_gameStats[ STAT_GAGS ] = pGroup->GetText( "Gags_Unlocked" );
+ m_gameStats[ STAT_MOVIES ] = pGroup->GetText( "Movies_Unlocked" );
+
+ // get game complete value
+ //
+ m_percentGameComplete = pGroup->GetText( "GameComplete_Value" );
+ rAssert( m_percentGameComplete != NULL );
+
+#ifdef RAD_DEBUG
+ for( int i = 0; i < NUM_GAME_STATS; i++ )
+ {
+ rAssert( m_gameStats[ i ] != NULL );
+ }
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenScrapBookStats::~CGuiScreenScrapBookStats
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenScrapBookStats::~CGuiScreenScrapBookStats()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenScrapBookStats::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenScrapBookStats::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ this->StartTransitionAnimation( 830, 850 );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenScrapBookStats::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenScrapBookStats::InitIntro()
+{
+ // sum game stats totals for all levels
+ //
+ int numUnlocked[ NUM_GAME_STATS ];
+ memset( numUnlocked, 0, sizeof( numUnlocked ) );
+
+ int numTotalGagsInGame = 0;
+ int numTotalWaspsInGame = 0;
+
+ for( int i = 0; i < RenderEnums::numLevels; i++ )
+ {
+ numUnlocked[ STAT_STORY_MISSIONS ] += GetCharacterSheetManager()->QueryNumMissionsCompleted( static_cast<RenderEnums::LevelEnum>( i ) );
+ numUnlocked[ STAT_BONUS_MISSIONS ] += GetCharacterSheetManager()->QueryBonusMissionCompleted( static_cast<RenderEnums::LevelEnum>( i ) ) ? 1 : 0;
+ numUnlocked[ STAT_STREET_RACES ] += GetCharacterSheetManager()->QueryNumStreetRacesCompleted( static_cast<RenderEnums::LevelEnum>( i ) );
+ numUnlocked[ STAT_CARDS ] += GetCardGallery()->GetCollectedCards( i )->m_numCards;
+ numUnlocked[ STAT_CLOTHING ] += GetCharacterSheetManager()->QueryNumSkinsUnlocked( static_cast<RenderEnums::LevelEnum>( i ) );
+ numUnlocked[ STAT_VEHICLES ] += GetCharacterSheetManager()->QueryNumCarUnlocked( static_cast<RenderEnums::LevelEnum>( i ) );
+ numUnlocked[ STAT_WASPS ] += GetCharacterSheetManager()->QueryNumWaspsDestroyed( static_cast<RenderEnums::LevelEnum>( i ) );
+ numUnlocked[ STAT_GAGS ] += GetCharacterSheetManager()->QueryNumGagsViewed( static_cast<RenderEnums::LevelEnum>( i ) );
+ numUnlocked[ STAT_MOVIES ] += GetCharacterSheetManager()->QueryFMVUnlocked( static_cast<RenderEnums::LevelEnum>( i ) ) ? 1 : 0;
+
+ numTotalGagsInGame += GetRewardsManager()->GetTotalGags( i );
+ numTotalWaspsInGame += GetRewardsManager()->GetTotalWasps( i );
+ }
+
+ // update game stats
+ //
+ HeapMgr()->PushHeap( GMA_LEVEL_FE );
+
+ char buffer[ 32 ];
+
+ sprintf( buffer, "%d / %d", numUnlocked[ STAT_STORY_MISSIONS ], 49 );
+ m_gameStats[ STAT_STORY_MISSIONS ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%d / %d", numUnlocked[ STAT_BONUS_MISSIONS ], 7 );
+ m_gameStats[ STAT_BONUS_MISSIONS ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%d / %d", numUnlocked[ STAT_STREET_RACES ], 21 );
+ m_gameStats[ STAT_STREET_RACES ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%d / %d", numUnlocked[ STAT_CARDS ], 49 );
+ m_gameStats[ STAT_CARDS ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%d / %d", numUnlocked[ STAT_CLOTHING ], 21 );
+ m_gameStats[ STAT_CLOTHING ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%d / %d", numUnlocked[ STAT_VEHICLES ], 35 );
+ m_gameStats[ STAT_VEHICLES ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%d / %d", numUnlocked[ STAT_WASPS ], numTotalWaspsInGame );
+ m_gameStats[ STAT_WASPS ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%d / %d", numUnlocked[ STAT_GAGS ], numTotalGagsInGame );
+ m_gameStats[ STAT_GAGS ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%d / %d", numUnlocked[ STAT_MOVIES ], 7 );
+ m_gameStats[ STAT_MOVIES ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%.1f %%", GetCharacterSheetManager()->QueryPercentGameCompleted() );
+ m_percentGameComplete->SetString( 0, buffer );
+
+ HeapMgr()->PopHeap( GMA_LEVEL_FE );
+}
+
+
+//===========================================================================
+// CGuiScreenScrapBookStats::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenScrapBookStats::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenScrapBookStats::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenScrapBookStats::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/frontend/guiscreenscrapbookstats.h b/game/code/presentation/gui/frontend/guiscreenscrapbookstats.h
new file mode 100644
index 0000000..ce2f706
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenscrapbookstats.h
@@ -0,0 +1,67 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenScrapBookStats
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/10 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENSCRAPBOOKSTATS_H
+#define GUISCREENSCRAPBOOKSTATS_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenScrapBookStats : public CGuiScreen
+{
+public:
+ CGuiScreenScrapBookStats( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenScrapBookStats();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ enum eGameStats
+ {
+ STAT_STORY_MISSIONS,
+ STAT_BONUS_MISSIONS,
+ STAT_STREET_RACES,
+ STAT_CARDS,
+ STAT_CLOTHING,
+ STAT_VEHICLES,
+ STAT_WASPS,
+ STAT_GAGS,
+ STAT_MOVIES,
+
+ NUM_GAME_STATS
+ };
+
+ Scrooby::Text* m_gameStats[ NUM_GAME_STATS ];
+ Scrooby::Text* m_percentGameComplete;
+
+};
+
+#endif // GUISCREENSCRAPBOOKSTATS_H
diff --git a/game/code/presentation/gui/frontend/guiscreenskingallery.cpp b/game/code/presentation/gui/frontend/guiscreenskingallery.cpp
new file mode 100644
index 0000000..3d79266
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenskingallery.cpp
@@ -0,0 +1,785 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenSkinGallery
+//
+// Description: Implementation of the CGuiScreenSkinGallery class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/21 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreenskingallery.h>
+#include <presentation/gui/frontend/guiscreenscrapbookcontents.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/gui/guimenu.h>
+
+#include <cheats/cheatinputsystem.h>
+#include <memory/srrmemory.h>
+#include <mission/rewards/rewardsmanager.h>
+#include <mission/rewards/reward.h>
+#include <events/eventmanager.h>
+
+#include <p3d/inventory.hpp>
+
+#include <raddebug.hpp> // Foundation
+
+#include <screen.h>
+#include <page.h>
+#include <layer.h>
+#include <group.h>
+#include <text.h>
+
+#include <string.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const char* SKIN_GALLERY_INVENTORY_SECTION = "FE_SkinGallery";
+const char* SKIN_GALLERY_IMAGES_DIR = "art\\frontend\\dynaload\\images\\skins2d\\";
+
+const float SKIN_VIEW_TRANSITION_TIME = 250.0f; // in msec
+const float SKIN_VIEW_PROJECTILE_GRAVITY = 0.005f; // in m/ms/ms
+const int SKIN_VIEW_POS_X = 250;
+const int SKIN_VIEW_POS_Y = 130;
+
+#ifdef RAD_WIN32
+const float SKIN_BASE_SCALE = 1.0f / 2.5f;
+const float SKIN_IMAGE_SCALE = 0.5f / 2.5f;
+#else
+const float SKIN_BASE_SCALE = 1.0f;
+const float SKIN_IMAGE_SCALE = 1.5f - 1.0f;
+#endif
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenSkinGallery::CGuiScreenSkinGallery
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenSkinGallery::CGuiScreenSkinGallery
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SKIN_GALLERY ),
+ m_pMenu( NULL ),
+ m_numSelections( 0 ),
+ m_isSkinsLoaded( false ),
+ m_screenState( SCREEN_STATE_NORMAL ),
+ m_elapsedTime( 0 ),
+ m_projectileVelocity( 0.0f, 0.0f, 0.0f ),
+ m_skinInfo( NULL ),
+#ifdef RAD_WIN32
+ m_selectedSkin(0),
+#endif
+ m_skinName( NULL )
+{
+ memset( m_rewardSelections, 0, sizeof( m_rewardSelections ) );
+
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "SkinGallery" );
+ rAssert( pPage != NULL );
+
+ // create a 2D sprite menu
+ //
+ m_pMenu = new CGuiMenu2D( this, MAX_NUM_SKINS_PER_LEVEL, 3, GUI_SPRITE_MENU, MENU_SFX_NONE );
+ rAssert( m_pMenu != NULL );
+ m_pMenu->SetGreyOutEnabled( false );
+
+ Scrooby::Group* pGroup = pPage->GetGroup( "Menu" );
+ rAssert( pGroup != NULL );
+
+ // add sprites to menu
+ //
+ for( int i = 0; i < MAX_NUM_SKINS_PER_LEVEL; i++ )
+ {
+ char name[ 16 ];
+ sprintf( name, "Skin%d", i );
+
+ m_pMenu->AddMenuItem( pGroup->GetSprite( name ) );
+ }
+
+ // add menu cursor
+ //
+ m_pMenu->SetCursor( pGroup->GetSprite( "SkinCursor" ) );
+
+ // get skin info layer and name
+ //
+ m_skinInfo = pPage->GetLayer( "ViewSkin" );
+ m_skinName = pPage->GetText( "SkinName" );
+
+ // hide skin info layer by default
+ //
+ rAssert( m_skinInfo != NULL );
+ m_skinInfo->SetVisible( false );
+ m_skinInfo->SetAlpha( 0.0f );
+
+ if( this->IsWideScreenDisplay() )
+ {
+ m_skinInfo->ResetTransformation();
+ this->ApplyWideScreenCorrectionScale( m_skinInfo );
+ }
+
+ // wrap skin name
+ //
+// rAssert( m_skinName != NULL );
+// m_skinName->SetTextMode( Scrooby::TEXT_WRAP );
+
+ // add outline to skin name
+ //
+ m_skinName->SetDisplayOutline( true );
+
+ // create inventory section for skin galllery resources
+ //
+ p3d::inventory->AddSection( SKIN_GALLERY_INVENTORY_SECTION );
+}
+
+
+//===========================================================================
+// CGuiScreenSkinGallery::~CGuiScreenSkinGallery
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenSkinGallery::~CGuiScreenSkinGallery()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+
+ // destroy skin gallery inventory section
+ //
+ p3d::inventory->DeleteSection( SKIN_GALLERY_INVENTORY_SECTION );
+}
+
+
+//===========================================================================
+// CGuiScreenSkinGallery::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSkinGallery::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_screenState == SCREEN_STATE_GOTO_VIEW ||
+ m_screenState == SCREEN_STATE_BACK_VIEW )
+ {
+ if( message == GUI_MSG_UPDATE )
+ {
+ this->OnUpdate( param1 );
+ }
+
+ return;
+ }
+
+ if( m_screenState == SCREEN_STATE_VIEWING )
+ {
+ if( message == GUI_MSG_UPDATE )
+ {
+ this->OnUpdate( param1 );
+ }
+ else if( message == GUI_MSG_CONTROLLER_BACK )
+ {
+ m_screenState = SCREEN_STATE_BACK_VIEW;
+ m_elapsedTime = 0;
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); // sound effect
+ }
+
+ return;
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ this->OnUpdate( param1 );
+
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_CHANGED:
+ {
+ this->OnMenuSelectionChange( static_cast<int>( param1 ) );
+
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ this->OnMenuSelectionMade( static_cast<int>( param1 ) );
+#ifdef RAD_WIN32
+ m_selectedSkin = static_cast<int>( param1 );
+ // Hide/disable all other menu items.
+ this->SetVisibilityForAllOtherMenuItems( false );
+#endif
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ //
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenSkinGallery::OnProcessRequestsComplete
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void
+CGuiScreenSkinGallery::OnProcessRequestsComplete( void* pUserData )
+{
+ m_numTransitionsPending--;
+
+ p3d::pddi->DrawSync();
+
+ // push and select inventory section for searching
+ //
+ p3d::inventory->PushSection();
+ p3d::inventory->SelectSection( SKIN_GALLERY_INVENTORY_SECTION );
+ bool currentSectionOnly = p3d::inventory->GetCurrentSectionOnly();
+ p3d::inventory->SetCurrentSectionOnly( true );
+
+ // update all 3D models
+ //
+ CGuiScreenScrapBookContents* pScreen = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ rAssert( pScreen != NULL );
+
+ for( int i = 0; i < m_numSelections; i++ )
+ {
+ if( (m_pMenu->GetMenuItem( i )->m_attributes & SELECTION_ENABLED) > 0 )
+ {
+ char name[ 16 ];
+ sprintf( name, "%s.png", m_rewardSelections[ i ]->GetName() );
+ tSprite* pSprite = p3d::find<tSprite>( name );
+ if( pSprite != NULL )
+ {
+ Scrooby::Sprite* skinImage = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() );
+ rAssert( skinImage != NULL );
+ skinImage->SetRawSprite( pSprite, true );
+ }
+ else
+ {
+ rAssertMsg( false, "Skin image not found!" );
+ }
+ }
+ }
+
+ // pop inventory section and restore states
+ //
+ p3d::inventory->SetCurrentSectionOnly( currentSectionOnly );
+ p3d::inventory->PopSection();
+
+ m_isSkinsLoaded = true;
+}
+
+//===========================================================================
+// CGuiScreenSkinGallery::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSkinGallery::InitIntro()
+{
+ if( !m_isSkinsLoaded )
+ {
+ this->Load2DImages();
+ }
+
+ // set level-specific silhouettes
+ //
+ CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ rAssert( scrapBookContents != NULL );
+ for( int i = 0; i < MAX_NUM_SKINS_PER_LEVEL; i++ )
+ {
+ Scrooby::Sprite* skinImage = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() );
+ rAssert( skinImage != NULL );
+ skinImage->SetIndex( scrapBookContents->GetCurrentLevel() );
+ }
+
+ this->OnMenuSelectionChange( m_pMenu->GetSelection() );
+
+ GetEventManager()->TriggerEvent( EVENT_PLAY_MUZAK );
+}
+
+
+//===========================================================================
+// CGuiScreenSkinGallery::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSkinGallery::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenSkinGallery::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSkinGallery::InitOutro()
+{
+ if( m_isSkinsLoaded )
+ {
+ this->Unload2DImages();
+ }
+
+ GetEventManager()->TriggerEvent( EVENT_PLAY_FE_MUSIC );
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenSkinGallery::OnUpdate( unsigned int elapsedTime )
+{
+ switch( m_screenState )
+ {
+ case SCREEN_STATE_NORMAL:
+ {
+ // pulse cursor alpha
+ //
+ Scrooby::Drawable* cursor = m_pMenu->GetCursor();
+ if( cursor != NULL )
+ {
+ const unsigned int PULSE_PERIOD = 1000;
+
+ float alpha = GuiSFX::Pulse( (float)m_elapsedTime,
+ (float)PULSE_PERIOD,
+ 0.75f,
+ 0.25f,
+ -rmt::PI_BY2 );
+
+ cursor->SetAlpha( alpha );
+
+ m_elapsedTime += elapsedTime;
+ m_elapsedTime %= PULSE_PERIOD;
+ }
+
+ break;
+ }
+ case SCREEN_STATE_GOTO_VIEW:
+ {
+ m_elapsedTime += elapsedTime;
+
+ rAssert( m_pMenu != NULL );
+ int currentSelection = m_pMenu->GetSelection();
+
+ Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( currentSelection )->GetItem();
+ rAssert( pDrawable != NULL );
+
+ pDrawable->ResetTransformation();
+
+ if( m_elapsedTime < (unsigned int)SKIN_VIEW_TRANSITION_TIME )
+ {
+ float percentageDone = m_elapsedTime / SKIN_VIEW_TRANSITION_TIME;
+
+ pDrawable->ScaleAboutCenter( SKIN_BASE_SCALE + percentageDone * SKIN_IMAGE_SCALE );
+
+ GuiSFX::Projectile( pDrawable,
+ (float)m_elapsedTime,
+ SKIN_VIEW_TRANSITION_TIME,
+ m_projectileVelocity,
+ false,
+ SKIN_VIEW_PROJECTILE_GRAVITY );
+
+ // fade out rest of the menu items
+ //
+ this->SetMenuAlpha( 1.0f - rmt::Sqrt( percentageDone ) );
+
+ // fade in skin info layer
+ //
+ rAssert( m_skinInfo != NULL );
+ m_skinInfo->SetAlpha( percentageDone * percentageDone );
+ }
+ else
+ {
+ pDrawable->ScaleAboutCenter( SKIN_BASE_SCALE + SKIN_IMAGE_SCALE );
+
+ GuiSFX::Projectile( pDrawable,
+ SKIN_VIEW_TRANSITION_TIME,
+ SKIN_VIEW_TRANSITION_TIME,
+ m_projectileVelocity,
+ false,
+ SKIN_VIEW_PROJECTILE_GRAVITY );
+
+ this->SetMenuAlpha( 0.0f );
+
+ rAssert( m_skinInfo != NULL );
+ m_skinInfo->SetAlpha( 1.0f );
+
+ m_screenState = SCREEN_STATE_VIEWING;
+ }
+
+ break;
+ }
+ case SCREEN_STATE_VIEWING:
+ {
+
+ break;
+ }
+ case SCREEN_STATE_BACK_VIEW:
+ {
+ m_elapsedTime += elapsedTime;
+
+ rAssert( m_pMenu != NULL );
+ int currentSelection = m_pMenu->GetSelection();
+
+ Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( currentSelection )->GetItem();
+ rAssert( pDrawable != NULL );
+
+ pDrawable->ResetTransformation();
+
+ if( m_elapsedTime < (unsigned int)SKIN_VIEW_TRANSITION_TIME )
+ {
+ float percentageDone = m_elapsedTime / SKIN_VIEW_TRANSITION_TIME;
+
+ pDrawable->ScaleAboutCenter( SKIN_BASE_SCALE + (1.0f - percentageDone) * SKIN_IMAGE_SCALE );
+
+ GuiSFX::Projectile( pDrawable,
+ (float)m_elapsedTime,
+ SKIN_VIEW_TRANSITION_TIME,
+ m_projectileVelocity,
+ true,
+ SKIN_VIEW_PROJECTILE_GRAVITY );
+
+ // fade back in rest of the menu items
+ //
+ this->SetMenuAlpha( percentageDone * percentageDone );
+
+ // fade in skin info layer
+ //
+ rAssert( m_skinInfo != NULL );
+ m_skinInfo->SetAlpha( 1.0f - rmt::Sqrt( percentageDone ) );
+ }
+ else
+ {
+ pDrawable->ScaleAboutCenter( SKIN_BASE_SCALE );
+
+ GuiSFX::Projectile( pDrawable,
+ SKIN_VIEW_TRANSITION_TIME,
+ SKIN_VIEW_TRANSITION_TIME,
+ m_projectileVelocity,
+ true,
+ SKIN_VIEW_PROJECTILE_GRAVITY );
+
+ // show menu cursor
+ //
+ rAssert( m_pMenu != NULL );
+ m_pMenu->GetCursor()->SetVisible( true );
+
+ // show level bar
+ //
+ CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ rAssert( scrapBookContents != NULL );
+ scrapBookContents->SetLevelBarVisible( true );
+
+ this->SetMenuAlpha( 1.0f );
+
+ rAssert( m_skinInfo != NULL );
+ m_skinInfo->SetAlpha( 0.0f );
+
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, true );
+
+ // hide skin info layer
+ //
+ rAssert( m_skinInfo != NULL );
+ m_skinInfo->SetVisible( false );
+
+ m_elapsedTime = 0;
+ m_screenState = SCREEN_STATE_NORMAL;
+#ifdef RAD_WIN32
+ // Show/enable all hidden menu items.
+ this->SetVisibilityForAllOtherMenuItems( true );
+#endif
+ }
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Invalid screen state!" );
+
+ break;
+ }
+ }
+}
+
+void
+CGuiScreenSkinGallery::OnMenuSelectionChange( int selection )
+{
+ // scale up new selection
+ //
+ for( int i = 0; i < m_numSelections; i++ )
+ {
+ Scrooby::BoundedDrawable* drawable = m_pMenu->GetMenuItem( i )->GetItem();
+ rAssert( drawable != NULL );
+ drawable->ResetTransformation();
+ drawable->ScaleAboutCenter( SKIN_BASE_SCALE );
+
+ if( i != selection )
+ {
+ drawable->ScaleAboutCenter( 0.9f );
+ }
+ }
+}
+
+void
+CGuiScreenSkinGallery::OnMenuSelectionMade( int selection )
+{
+ if( m_numSelections > 0 )
+ {
+ // hide level bar
+ //
+ CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ rAssert( scrapBookContents != NULL );
+ scrapBookContents->SetLevelBarVisible( false );
+
+ // hide menu cursor
+ //
+ rAssert( m_pMenu != NULL );
+ m_pMenu->GetCursor()->SetVisible( false );
+
+ // show skin info layer
+ //
+ rAssert( m_skinInfo != NULL );
+ m_skinInfo->SetVisible( true );
+
+ // update skin name
+ //
+ HeapMgr()->PushHeap( GMA_LEVEL_FE );
+
+ char stringID[ 16 ];
+ rAssert( m_rewardSelections[ m_pMenu->GetSelection() ] != NULL );
+ strcpy( stringID, m_rewardSelections[ m_pMenu->GetSelection() ]->GetName() );
+
+ UnicodeString unicodeString;
+ unicodeString.ReadUnicode( GetTextBibleString( strupr( stringID ) ) );
+
+ rAssert( m_skinName != NULL );
+ m_skinName->SetString( 0, unicodeString );
+
+ HeapMgr()->PopHeap( GMA_LEVEL_FE );
+
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, false );
+
+ // calculate the initial projectile velocity
+ //
+ Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( selection )->GetItem();
+ rAssert( pDrawable != NULL );
+
+ int startPosX = 0;
+ int startPosY = 0;
+ pDrawable->GetOriginPosition( startPosX, startPosY );
+
+ m_projectileVelocity.x = (SKIN_VIEW_POS_X - startPosX) / SKIN_VIEW_TRANSITION_TIME;
+ m_projectileVelocity.y = (SKIN_VIEW_POS_Y - startPosY - 0.5f * SKIN_VIEW_PROJECTILE_GRAVITY * SKIN_VIEW_TRANSITION_TIME * SKIN_VIEW_TRANSITION_TIME) / SKIN_VIEW_TRANSITION_TIME;
+
+ m_screenState = SCREEN_STATE_GOTO_VIEW;
+ m_elapsedTime = 0;
+ }
+}
+
+void
+CGuiScreenSkinGallery::SetMenuAlpha( float alpha )
+{
+ rAssert( m_pMenu != NULL );
+ int currentSelection = m_pMenu->GetSelection();
+
+ for( int i = 0; i < MAX_NUM_SKINS_PER_LEVEL; i++ )
+ {
+ if( i != currentSelection )
+ {
+ Scrooby::Drawable* skinImage = m_pMenu->GetMenuItem( i )->GetItem();
+ rAssert( skinImage != NULL );
+ skinImage->SetAlpha( alpha );
+ }
+ }
+}
+
+void
+CGuiScreenSkinGallery::Load2DImages()
+{
+ // load 2D images for current level
+ //
+ CGuiScreenScrapBookContents* pScreen = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ rAssert( pScreen != NULL );
+
+ m_numSelections = 0;
+
+ for( Reward* pReward = GetRewardsManager()->FindFirstMerchandise( pScreen->GetCurrentLevel(), Merchandise::SELLER_INTERIOR );
+ pReward != NULL;
+ pReward = GetRewardsManager()->FindNextMerchandise( pScreen->GetCurrentLevel(), Merchandise::SELLER_INTERIOR ) )
+ {
+ rAssert( m_numSelections < MAX_NUM_SKINS_PER_LEVEL );
+
+ // store reference to reward
+ //
+ m_rewardSelections[ m_numSelections ] = pReward;
+
+ char filename[ 64 ];
+ sprintf( filename, "%s%s.p3d", SKIN_GALLERY_IMAGES_DIR, pReward->GetName() );
+ rAssert( strlen( filename) < sizeof( filename ) );
+
+ GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D,
+ filename,
+ GMA_LEVEL_FE,
+ SKIN_GALLERY_INVENTORY_SECTION,
+ SKIN_GALLERY_INVENTORY_SECTION );
+
+ m_numSelections++;
+ }
+
+ rWarningMsg( m_numSelections > 0, "No model selections available!" );
+
+ if( m_numSelections > 0 )
+ {
+ GetLoadingManager()->AddCallback( this );
+
+ m_numTransitionsPending++;
+ }
+
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); // hide by default
+
+ for( int i = 0; i < MAX_NUM_SKINS_PER_LEVEL; i++ )
+ {
+ if( i < m_numSelections )
+ {
+ bool isUnlocked = m_rewardSelections[ i ]->RewardStatus();
+ if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_SKINS ) )
+ {
+ isUnlocked = true;
+ }
+
+ m_pMenu->SetMenuItemEnabled( i, isUnlocked );
+
+ if( isUnlocked )
+ {
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, true );
+ }
+ }
+ else
+ {
+ m_pMenu->SetMenuItemEnabled( i, false );
+ }
+ }
+}
+
+void
+CGuiScreenSkinGallery::Unload2DImages()
+{
+ p3d::pddi->DrawSync();
+
+ // clear all drawables
+ //
+ for( int i = 0; i < MAX_NUM_SKINS_PER_LEVEL; i++ )
+ {
+ Scrooby::Sprite* skinImage = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() );
+ rAssert( skinImage != NULL );
+ skinImage->SetRawSprite( NULL, true );
+
+ m_pMenu->SetMenuItemEnabled( i, false );
+ }
+
+ // unload 2D images
+ //
+ p3d::inventory->RemoveSectionElements( SKIN_GALLERY_INVENTORY_SECTION );
+
+ m_isSkinsLoaded = false;
+}
+
+#ifdef RAD_WIN32
+void CGuiScreenSkinGallery::SetVisibilityForAllOtherMenuItems( bool bVisible )
+{
+ for( int i = 0; i < MAX_NUM_SKINS_PER_LEVEL; i++ )
+ {
+ if( i != m_selectedSkin )
+ m_pMenu->GetMenuItem(i)->GetItem()->SetVisible( bVisible );
+ }
+}
+#endif \ No newline at end of file
diff --git a/game/code/presentation/gui/frontend/guiscreenskingallery.h b/game/code/presentation/gui/frontend/guiscreenskingallery.h
new file mode 100644
index 0000000..c082306
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenskingallery.h
@@ -0,0 +1,100 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenSkinGallery
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/21 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENSKINGALLERY_H
+#define GUISCREENSKINGALLERY_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <loading/loadingmanager.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class CGuiMenu2D;
+class Reward;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenSkinGallery : public CGuiScreen,
+ public LoadingManager::ProcessRequestsCallback
+{
+public:
+ CGuiScreenSkinGallery( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenSkinGallery();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+ // Implements LoadingManager::ProcessRequestsCallback
+ //
+ virtual void OnProcessRequestsComplete( void* pUserData );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ void OnUpdate( unsigned int elapsedTime );
+ void OnMenuSelectionChange( int selection );
+ void OnMenuSelectionMade( int selection );
+ void SetMenuAlpha( float alpha );
+#ifdef RAD_WIN32
+ void SetVisibilityForAllOtherMenuItems( bool bDisable );
+#endif
+
+ void Load2DImages();
+ void Unload2DImages();
+
+ static const int MAX_NUM_SKINS_PER_LEVEL = 3;
+
+ CGuiMenu2D* m_pMenu;
+
+ Reward* m_rewardSelections[ MAX_NUM_SKINS_PER_LEVEL ];
+ int m_numSelections;
+
+ bool m_isSkinsLoaded : 1;
+
+ enum eScreenState
+ {
+ SCREEN_STATE_NORMAL,
+ SCREEN_STATE_GOTO_VIEW,
+ SCREEN_STATE_VIEWING,
+ SCREEN_STATE_BACK_VIEW,
+
+ NUM_SCREEN_STATES
+ };
+
+ eScreenState m_screenState;
+ unsigned int m_elapsedTime;
+ rmt::Vector m_projectileVelocity;
+
+ Scrooby::Layer* m_skinInfo;
+ Scrooby::Text* m_skinName;
+
+#ifdef RAD_WIN32
+ int m_selectedSkin;
+#endif
+};
+
+#endif // GUISCREENSKINGALLERY_H
diff --git a/game/code/presentation/gui/frontend/guiscreensound.cpp b/game/code/presentation/gui/frontend/guiscreensound.cpp
new file mode 100644
index 0000000..a8f4b81
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreensound.cpp
@@ -0,0 +1,541 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenSound
+//
+// Description: Implementation of the CGuiScreenSound class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreensound.h>
+#include <presentation/gui/guimenu.h>
+
+#include <memory/srrmemory.h>
+#include <sound/soundmanager.h>
+
+#include <raddebug.hpp> // Foundation
+#include <page.h>
+#include <screen.h>
+#include <group.h>
+#include <sprite.h>
+#include <text.h>
+
+#include <string.h>
+
+#ifdef RAD_WIN32
+#include <data/config/gameconfigmanager.h>
+#endif
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const char* SOUND_MENU_ITEMS[] =
+{
+ "Music",
+ "Effects",
+ "Engine",
+ "Voice",
+
+#ifdef INCLUDE_SOUND_MODE
+ "SurroundSound",
+#endif
+
+ "" // dummy terminator
+};
+
+const float SLIDER_CORRECTION_SCALE = 4.0f; // in x-direction only
+
+#ifdef RAD_WIN32
+const float SLIDER_ICON_SCALE = 0.5f;
+#endif
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenSound::CGuiScreenSound
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenSound::CGuiScreenSound
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SOUND ),
+ m_pMenu( NULL )
+{
+MEMTRACK_PUSH_GROUP( "CGUIScreenSound" );
+ memset( m_soundOffIcons, 0, sizeof( m_soundOffIcons ) );
+
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage;
+ pPage = m_pScroobyScreen->GetPage( "Sound" );
+ rAssert( pPage );
+
+ // Create a menu.
+ //
+ m_pMenu = new CGuiMenu( this, NUM_MENU_ITEMS );
+ rAssert( m_pMenu != NULL );
+
+ // Add menu items
+ //
+ Scrooby::Text* pText = NULL;
+ Scrooby::Text* pTextValue = NULL;
+ Scrooby::Sprite* pArrowL = NULL;
+ Scrooby::Sprite* pArrowR = NULL;
+
+ char itemName[ 32 ];
+
+ for( int i = 0; i < NUM_MENU_ITEMS; i++ )
+ {
+ Scrooby::Group* group = pPage->GetGroup( SOUND_MENU_ITEMS[ i ] );
+ rAssert( group != NULL );
+
+ pText = group->GetText( SOUND_MENU_ITEMS[ i ] );
+
+ // if text value exists
+ //
+ sprintf( itemName, "%s_Value", SOUND_MENU_ITEMS[ i ] );
+ pTextValue = group->GetText( itemName );
+
+#ifdef INCLUDE_SOUND_MODE
+ if( i == MENU_ITEM_SURROUND_SOUND )
+ {
+/*
+ // get "dolby prologic #" text and set: # = 1 for GC
+ // # = 2 for PS2
+ //
+ P3D_UNICODE* unicodeString = static_cast<P3D_UNICODE*>( pTextValue->GetStringBuffer( SURROUND_SOUND ) );
+ if( unicodeString != NULL )
+ {
+ int stringLength = p3d::UnicodeStrLen( unicodeString );
+ for( int j = 0; j < stringLength; j++ )
+ {
+ if( unicodeString[ j ] == '#' )
+ {
+#ifdef RAD_GAMECUBE
+ unicodeString[ j ] = '1';
+#endif
+#ifdef RAD_PS2
+ unicodeString[ j ] = '2';
+#endif
+ }
+ }
+ }
+*/
+
+ // add menu item for sound mode setting
+ //
+ pText = pTextValue;
+
+ sprintf( itemName, "%s_LArrow", SOUND_MENU_ITEMS[ i ] );
+ pArrowL = group->GetSprite( itemName );
+
+ sprintf( itemName, "%s_RArrow", SOUND_MENU_ITEMS[ i ] );
+ pArrowR = group->GetSprite( itemName );
+
+ m_pMenu->AddMenuItem( pText,
+ pTextValue,
+ NULL,
+ NULL,
+ pArrowL,
+ pArrowR,
+ SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED );
+ }
+#endif
+
+ // if slider exists
+ //
+ sprintf( itemName, "%s_Slider", SOUND_MENU_ITEMS[ i ] );
+ Scrooby::Group* sliderGroup = group->GetGroup( itemName );
+ if( sliderGroup != NULL )
+ {
+ sliderGroup->ResetTransformation();
+ sliderGroup->ScaleAboutCenter( SLIDER_CORRECTION_SCALE, 1.0f, 1.0f );
+
+ m_pMenu->AddMenuItem( pText,
+ pTextValue,
+ NULL,
+ sliderGroup->GetSprite( itemName ),
+ pArrowL,
+ pArrowR,
+ SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED );
+
+ m_pMenu->GetMenuItem( i )->m_slider.m_type = Slider::HORIZONTAL_SLIDER_ABOUT_CENTER;
+
+ // get sound off icon
+ //
+ sprintf( itemName, "%s_Off", SOUND_MENU_ITEMS[ i ] );
+ m_soundOffIcons[ i ] = group->GetSprite( itemName );
+#ifdef RAD_WIN32
+ m_soundOffIcons[ i ]->ScaleAboutCenter( SLIDER_ICON_SCALE );
+
+ sprintf( itemName, "%s_Icon", SOUND_MENU_ITEMS[ i ] );
+ Scrooby::Sprite* soundOnIcon = group->GetSprite( itemName );
+ soundOnIcon->ScaleAboutCenter( SLIDER_ICON_SCALE );
+#endif
+ }
+ }
+
+#ifdef INCLUDE_SOUND_MODE
+ m_pMenu->SetSelectionValueCount( MENU_ITEM_SURROUND_SOUND, NUM_SOUND_SETTINGS );
+#else
+ // hide surround sound setting
+ //
+ Scrooby::Group* surroundSoundSetting = pPage->GetGroup( "SurroundSound" );
+ if( surroundSoundSetting != NULL )
+ {
+ surroundSoundSetting->SetVisible( false );
+ }
+
+ #ifndef RAD_WIN32 // for PC don't shift the pixels... essential for the mouse cursor.
+ // and move regular sound menu down a bit to re-center vertically
+ //
+ Scrooby::Group* soundMenu = pPage->GetGroup( "Menu" );
+ rAssert( soundMenu != NULL );
+ soundMenu->Translate( 0, -30 );
+ #endif
+#endif
+
+MEMTRACK_POP_GROUP("CGUIScreenSound");
+}
+
+
+//===========================================================================
+// CGuiScreenSound::~CGuiScreenSound
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenSound::~CGuiScreenSound()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenSound::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSound::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_MENU_SELECTION_VALUE_CHANGED:
+ {
+ rAssert( m_pMenu );
+ GuiMenuItem* currentItem = m_pMenu->GetMenuItem( param1 );
+ rAssert( currentItem );
+
+ switch( param1 )
+ {
+ case MENU_ITEM_MUSIC:
+ {
+ GetSoundManager()->SetMusicVolume( currentItem->m_slider.m_value );
+
+ break;
+ }
+ case MENU_ITEM_EFFECTS:
+ {
+ GetSoundManager()->SetSfxVolume( currentItem->m_slider.m_value );
+
+ //
+ // HACK!!
+ //
+ // Oh boy, this is ugly. We've got four sliders and five sets of volumes.
+ // Sfx needs to adjust ambience as well. In a stroke of genius, I didn't
+ // provide a separate set of volumes for the designers. So, the sfx needs
+ // to adjust ambience without upsetting whatever ambience volume they choose
+ // in the scripts. I'm not proud of this.
+ //
+ // Esan
+ //
+ GetSoundManager()->SetAmbienceVolume( GetSoundManager()->GetCalculatedAmbienceVolume() );
+
+ break;
+ }
+ case MENU_ITEM_ENGINE:
+ {
+ GetSoundManager()->SetCarVolume( currentItem->m_slider.m_value );
+
+ break;
+ }
+ case MENU_ITEM_VOICE:
+ {
+ GetSoundManager()->SetDialogueVolume( currentItem->m_slider.m_value );
+
+ break;
+ }
+#ifdef INCLUDE_SOUND_MODE
+ case MENU_ITEM_SURROUND_SOUND:
+ {
+ if( param2 == MONO_SOUND )
+ {
+ GetSoundManager()->SetSoundMode( SOUND_MONO );
+ }
+ else if( param2 == STEREO_SOUND )
+ {
+ GetSoundManager()->SetSoundMode( SOUND_STEREO );
+ }
+ else if( param2 == SURROUND_SOUND )
+ {
+ GetSoundManager()->SetSoundMode( SOUND_SURROUND );
+ }
+ else
+ {
+ rAssert( false );
+ }
+
+ break;
+ }
+#endif
+ default:
+ {
+ break;
+ }
+ }
+
+ // show 'sound off' icon if volume is completely turn off
+ //
+ if( m_soundOffIcons[ param1 ] != NULL )
+ {
+ m_soundOffIcons[ param1 ]->SetVisible( currentItem->m_slider.m_value == 0 );
+ }
+
+ // set flag indicating slider value has changed
+ //
+ m_hasSliderValueChanged[ param1 ] = true;
+
+ break;
+ }
+ case GUI_MSG_MENU_SLIDER_NOT_CHANGING:
+ {
+ // play stinger if music slider has recently changed
+ //
+ if( m_hasSliderValueChanged[ MENU_ITEM_MUSIC ] )
+ {
+ m_hasSliderValueChanged[ MENU_ITEM_MUSIC ] = false;
+
+ GetSoundManager()->PlayMusicOptionMenuStinger();
+ }
+
+ // play stinger if effects slider has recently changed
+ //
+ if( m_hasSliderValueChanged[ MENU_ITEM_EFFECTS ] )
+ {
+ m_hasSliderValueChanged[ MENU_ITEM_EFFECTS ] = false;
+
+ GetSoundManager()->PlaySfxOptionMenuStinger();
+ }
+
+ // play stinger if engine slider has recently changed
+ //
+ if( m_hasSliderValueChanged[ MENU_ITEM_ENGINE ] )
+ {
+ m_hasSliderValueChanged[ MENU_ITEM_ENGINE ] = false;
+
+ GetSoundManager()->PlayCarOptionMenuStinger();
+ }
+
+ // play stinger if voic slider has recently changed
+ //
+ if( m_hasSliderValueChanged[ MENU_ITEM_VOICE ] )
+ {
+ m_hasSliderValueChanged[ MENU_ITEM_VOICE ] = false;
+
+ GetSoundManager()->PlayDialogueOptionMenuStinger();
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ this->StartTransitionAnimation( 690, 720 );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ //
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+//===========================================================================
+// CGuiScreenSound::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSound::InitIntro()
+{
+ // Set slider values to current volume settings
+ //
+ GuiMenuItem* menuItem = NULL;
+ rAssert( m_pMenu );
+
+ // music
+ //
+ menuItem = m_pMenu->GetMenuItem( MENU_ITEM_MUSIC );
+ rAssert( menuItem );
+ menuItem->m_slider.SetValue( GetSoundManager()->GetMusicVolume() );
+
+ rAssert( m_soundOffIcons[ MENU_ITEM_MUSIC ] != NULL );
+ m_soundOffIcons[ MENU_ITEM_MUSIC ]->SetVisible( menuItem->m_slider.m_value == 0 );
+
+ // effects
+ //
+ menuItem = m_pMenu->GetMenuItem( MENU_ITEM_EFFECTS );
+ rAssert( menuItem );
+ menuItem->m_slider.SetValue( GetSoundManager()->GetSfxVolume() );
+
+ rAssert( m_soundOffIcons[ MENU_ITEM_EFFECTS ] != NULL );
+ m_soundOffIcons[ MENU_ITEM_EFFECTS ]->SetVisible( menuItem->m_slider.m_value == 0 );
+
+ // engine
+ //
+ menuItem = m_pMenu->GetMenuItem( MENU_ITEM_ENGINE );
+ rAssert( menuItem );
+ menuItem->m_slider.SetValue( GetSoundManager()->GetCarVolume() );
+
+ rAssert( m_soundOffIcons[ MENU_ITEM_ENGINE ] != NULL );
+ m_soundOffIcons[ MENU_ITEM_ENGINE ]->SetVisible( menuItem->m_slider.m_value == 0 );
+
+ // voice
+ //
+ menuItem = m_pMenu->GetMenuItem( MENU_ITEM_VOICE );
+ rAssert( menuItem );
+ menuItem->m_slider.SetValue( GetSoundManager()->GetDialogueVolume() );
+
+ rAssert( m_soundOffIcons[ MENU_ITEM_VOICE ] != NULL );
+ m_soundOffIcons[ MENU_ITEM_VOICE ]->SetVisible( menuItem->m_slider.m_value == 0 );
+
+ // surround sound
+ //
+#ifdef INCLUDE_SOUND_MODE
+ if( GetSoundManager()->GetSoundMode() == SOUND_MONO )
+ {
+ m_pMenu->SetSelectionValue( MENU_ITEM_SURROUND_SOUND, MONO_SOUND );
+ }
+ else if( GetSoundManager()->GetSoundMode() == SOUND_STEREO )
+ {
+ m_pMenu->SetSelectionValue( MENU_ITEM_SURROUND_SOUND, STEREO_SOUND );
+ }
+ else if( GetSoundManager()->GetSoundMode() == SOUND_SURROUND )
+ {
+ m_pMenu->SetSelectionValue( MENU_ITEM_SURROUND_SOUND, SURROUND_SOUND );
+ }
+#endif
+
+ // reset slider value changed flags
+ //
+ for( int i = 0; i < NUM_MENU_ITEMS; i++ )
+ {
+ m_hasSliderValueChanged[ i ] = false;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenSound::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSound::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenSound::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSound::InitOutro()
+{
+#ifdef RAD_WIN32
+ // Save the new controller mappings to the config file.
+ GetGameConfigManager()->SaveConfigFile();
+#endif
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/frontend/guiscreensound.h b/game/code/presentation/gui/frontend/guiscreensound.h
new file mode 100644
index 0000000..a263ef7
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreensound.h
@@ -0,0 +1,94 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenSound
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENSOUND_H
+#define GUISCREENSOUND_H
+
+#if defined( RAD_GAMECUBE ) || defined( RAD_PS2 )
+ #define INCLUDE_SOUND_MODE
+#endif
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+namespace Scrooby
+{
+ class Screen;
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenSound : public CGuiScreen
+{
+public:
+ CGuiScreenSound( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenSound();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+#ifdef RAD_WIN32
+ //virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y );
+#endif
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ enum eMenuItem
+ {
+ MENU_ITEM_MUSIC,
+ MENU_ITEM_EFFECTS,
+ MENU_ITEM_ENGINE,
+ MENU_ITEM_VOICE,
+
+#ifdef INCLUDE_SOUND_MODE
+ MENU_ITEM_SURROUND_SOUND,
+#endif
+
+ NUM_MENU_ITEMS
+ };
+
+#ifdef INCLUDE_SOUND_MODE
+ enum eMenuItemSurroundSound
+ {
+ MONO_SOUND,
+ STEREO_SOUND,
+ SURROUND_SOUND,
+
+ NUM_SOUND_SETTINGS
+ };
+#endif
+
+ CGuiMenu* m_pMenu;
+
+ Scrooby::Sprite* m_soundOffIcons[ NUM_MENU_ITEMS ];
+ bool m_hasSliderValueChanged[ NUM_MENU_ITEMS ];
+
+};
+
+#endif // GUISCREENSOUND_H
diff --git a/game/code/presentation/gui/frontend/guiscreensplash.cpp b/game/code/presentation/gui/frontend/guiscreensplash.cpp
new file mode 100644
index 0000000..5b8cec7
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreensplash.cpp
@@ -0,0 +1,344 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenSplash
+//
+// Description: Implementation of the CGuiScreenSplash class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreensplash.h>
+#include <presentation/gui/frontend/guiscreenplaymovie.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/frontend/guimanagerfrontend.h>
+
+#include <cheats/cheatinputsystem.h>
+#include <loading/loadingmanager.h>
+#include <main/commandlineoptions.h>
+
+#include <raddebug.hpp> // Foundation
+#include <page.h>
+#include <screen.h>
+#include <sprite.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+short CGuiScreenSplash::s_demoPlaybackToggle = 0;
+
+const unsigned int SPLASH_SCREEN_DEMO_WAIT_TIME = 30000; // in msec
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenSplash::CGuiScreenSplash
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenSplash::CGuiScreenSplash
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SPLASH ),
+ m_pMenu( NULL ),
+ m_pressStart( NULL ),
+ m_demoLoopTime( SPLASH_SCREEN_DEMO_WAIT_TIME ),
+ m_elapsedTime( 0 )
+{
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Splash" );
+ rAssert( pPage != NULL );
+/*
+ Scrooby::Sprite* splashImage = pPage->GetSprite( "GameLogo" );
+ if( splashImage != NULL )
+ {
+ const float SPLASH_SCREEN_IMAGE_CORRECTION_SCALE = 2.0f;
+ splashImage->ScaleAboutCenter( SPLASH_SCREEN_IMAGE_CORRECTION_SCALE );
+ }
+*/
+ // Create a menu.
+ //
+ m_pMenu = new CGuiMenu( this );
+ rAssert( m_pMenu != NULL );
+
+ m_pressStart = pPage->GetText( "PressStart" );
+ rAssert( m_pressStart != NULL );
+
+ m_pMenu->AddMenuItem( m_pressStart,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ SELECTION_ENABLED | TEXT_OUTLINE_ENABLED );
+
+ // set "press start" text to "loading ...", by default
+ //
+ m_pressStart->SetIndex( TEXT_LOADING );
+ m_pressStart->SetColour( tColour( 255, 255, 255 ) );
+
+ if( CommandLineOptions::Get( CLO_DEMO_TEST ) ||
+ GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_DEMO_TEST ) )
+ {
+ m_demoLoopTime = 1000; // in msec
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenSplash::~CGuiScreenSplash
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenSplash::~CGuiScreenSplash()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenSplash::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSplash::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ if( !m_pMenu->HasSelectionBeenMade() )
+ {
+ m_elapsedTime += param1;
+ if( m_elapsedTime > m_demoLoopTime )
+ {
+ if( s_demoPlaybackToggle != 0 )
+ {
+ if ( CommandLineOptions::Get( CLO_DEMO_TEST ) ||
+ GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_DEMO_TEST ) )
+ {
+ this->StartDemoInRuntime();
+ }
+ else
+ {
+ this->StartDemoAsMovie();
+ }
+ }
+ else
+ {
+ if ( CommandLineOptions::Get( CLO_DEMO_TEST ) ||
+ GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_DEMO_TEST ) )
+ {
+ this->StartDemoInRuntime();
+ }
+ else
+ {
+ this->StartDemoAsMovie();
+ }
+ }
+
+ // toggle demo playback format (btw. movie and runtime)
+ //
+ s_demoPlaybackToggle = 1 - s_demoPlaybackToggle;
+
+ m_elapsedTime = 0;
+ }
+ }
+
+ if( m_pressStart != NULL && !GetLoadingManager()->IsLoading() ) // sound loading is done
+ {
+ rAssert( m_pMenu != NULL );
+
+ m_pressStart->SetIndex( TEXT_PRESS_START_GC + PLATFORM_TEXT_INDEX);
+ m_pressStart->SetColour( m_pMenu->GetHighlightColour() );
+ m_pMenu->GetMenuItem( 0 )->m_attributes |= SELECTABLE;
+
+ // set this to NULL cuz we don't need to change it anymore
+ //
+ m_pressStart = NULL;
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ // ignore controller select inputs
+ //
+ return;
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_START:
+ {
+
+ GetGuiSystem()->SetPrimaryController((int)param1);
+
+ if( GetLoadingManager()->IsLoading() )
+ {
+ // ignore start input until all loading is done
+ //
+ return;
+ }
+
+ if( !m_pMenu->HasSelectionBeenMade() )
+ {
+ m_pMenu->MakeSelection();
+ }
+
+ break;
+ }
+
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ m_pParent->HandleMessage( GUI_MSG_SPLASH_SCREEN_DONE );
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ //
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+//===========================================================================
+// CGuiScreenSplash::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSplash::InitIntro()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenSplash::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSplash::InitRunning()
+{
+ m_elapsedTime = 0;
+}
+
+
+//===========================================================================
+// CGuiScreenSplash::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSplash::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenSplash::StartDemoInRuntime()
+{
+ // Quit FE and start the demo in runtime.
+ //
+ m_pParent->HandleMessage( GUI_MSG_QUIT_FRONTEND, 0 ); // 0 = demo mode
+}
+
+void
+CGuiScreenSplash::StartDemoAsMovie()
+{
+#ifndef RAD_WIN32
+ // Play demo movie.
+ //
+ rAssert( m_guiManager );
+ CGuiScreenPlayMovie* playMovieScreen = static_cast<CGuiScreenPlayMovie*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_PLAY_MOVIE_DEMO ) );
+ rAssert( playMovieScreen );
+ playMovieScreen->SetMovieToPlay( MovieNames::DEMO );
+
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ GUI_SCREEN_ID_PLAY_MOVIE_DEMO );
+#endif
+}
+
diff --git a/game/code/presentation/gui/frontend/guiscreensplash.h b/game/code/presentation/gui/frontend/guiscreensplash.h
new file mode 100644
index 0000000..86568ce
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreensplash.h
@@ -0,0 +1,73 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenSplash
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENSPLASH_H
+#define GUISCREENSPLASH_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class CGuiMenu;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenSplash : public CGuiScreen
+{
+public:
+ CGuiScreenSplash( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenSplash();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ void StartDemoAsMovie();
+ void StartDemoInRuntime();
+
+ enum ePressStartText
+ {
+ TEXT_LOADING,
+ TEXT_PRESS_START_GC,
+ TEXT_PRESS_START_PS2,
+ TEXT_PRESS_START_XBOX,
+
+ NUM_PRESS_START_TEXTS
+ };
+
+ CGuiMenu* m_pMenu;
+ Scrooby::Text* m_pressStart;
+
+ unsigned int m_demoLoopTime;
+ unsigned int m_elapsedTime;
+
+ static short s_demoPlaybackToggle;
+
+};
+
+#endif // GUISCREENSPLASH_H
diff --git a/game/code/presentation/gui/frontend/guiscreenvehiclegallery.cpp b/game/code/presentation/gui/frontend/guiscreenvehiclegallery.cpp
new file mode 100644
index 0000000..7619c94
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenvehiclegallery.cpp
@@ -0,0 +1,837 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenVehicleGallery
+//
+// Description: Implementation of the CGuiScreenVehicleGallery class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/21 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreenvehiclegallery.h>
+#include <presentation/gui/frontend/guiscreenscrapbookcontents.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/gui/guimenu.h>
+
+#include <cheats/cheatinputsystem.h>
+#include <memory/srrmemory.h>
+#include <mission/rewards/rewardsmanager.h>
+#include <mission/rewards/reward.h>
+#include <events/eventmanager.h>
+
+#include <p3d/inventory.hpp>
+
+#include <raddebug.hpp> // Foundation
+
+#include <screen.h>
+#include <page.h>
+#include <layer.h>
+#include <group.h>
+#include <text.h>
+
+#include <string.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const char* VEHICLE_GALLERY_INVENTORY_SECTION = "FE_VehicleGallery";
+const char* VEHICLE_GALLERY_IMAGES_DIR = "art\\frontend\\dynaload\\images\\cars2d\\";
+
+const float VEHICLE_VIEW_TRANSITION_TIME = 250.0f; // in msec
+const float VEHICLE_VIEW_PROJECTILE_GRAVITY = 0.005f; // in m/ms/ms
+const int VEHICLE_VIEW_POS_X = 250;
+const int VEHICLE_VIEW_POS_Y = 140;
+#ifdef RAD_WIN32
+const float VEHICLE_BASE_SCALE = 0.66f;
+const float VEHICLE_IMAGE_SCALE = 1.33f - 0.66f;
+#else
+const float VEHICLE_BASE_SCALE = 1.0f;
+const float VEHICLE_IMAGE_SCALE = 2.0f - 1.0f;
+#endif
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenVehicleGallery::CGuiScreenVehicleGallery
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenVehicleGallery::CGuiScreenVehicleGallery
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_VEHICLE_GALLERY ),
+ m_pMenu( NULL ),
+ m_numSelections( 0 ),
+ m_isVehiclesLoaded( false ),
+ m_screenState( SCREEN_STATE_NORMAL ),
+ m_elapsedTime( 0 ),
+ m_projectileVelocity( 0.0f, 0.0f, 0.0f ),
+ m_vehicleInfo( NULL ),
+#ifdef RAD_WIN32
+ m_selectedVehicle(0),
+#endif
+ m_vehicleName( NULL )
+{
+ memset( m_rewardSelections, 0, sizeof( m_rewardSelections ) );
+
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "VehicleGallery" );
+ rAssert( pPage != NULL );
+
+ // create a 2D sprite menu
+ //
+ m_pMenu = new CGuiMenu2D( this, MAX_NUM_VEHICLES_PER_LEVEL, 3, GUI_SPRITE_MENU, MENU_SFX_NONE );
+ rAssert( m_pMenu != NULL );
+ m_pMenu->SetGreyOutEnabled( false );
+
+ Scrooby::Group* pGroup = pPage->GetGroup( "Menu" );
+ rAssert( pGroup != NULL );
+
+ // add sprites to menu
+ //
+ for( int i = 0; i < MAX_NUM_VEHICLES_PER_LEVEL; i++ )
+ {
+ char name[ 16 ];
+ sprintf( name, "Vehicle%d", i );
+
+ m_pMenu->AddMenuItem( pGroup->GetSprite( name ) );
+ }
+
+ // add menu cursor
+ //
+ Scrooby::Sprite* pCursor = pGroup->GetSprite( "VehicleCursor" );
+ if( pCursor != NULL )
+ {
+ // scale up cursor a bit for vehicles
+ //
+ pCursor->ScaleAboutCenter( 2.0f );
+
+ m_pMenu->SetCursor( pCursor );
+ }
+
+ // get vehicle info layer and name
+ //
+ m_vehicleInfo = pPage->GetLayer( "ViewVehicle" );
+ m_vehicleName = pPage->GetText( "VehicleName" );
+
+ // hide vehicle info layer by default
+ //
+ rAssert( m_vehicleInfo != NULL );
+ m_vehicleInfo->SetVisible( false );
+ m_vehicleInfo->SetAlpha( 0.0f );
+
+ if( this->IsWideScreenDisplay() )
+ {
+ m_vehicleInfo->ResetTransformation();
+ this->ApplyWideScreenCorrectionScale( m_vehicleInfo );
+ }
+
+ // wrap vehicle name
+ //
+// rAssert( m_vehicleName != NULL );
+// m_vehicleName->SetTextMode( Scrooby::TEXT_WRAP );
+
+ // add outline to vehicle name
+ //
+ m_vehicleName->SetDisplayOutline( true );
+
+ // create inventory section for vehicle galllery resources
+ //
+ p3d::inventory->AddSection( VEHICLE_GALLERY_INVENTORY_SECTION );
+}
+
+
+//===========================================================================
+// CGuiScreenVehicleGallery::~CGuiScreenVehicleGallery
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenVehicleGallery::~CGuiScreenVehicleGallery()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+
+ // destroy vehicle gallery inventory section
+ //
+ p3d::inventory->DeleteSection( VEHICLE_GALLERY_INVENTORY_SECTION );
+}
+
+
+//===========================================================================
+// CGuiScreenVehicleGallery::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenVehicleGallery::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_screenState == SCREEN_STATE_GOTO_VIEW ||
+ m_screenState == SCREEN_STATE_BACK_VIEW )
+ {
+ if( message == GUI_MSG_UPDATE )
+ {
+ this->OnUpdate( param1 );
+ }
+
+ return;
+ }
+
+ if( m_screenState == SCREEN_STATE_VIEWING )
+ {
+ if( message == GUI_MSG_UPDATE )
+ {
+ this->OnUpdate( param1 );
+ }
+ else if( message == GUI_MSG_CONTROLLER_BACK )
+ {
+ m_screenState = SCREEN_STATE_BACK_VIEW;
+ m_elapsedTime = 0;
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); // sound effect
+ }
+
+ return;
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ this->OnUpdate( param1 );
+
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_CHANGED:
+ {
+ this->OnMenuSelectionChange( static_cast<int>( param1 ) );
+
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ this->OnMenuSelectionMade( static_cast<int>( param1 ) );
+
+#ifdef RAD_WIN32
+ m_selectedVehicle = static_cast<int>( param1 );
+ // Hide/disable all other menu items.
+ this->SetVisibilityForAllOtherMenuItems( false );
+#endif
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ //
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenVehicleGallery::OnProcessRequestsComplete
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void
+CGuiScreenVehicleGallery::OnProcessRequestsComplete( void* pUserData )
+{
+ m_numTransitionsPending--;
+
+ p3d::pddi->DrawSync();
+
+ // push and select inventory section for searching
+ //
+ p3d::inventory->PushSection();
+ p3d::inventory->SelectSection( VEHICLE_GALLERY_INVENTORY_SECTION );
+ bool currentSectionOnly = p3d::inventory->GetCurrentSectionOnly();
+ p3d::inventory->SetCurrentSectionOnly( true );
+
+ // update all 3D models
+ //
+ CGuiScreenScrapBookContents* pScreen = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ rAssert( pScreen != NULL );
+
+ for( int i = 0; i < m_numSelections; i++ )
+ {
+ if( (m_pMenu->GetMenuItem( i )->m_attributes & SELECTION_ENABLED) > 0 )
+ {
+ char name[ 16 ];
+ sprintf( name, "%s.png", m_rewardSelections[ i ]->GetName() );
+ tSprite* pSprite = p3d::find<tSprite>( name );
+ if( pSprite != NULL )
+ {
+ Scrooby::Sprite* vehicleImage = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() );
+ rAssert( vehicleImage != NULL );
+ vehicleImage->SetRawSprite( pSprite, true );
+ }
+ else
+ {
+ rAssertMsg( false, "Vehicle image not found!" );
+ }
+ }
+ }
+
+ // pop inventory section and restore states
+ //
+ p3d::inventory->SetCurrentSectionOnly( currentSectionOnly );
+ p3d::inventory->PopSection();
+
+ m_isVehiclesLoaded = true;
+}
+
+//===========================================================================
+// CGuiScreenVehicleGallery::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenVehicleGallery::InitIntro()
+{
+ if( !m_isVehiclesLoaded )
+ {
+ this->Load2DImages();
+ }
+
+ this->OnMenuSelectionChange( m_pMenu->GetSelection() );
+
+ GetEventManager()->TriggerEvent( EVENT_PLAY_MUZAK );
+}
+
+
+//===========================================================================
+// CGuiScreenVehicleGallery::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenVehicleGallery::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenVehicleGallery::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenVehicleGallery::InitOutro()
+{
+ if( m_isVehiclesLoaded )
+ {
+ this->Unload2DImages();
+ }
+
+ GetEventManager()->TriggerEvent( EVENT_PLAY_FE_MUSIC );
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenVehicleGallery::OnUpdate( unsigned int elapsedTime )
+{
+ switch( m_screenState )
+ {
+ case SCREEN_STATE_NORMAL:
+ {
+ // pulse cursor alpha
+ //
+ Scrooby::Drawable* cursor = m_pMenu->GetCursor();
+ if( cursor != NULL )
+ {
+ const unsigned int PULSE_PERIOD = 1000;
+
+ float alpha = GuiSFX::Pulse( (float)m_elapsedTime,
+ (float)PULSE_PERIOD,
+ 0.75f,
+ 0.25f,
+ -rmt::PI_BY2 );
+
+ cursor->SetAlpha( alpha );
+
+ m_elapsedTime += elapsedTime;
+ m_elapsedTime %= PULSE_PERIOD;
+ }
+
+ break;
+ }
+ case SCREEN_STATE_GOTO_VIEW:
+ {
+ m_elapsedTime += elapsedTime;
+
+ rAssert( m_pMenu != NULL );
+ int currentSelection = m_pMenu->GetSelection();
+
+ Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( currentSelection )->GetItem();
+ rAssert( pDrawable != NULL );
+
+ pDrawable->ResetTransformation();
+
+ if( m_elapsedTime < (unsigned int)VEHICLE_VIEW_TRANSITION_TIME )
+ {
+ float percentageDone = m_elapsedTime / VEHICLE_VIEW_TRANSITION_TIME;
+
+ pDrawable->ScaleAboutCenter( VEHICLE_BASE_SCALE + percentageDone * VEHICLE_IMAGE_SCALE );
+
+ GuiSFX::Projectile( pDrawable,
+ (float)m_elapsedTime,
+ VEHICLE_VIEW_TRANSITION_TIME,
+ m_projectileVelocity,
+ false,
+ VEHICLE_VIEW_PROJECTILE_GRAVITY );
+
+ // fade out rest of the menu items
+ //
+ this->SetMenuAlpha( 1.0f - rmt::Sqrt( percentageDone ) );
+
+ // fade in vehicle info layer
+ //
+ rAssert( m_vehicleInfo != NULL );
+ m_vehicleInfo->SetAlpha( percentageDone * percentageDone );
+ }
+ else
+ {
+ pDrawable->ScaleAboutCenter( VEHICLE_BASE_SCALE + VEHICLE_IMAGE_SCALE );
+
+ GuiSFX::Projectile( pDrawable,
+ VEHICLE_VIEW_TRANSITION_TIME,
+ VEHICLE_VIEW_TRANSITION_TIME,
+ m_projectileVelocity,
+ false,
+ VEHICLE_VIEW_PROJECTILE_GRAVITY );
+
+ this->SetMenuAlpha( 0.0f );
+
+ rAssert( m_vehicleInfo != NULL );
+ m_vehicleInfo->SetAlpha( 1.0f );
+
+ m_screenState = SCREEN_STATE_VIEWING;
+ }
+
+ break;
+ }
+ case SCREEN_STATE_VIEWING:
+ {
+
+ break;
+ }
+ case SCREEN_STATE_BACK_VIEW:
+ {
+ m_elapsedTime += elapsedTime;
+
+ rAssert( m_pMenu != NULL );
+ int currentSelection = m_pMenu->GetSelection();
+
+ Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( currentSelection )->GetItem();
+ rAssert( pDrawable != NULL );
+
+ pDrawable->ResetTransformation();
+
+ if( m_elapsedTime < (unsigned int)VEHICLE_VIEW_TRANSITION_TIME )
+ {
+ float percentageDone = m_elapsedTime / VEHICLE_VIEW_TRANSITION_TIME;
+
+ pDrawable->ScaleAboutCenter( VEHICLE_BASE_SCALE + (1.0f - percentageDone) * VEHICLE_IMAGE_SCALE );
+
+ GuiSFX::Projectile( pDrawable,
+ (float)m_elapsedTime,
+ VEHICLE_VIEW_TRANSITION_TIME,
+ m_projectileVelocity,
+ true,
+ VEHICLE_VIEW_PROJECTILE_GRAVITY );
+
+ // fade back in rest of the menu items
+ //
+ this->SetMenuAlpha( percentageDone * percentageDone );
+
+ // fade in vehicle info layer
+ //
+ rAssert( m_vehicleInfo != NULL );
+ m_vehicleInfo->SetAlpha( 1.0f - rmt::Sqrt( percentageDone ) );
+ }
+ else
+ {
+ pDrawable->ScaleAboutCenter( VEHICLE_BASE_SCALE );
+
+ GuiSFX::Projectile( pDrawable,
+ VEHICLE_VIEW_TRANSITION_TIME,
+ VEHICLE_VIEW_TRANSITION_TIME,
+ m_projectileVelocity,
+ true,
+ VEHICLE_VIEW_PROJECTILE_GRAVITY );
+
+ // show menu cursor
+ //
+ rAssert( m_pMenu != NULL );
+ m_pMenu->GetCursor()->SetVisible( true );
+
+ // show level bar
+ //
+ CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ rAssert( scrapBookContents != NULL );
+ scrapBookContents->SetLevelBarVisible( true );
+
+ this->SetMenuAlpha( 1.0f );
+
+ rAssert( m_vehicleInfo != NULL );
+ m_vehicleInfo->SetAlpha( 0.0f );
+
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, true );
+
+ // hide vehicle info layer
+ //
+ rAssert( m_vehicleInfo != NULL );
+ m_vehicleInfo->SetVisible( false );
+
+ m_elapsedTime = 0;
+ m_screenState = SCREEN_STATE_NORMAL;
+#ifdef RAD_WIN32
+ // Show/enable all hidden menu items.
+ this->SetVisibilityForAllOtherMenuItems( true );
+#endif
+ }
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Invalid screen state!" );
+
+ break;
+ }
+ }
+}
+
+void
+CGuiScreenVehicleGallery::OnMenuSelectionChange( int selection )
+{
+ // scale up new selection
+ //
+ for( int i = 0; i < m_numSelections; i++ )
+ {
+ Scrooby::BoundedDrawable* drawable = m_pMenu->GetMenuItem( i )->GetItem();
+ rAssert( drawable != NULL );
+ drawable->ResetTransformation();
+ drawable->ScaleAboutCenter( VEHICLE_BASE_SCALE );
+
+ if( i != selection )
+ {
+ drawable->ScaleAboutCenter( 0.9f );
+ }
+ }
+}
+
+void
+CGuiScreenVehicleGallery::OnMenuSelectionMade( int selection )
+{
+ if( m_numSelections > 0 )
+ {
+ // hide level bar
+ //
+ CGuiScreenScrapBookContents* scrapBookContents = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ rAssert( scrapBookContents != NULL );
+ scrapBookContents->SetLevelBarVisible( false );
+
+ // hide menu cursor
+ //
+ rAssert( m_pMenu != NULL );
+ m_pMenu->GetCursor()->SetVisible( false );
+
+ // show vehicle info layer
+ //
+ rAssert( m_vehicleInfo != NULL );
+ m_vehicleInfo->SetVisible( true );
+
+ // update vehicle name
+ //
+ HeapMgr()->PushHeap( GMA_LEVEL_FE );
+
+ char stringID[ 16 ];
+ rAssert( m_rewardSelections[ m_pMenu->GetSelection() ] != NULL );
+ strcpy( stringID, m_rewardSelections[ m_pMenu->GetSelection() ]->GetName() );
+
+ UnicodeString unicodeString;
+ unicodeString.ReadUnicode( GetTextBibleString( strupr( stringID ) ) );
+
+ rAssert( m_vehicleName != NULL );
+ m_vehicleName->SetString( 0, unicodeString );
+
+ HeapMgr()->PopHeap( GMA_LEVEL_FE );
+
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, false );
+
+ // calculate the initial projectile velocity
+ //
+ Scrooby::BoundedDrawable* pDrawable = m_pMenu->GetMenuItem( selection )->GetItem();
+ rAssert( pDrawable != NULL );
+
+ int startPosX = 0;
+ int startPosY = 0;
+ pDrawable->GetOriginPosition( startPosX, startPosY );
+
+ m_projectileVelocity.x = (VEHICLE_VIEW_POS_X - startPosX) / VEHICLE_VIEW_TRANSITION_TIME;
+ m_projectileVelocity.y = (VEHICLE_VIEW_POS_Y - startPosY - 0.5f * VEHICLE_VIEW_PROJECTILE_GRAVITY * VEHICLE_VIEW_TRANSITION_TIME * VEHICLE_VIEW_TRANSITION_TIME) / VEHICLE_VIEW_TRANSITION_TIME;
+
+ m_screenState = SCREEN_STATE_GOTO_VIEW;
+ m_elapsedTime = 0;
+ }
+}
+
+void
+CGuiScreenVehicleGallery::SetMenuAlpha( float alpha )
+{
+ rAssert( m_pMenu != NULL );
+ int currentSelection = m_pMenu->GetSelection();
+
+ for( int i = 0; i < MAX_NUM_VEHICLES_PER_LEVEL; i++ )
+ {
+ if( i != currentSelection )
+ {
+ Scrooby::Drawable* vehicleImage = m_pMenu->GetMenuItem( i )->GetItem();
+ rAssert( vehicleImage != NULL );
+ vehicleImage->SetAlpha( alpha );
+ }
+ }
+}
+
+void
+CGuiScreenVehicleGallery::Load2DImages()
+{
+ // load 2D images for current level
+ //
+ CGuiScreenScrapBookContents* pScreen = static_cast<CGuiScreenScrapBookContents*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS ) );
+ rAssert( pScreen != NULL );
+
+ Reward* pReward = NULL;
+ char filename[ 64 ];
+ m_numSelections = 0;
+
+ // load earnable reward and default vehicles
+ //
+ for( int i = Reward::eBlank + 1; i < Reward::NUM_QUESTS; i++ )
+ {
+ pReward = GetRewardsManager()->GetReward( pScreen->GetCurrentLevel(), static_cast<Reward::eQuestType>( i ) );
+ if( pReward != NULL )
+ {
+ if( pReward->GetRewardType() == Reward::ALT_PLAYERCAR )
+ {
+ rAssert( m_numSelections < MAX_NUM_VEHICLES_PER_LEVEL );
+
+ // store reference to reward
+ //
+ m_rewardSelections[ m_numSelections ] = pReward;
+
+ sprintf( filename, "%s%s.p3d", VEHICLE_GALLERY_IMAGES_DIR, pReward->GetName() );
+ rAssert( strlen( filename) < sizeof( filename ) );
+
+ GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D,
+ filename,
+ GMA_LEVEL_FE,
+ VEHICLE_GALLERY_INVENTORY_SECTION,
+ VEHICLE_GALLERY_INVENTORY_SECTION );
+
+ m_numSelections++;
+ }
+ }
+ }
+
+ // load merchandise vehicles (from GIL)
+ //
+ for( pReward = GetRewardsManager()->FindFirstMerchandise( pScreen->GetCurrentLevel(), Merchandise::SELLER_GIL );
+ pReward != NULL;
+ pReward = GetRewardsManager()->FindNextMerchandise( pScreen->GetCurrentLevel(), Merchandise::SELLER_GIL ) )
+ {
+ rAssert( m_numSelections < MAX_NUM_VEHICLES_PER_LEVEL );
+
+ // store reference to reward
+ //
+ m_rewardSelections[ m_numSelections ] = pReward;
+
+ sprintf( filename, "%s%s.p3d", VEHICLE_GALLERY_IMAGES_DIR, pReward->GetName() );
+ rAssert( strlen( filename) < sizeof( filename ) );
+
+ GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D,
+ filename,
+ GMA_LEVEL_FE,
+ VEHICLE_GALLERY_INVENTORY_SECTION,
+ VEHICLE_GALLERY_INVENTORY_SECTION );
+
+ m_numSelections++;
+ }
+
+ // load merchandise vehicles (from SIMPSON CHARACTER)
+ //
+ for( pReward = GetRewardsManager()->FindFirstMerchandise( pScreen->GetCurrentLevel(), Merchandise::SELLER_SIMPSON );
+ pReward != NULL;
+ pReward = GetRewardsManager()->FindNextMerchandise( pScreen->GetCurrentLevel(), Merchandise::SELLER_SIMPSON ) )
+ {
+ rAssert( m_numSelections < MAX_NUM_VEHICLES_PER_LEVEL );
+
+ // store reference to reward
+ //
+ m_rewardSelections[ m_numSelections ] = pReward;
+
+ sprintf( filename, "%s%s.p3d", VEHICLE_GALLERY_IMAGES_DIR, pReward->GetName() );
+ rAssert( strlen( filename) < sizeof( filename ) );
+
+ GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D,
+ filename,
+ GMA_LEVEL_FE,
+ VEHICLE_GALLERY_INVENTORY_SECTION,
+ VEHICLE_GALLERY_INVENTORY_SECTION );
+
+ m_numSelections++;
+ }
+
+ rWarningMsg( m_numSelections > 0, "No model selections available!" );
+
+ if( m_numSelections > 0 )
+ {
+ GetLoadingManager()->AddCallback( this );
+
+ m_numTransitionsPending++;
+ }
+
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); // hide by default
+
+ for( int i = 0; i < MAX_NUM_VEHICLES_PER_LEVEL; i++ )
+ {
+ if( i < m_numSelections )
+ {
+ bool isUnlocked = m_rewardSelections[ i ]->RewardStatus();
+ if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_VEHICLES ) )
+ {
+ isUnlocked = true;
+ }
+
+ m_pMenu->SetMenuItemEnabled( i, isUnlocked );
+
+ if( isUnlocked )
+ {
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, true );
+ }
+ }
+ else
+ {
+ m_pMenu->SetMenuItemEnabled( i, false );
+ }
+ }
+}
+
+void
+CGuiScreenVehicleGallery::Unload2DImages()
+{
+ p3d::pddi->DrawSync();
+
+ // clear all drawables
+ //
+ for( int i = 0; i < MAX_NUM_VEHICLES_PER_LEVEL; i++ )
+ {
+ Scrooby::Sprite* vehicleImage = dynamic_cast<Scrooby::Sprite*>( m_pMenu->GetMenuItem( i )->GetItem() );
+ rAssert( vehicleImage != NULL );
+ vehicleImage->SetRawSprite( NULL, true );
+
+ m_pMenu->SetMenuItemEnabled( i, false );
+ }
+
+ // unload 2D images
+ //
+ p3d::inventory->RemoveSectionElements( VEHICLE_GALLERY_INVENTORY_SECTION );
+
+ m_isVehiclesLoaded = false;
+}
+#ifdef RAD_WIN32
+void CGuiScreenVehicleGallery::SetVisibilityForAllOtherMenuItems( bool bVisible )
+{
+ for( int i = 0; i < MAX_NUM_VEHICLES_PER_LEVEL; i++ )
+ {
+ if( i != m_selectedVehicle )
+ m_pMenu->GetMenuItem(i)->GetItem()->SetVisible( bVisible );
+ }
+}
+#endif
diff --git a/game/code/presentation/gui/frontend/guiscreenvehiclegallery.h b/game/code/presentation/gui/frontend/guiscreenvehiclegallery.h
new file mode 100644
index 0000000..6ddc500
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenvehiclegallery.h
@@ -0,0 +1,100 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenVehicleGallery
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/21 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENVEHICLEGALLERY_H
+#define GUISCREENVEHICLEGALLERY_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <loading/loadingmanager.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class CGuiMenu2D;
+class Reward;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenVehicleGallery : public CGuiScreen,
+ public LoadingManager::ProcessRequestsCallback
+{
+public:
+ CGuiScreenVehicleGallery( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenVehicleGallery();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+ // Implements LoadingManager::ProcessRequestsCallback
+ //
+ virtual void OnProcessRequestsComplete( void* pUserData );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ void OnUpdate( unsigned int elapsedTime );
+ void OnMenuSelectionChange( int selection );
+ void OnMenuSelectionMade( int selection );
+ void SetMenuAlpha( float alpha );
+#ifdef RAD_WIN32
+ void SetVisibilityForAllOtherMenuItems( bool bDisable );
+#endif
+
+ void Load2DImages();
+ void Unload2DImages();
+
+ static const int MAX_NUM_VEHICLES_PER_LEVEL = 6;
+
+ CGuiMenu2D* m_pMenu;
+
+ Reward* m_rewardSelections[ MAX_NUM_VEHICLES_PER_LEVEL ];
+ int m_numSelections;
+
+ bool m_isVehiclesLoaded : 1;
+
+ enum eScreenState
+ {
+ SCREEN_STATE_NORMAL,
+ SCREEN_STATE_GOTO_VIEW,
+ SCREEN_STATE_VIEWING,
+ SCREEN_STATE_BACK_VIEW,
+
+ NUM_SCREEN_STATES
+ };
+
+ eScreenState m_screenState;
+ unsigned int m_elapsedTime;
+ rmt::Vector m_projectileVelocity;
+
+ Scrooby::Layer* m_vehicleInfo;
+ Scrooby::Text* m_vehicleName;
+
+#ifdef RAD_WIN32
+ int m_selectedVehicle;
+#endif
+};
+
+#endif // GUISCREENVEHICLEGALLERY_H
diff --git a/game/code/presentation/gui/frontend/guiscreenviewcredits.cpp b/game/code/presentation/gui/frontend/guiscreenviewcredits.cpp
new file mode 100644
index 0000000..ed3a614
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenviewcredits.cpp
@@ -0,0 +1,503 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenViewCredits
+//
+// Description: Implementation of the CGuiScreenViewCredits class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/05/14 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreenviewcredits.h>
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guiuserinputhandler.h>
+
+#include <cheats/cheatinputsystem.h>
+#include <events/eventmanager.h>
+#include <memory/srrmemory.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+
+// Scrooby
+#include <app.h>
+#include <page.h>
+#include <screen.h>
+#include <group.h>
+#include <text.h>
+#include <sprite.h>
+
+// ATG
+#include <raddebug.hpp>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const float CREDITS_SCROLL_RATE = 20.0f; // in pixels per second
+const float CREDITS_MANUAL_SCROLL_FACTOR = 5.0f;
+const float CREDITS_FGD_CORRECTION_SCALE = 2.0f;
+
+const int CREDITS_PARTITION_FOR_LOCALIZATION = 13;
+const int CREDITS_PARTITION_FOR_LOGITECH = 30;
+
+float CGuiScreenViewCredits::s_totalTranslateY = 0.0f;
+float CGuiScreenViewCredits::s_numPixelsPerLine = 0.0f;
+float CGuiScreenViewCredits::s_creditsOffsets[ CGuiScreenViewCredits::MAX_NUM_CREDITS_PARTITIONS ];
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenViewCredits::CGuiScreenViewCredits
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenViewCredits::CGuiScreenViewCredits
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_VIEW_CREDITS ),
+ m_playKKDialog( false ),
+ m_creditsGroup( NULL ),
+ m_currentTranslateY( 0.0f ),
+ m_lastLineDisplayed( 0 ),
+ m_elapsedIdleTime( 0 )
+{
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "ViewCredits" );
+ rAssert( pPage != NULL );
+
+ // get credits group drawable
+ //
+ m_creditsGroup = pPage->GetGroup( "Credits" );
+ rAssert( m_creditsGroup != NULL );
+
+ bool isFirstTime = ( s_totalTranslateY == 0.0f );
+ float currentTranslateY = 0.0f;
+
+ // get all credits (partitioned) text
+ //
+ for( int i = 0; i < MAX_NUM_CREDITS_PARTITIONS; i++ )
+ {
+ char name[ 16 ];
+ sprintf( name, "Credits%d", i );
+ m_credits[ i ] = m_creditsGroup->GetText( name );
+
+ if( m_credits[ i ] != NULL )
+ {
+#ifndef PAL
+ // hide localization partition from credits for NTSC builds
+ //
+ if( i == CREDITS_PARTITION_FOR_LOCALIZATION )
+ {
+ m_credits[ i ]->SetVisible( false );
+
+ continue;
+ }
+#endif // !PAL
+
+#ifndef RAD_GAMECUBE
+ #ifndef RAD_PS2
+ // hide logitech line from credits for non-GC and non-PS2 platforms
+ //
+ if( i == CREDITS_PARTITION_FOR_LOGITECH )
+ {
+ m_credits[ i ]->SetVisible( false );
+
+ continue;
+ }
+ #endif // !RAD_PS2
+#endif // !RAD_GAMECUBE
+
+ if( isFirstTime )
+ {
+ currentTranslateY = this->FormatTextWithLineBreaks( m_credits[ i ] );
+
+ s_creditsOffsets[ i ] = -s_totalTranslateY;
+ s_totalTranslateY += currentTranslateY;
+ }
+
+ // offset current credits partition by total translation so far
+ //
+ m_credits[ i ]->ResetTransformation();
+ m_credits[ i ]->Translate( 0, (int)s_creditsOffsets[ i ] );
+
+ // disable any text outlining or drop shadow effects
+ //
+ m_credits[ i ]->SetDisplayOutline( false );
+ m_credits[ i ]->SetDisplayShadow( false );
+ }
+ else
+ {
+ // assuming there's no more partitions to follow
+ //
+ break;
+ }
+ }
+
+ // increment total translation for the screen area
+ //
+ if( isFirstTime )
+ {
+ s_totalTranslateY += Scrooby::App::GetInstance()->GetScreenHeight();
+ }
+
+/*
+ // get skip label
+ //
+ m_buttonIcons[ BUTTON_ICON_ACCEPT ] = pPage->GetGroup( "SkipLabel" );
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, false );
+*/
+
+ // apply correction scale to credits foreground overlay image (from CreditsFgd.pag)
+ //
+ pPage = m_pScroobyScreen->GetPage( "CreditsFgd" );
+ if( pPage != NULL )
+ {
+ Scrooby::Sprite* creditsFgd = pPage->GetSprite( "CreditsFgd" );
+ if( creditsFgd != NULL )
+ {
+ creditsFgd->ResetTransformation();
+ creditsFgd->ScaleAboutCenter( CREDITS_FGD_CORRECTION_SCALE );
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenViewCredits::~CGuiScreenViewCredits
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenViewCredits::~CGuiScreenViewCredits()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenViewCredits::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenViewCredits::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( message == GUI_MSG_WINDOW_ENTER )
+ {
+ this->SetFadingEnabled( !GetGuiSystem()->IsShowCreditsUponReturnToFE() );
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ float currentScrollAmount = param1 / 1000.0f * CREDITS_SCROLL_RATE;
+
+ // auto-scrolling
+ //
+ bool isScrollingDone = this->ScrollCredits( currentScrollAmount );
+
+ // check for up/down controller inputs for manual scroll control
+ //
+ const int NUM_USER_INPUT_HANDLERS = GetGuiSystem()->GetNumUserInputHandlers();
+
+ for( int i = 0; i < NUM_USER_INPUT_HANDLERS; i++ )
+ {
+ CGuiUserInputHandler* userInputHandler = GetGuiSystem()->GetUserInputHandler( i );
+ if( userInputHandler != NULL )
+ {
+#ifdef RAD_WIN32
+ if( userInputHandler->IsYAxisOnUp() )
+#else
+ if( userInputHandler->IsButtonDown( GuiInput::Up ) ||
+ userInputHandler->IsYAxisOnUp() )
+#endif
+ {
+ // scroll upwards at opposite rate
+ //
+ isScrollingDone = this->ScrollCredits( -(1.0f + CREDITS_MANUAL_SCROLL_FACTOR) * currentScrollAmount );
+ }
+
+ if( !m_playKKDialog ) // only allow speed-up if dialog is not playing
+ {
+#ifdef RAD_WIN32
+ if( userInputHandler->IsYAxisOnDown() )
+#else
+ if( userInputHandler->IsButtonDown( GuiInput::Down ) ||
+ userInputHandler->IsYAxisOnDown() )
+#endif
+ {
+ // double the scroll rate
+ //
+ isScrollingDone = this->ScrollCredits( (CREDITS_MANUAL_SCROLL_FACTOR - 1.0f) * currentScrollAmount );
+ }
+ }
+ }
+ }
+
+ // check if scroll idle time has expired
+ //
+ if( m_elapsedIdleTime > SCROLL_IDLE_TIME_BEFORE_RESET )
+ {
+ this->OnScrollingDone();
+ }
+ else if( isScrollingDone )
+ {
+ m_elapsedIdleTime += param1;
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ this->OnScrollingDone();
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ // ignore back controller inputs
+ //
+ return;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenViewCredits::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenViewCredits::InitIntro()
+{
+ // only play K&K credits dialog if either cheat is enabled or user has completed
+ // the last mission of the game
+ //
+ m_playKKDialog = GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_PLAY_CREDITS_DIALOG ) ||
+ GetCharacterSheetManager()->QueryMissionStatus( RenderEnums::L7, RenderEnums::M7 )->mCompleted;
+
+ this->ResetScrolling();
+
+ // hide back button label
+ //
+ this->SetButtonVisible( BUTTON_ICON_BACK, false );
+
+ GetEventManager()->TriggerEvent( EVENT_PLAY_CREDITS );
+}
+
+
+//===========================================================================
+// CGuiScreenViewCredits::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenViewCredits::InitRunning()
+{
+ if( GetGuiSystem()->IsShowCreditsUponReturnToFE() )
+ {
+ this->RestoreDefaultFadeTime();
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenViewCredits::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenViewCredits::InitOutro()
+{
+ if( GetGuiSystem()->IsShowCreditsUponReturnToFE() )
+ {
+ GetGuiSystem()->ShowCreditsUponReturnToFE( false );
+ }
+
+ GetEventManager()->TriggerEvent( EVENT_DIALOG_SHUTUP );
+ GetEventManager()->TriggerEvent( EVENT_PLAY_FE_MUSIC );
+}
+
+
+void
+CGuiScreenViewCredits::ResetScrolling()
+{
+ rAssert( m_creditsGroup != NULL );
+ m_creditsGroup->ResetTransformation();
+
+ m_currentTranslateY = 0.0f;
+
+ m_lastLineDisplayed = 0;
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+float
+CGuiScreenViewCredits::FormatTextWithLineBreaks( Scrooby::Text* pText )
+{
+ rAssert( pText != NULL );
+
+ float totalTranslateY = 0.0f;
+
+ int width = 0;
+ int height = 0;
+ pText->GetBoundingBoxSize( width, height );
+
+#ifdef RAD_WIN32
+ const float SPACING_FUDGE_FACTOR = 1.20f;
+#else
+ const float SPACING_FUDGE_FACTOR = 1.15f;
+#endif
+
+ s_numPixelsPerLine = height * SPACING_FUDGE_FACTOR;
+
+ P3D_UNICODE* textBuffer = static_cast<P3D_UNICODE*>( pText->GetStringBuffer() );
+ rAssert( textBuffer != NULL );
+
+ for( int i = 0; textBuffer[ i ] != '\0'; i++ )
+ {
+ if( textBuffer[ i ] == '\\' ) // replace backslashes with line breaks
+ {
+ textBuffer[ i ] = '\n';
+
+ // increment total translation by number of pixels per line
+ //
+ totalTranslateY += s_numPixelsPerLine;
+ }
+ }
+
+ return totalTranslateY;
+}
+
+bool
+CGuiScreenViewCredits::ScrollCredits( float pixels )
+{
+ float newTranslateY = m_currentTranslateY + pixels;
+
+ bool isScrollingDone = ( newTranslateY > s_totalTranslateY );
+
+ if( newTranslateY >= 0 && newTranslateY <= s_totalTranslateY )
+ {
+ m_currentTranslateY = newTranslateY;
+
+ rAssert( m_creditsGroup != NULL );
+ m_creditsGroup->ResetTransformation();
+ m_creditsGroup->Translate( 0, (int)m_currentTranslateY );
+
+ // check if new line is displayed
+ //
+ const float BOTTOM_OFFSET = 80.0f; // in pixels
+ if( (m_currentTranslateY - BOTTOM_OFFSET) >= (m_lastLineDisplayed * s_numPixelsPerLine) )
+ {
+ m_lastLineDisplayed++;
+
+ this->OnNewLineDisplayed( m_lastLineDisplayed );
+ }
+
+ m_elapsedIdleTime = 0; // reset idle time
+ }
+ else
+ {
+ rDebugPrintf( "Credits not scrolling.\n" );
+ }
+
+ return isScrollingDone;
+}
+
+void
+CGuiScreenViewCredits::OnScrollingDone()
+{
+ if( GetGuiSystem()->IsShowCreditsUponReturnToFE() )
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ GUI_SCREEN_ID_MAIN_MENU,
+ CLEAR_WINDOW_HISTORY );
+ }
+ else if( m_guiManager->GetPreviousScreen() != GUI_WINDOW_ID_UNDEFINED )
+ {
+ this->StartTransitionAnimation( 630, 660 );
+
+ m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN );
+ }
+}
+
+void
+CGuiScreenViewCredits::OnNewLineDisplayed( int lineNumber )
+{
+ rTunePrintf( "Credits Line #%d\n", lineNumber );
+
+ if( m_playKKDialog )
+ {
+ // trigger this event for the sound manager to play line-specific dialog
+ //
+ GetEventManager()->TriggerEvent( EVENT_FE_CREDITS_NEW_LINE, (void*)lineNumber );
+ }
+}
+
diff --git a/game/code/presentation/gui/frontend/guiscreenviewcredits.h b/game/code/presentation/gui/frontend/guiscreenviewcredits.h
new file mode 100644
index 0000000..b1899bf
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenviewcredits.h
@@ -0,0 +1,74 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenViewCredits
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/05/14 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENVIEWCREDITS_H
+#define GUISCREENVIEWCREDITS_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenViewCredits : public CGuiScreen
+{
+public:
+ CGuiScreenViewCredits( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenViewCredits();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+ void ResetScrolling();
+ bool m_playKKDialog : 1;
+
+ Scrooby::Group* m_creditsGroup;
+
+private:
+ float FormatTextWithLineBreaks( Scrooby::Text* pText );
+
+ bool ScrollCredits( float pixels );
+ virtual void OnScrollingDone();
+
+ void OnNewLineDisplayed( int lineNumber );
+
+ static const int MAX_NUM_CREDITS_PARTITIONS = 32;
+
+ static float s_totalTranslateY;
+ static float s_numPixelsPerLine;
+ static float s_creditsOffsets[ MAX_NUM_CREDITS_PARTITIONS ];
+
+ Scrooby::Text* m_credits[ MAX_NUM_CREDITS_PARTITIONS ];
+ float m_currentTranslateY;
+ int m_lastLineDisplayed;
+
+ static const unsigned int SCROLL_IDLE_TIME_BEFORE_RESET = 0; // in msec
+ unsigned int m_elapsedIdleTime;
+
+};
+
+#endif // GUISCREENVIEWCREDITS_H
diff --git a/game/code/presentation/gui/frontend/guiscreenviewmovies.cpp b/game/code/presentation/gui/frontend/guiscreenviewmovies.cpp
new file mode 100644
index 0000000..5573f98
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenviewmovies.cpp
@@ -0,0 +1,287 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenViewMovies
+//
+// Description: Implementation of the CGuiScreenViewMovies class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreenviewmovies.h>
+#include <presentation/gui/frontend/guiscreenplaymovie.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guimanager.h>
+
+#include <cheats/cheatinputsystem.h>
+#include <constants/movienames.h>
+#include <memory/srrmemory.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+
+#include <raddebug.hpp> // Foundation
+#include <page.h>
+#include <screen.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const char* MOVIES_MENU_ITEMS[] =
+{
+ "IntroMovie",
+ "Movie1",
+ "Movie2",
+ "Movie3",
+ "Movie4",
+ "Movie5",
+ "Movie6",
+ "Movie7",
+ "Movie8",
+
+ "" // dummy terminator
+};
+
+const char* MOVIES_SELECTION[] =
+{
+ MovieNames::INTROFMV,
+ MovieNames::MOVIE1,
+ MovieNames::MOVIE2,
+ MovieNames::MOVIE3,
+ MovieNames::MOVIE4,
+ MovieNames::MOVIE5,
+ MovieNames::MOVIE6,
+ MovieNames::MOVIE7,
+ MovieNames::MOVIE8,
+
+ "" // dummy terminator
+};
+
+const int NUM_MOVIE_SELECTIONS = sizeof( MOVIES_SELECTION ) / sizeof( MOVIES_SELECTION[ 0 ] ) - 1;
+
+const int MOVIE_INDEX_FOR_LEVEL[] =
+{
+ 2, // level 1
+ 3, // level 2
+ 8, // level 3
+ 4, // level 4
+ 5, // level 5
+ 6, // level 6
+ 7, // level 7
+
+ -1
+};
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenViewMovies::CGuiScreenViewMovies
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenViewMovies::CGuiScreenViewMovies
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_VIEW_MOVIES ),
+ m_pMenu( NULL )
+{
+MEMTRACK_PUSH_GROUP( "CGuiScreenViewMovies" );
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage;
+ pPage = m_pScroobyScreen->GetPage( "ViewMovies" );
+ rAssert( pPage );
+
+ // Create a menu.
+ //
+ m_pMenu = new(GMA_LEVEL_FE) CGuiMenu( this, NUM_MOVIE_SELECTIONS );
+ rAssert( m_pMenu != NULL );
+
+ // Add menu items
+ //
+ for( int i = 0; i < NUM_MOVIE_SELECTIONS; i++ )
+ {
+ m_pMenu->AddMenuItem( pPage->GetText( MOVIES_MENU_ITEMS[ i ] ) );
+ }
+
+ this->AutoScaleFrame( m_pScroobyScreen->GetPage( "BigBoard" ) );
+MEMTRACK_POP_GROUP("CGuiScreenViewMovies");
+}
+
+
+//===========================================================================
+// CGuiScreenViewMovies::~CGuiScreenViewMovies
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenViewMovies::~CGuiScreenViewMovies()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenViewMovies::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenViewMovies::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ rAssert( m_guiManager );
+ CGuiScreenPlayMovie* playMovieScreen = static_cast<CGuiScreenPlayMovie*>( m_guiManager->FindWindowByID( GUI_SCREEN_ID_PLAY_MOVIE ) );
+ rAssert( playMovieScreen );
+
+ rAssert( static_cast<int>( param1 ) < NUM_MOVIE_SELECTIONS );
+ if( param1 == 0 ) // 0 = Intro FMV
+ {
+ // Intro FMV does not have localized audio.
+ //
+ playMovieScreen->SetMovieToPlay( MOVIES_SELECTION[ param1 ], true, false, false );
+ }
+ else
+ {
+ playMovieScreen->SetMovieToPlay( MOVIES_SELECTION[ param1 ] );
+ }
+
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_PLAY_MOVIE );
+ this->StartTransitionAnimation( 975, 1005 );
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ this->StartTransitionAnimation( 944, 974 );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenViewMovies::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenViewMovies::InitIntro()
+{
+ // update movies unlocked status
+ //
+ rAssert( m_pMenu != NULL );
+ for( int i = 0; i < RenderEnums::numLevels; i++ )
+ {
+ bool isUnlocked = GetCharacterSheetManager()->QueryFMVUnlocked( static_cast<RenderEnums::LevelEnum>( i ) ) ||
+ GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_MOVIES );
+
+ m_pMenu->SetMenuItemEnabled( MOVIE_INDEX_FOR_LEVEL[ i ], isUnlocked );
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenViewMovies::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenViewMovies::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenViewMovies::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenViewMovies::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/frontend/guiscreenviewmovies.h b/game/code/presentation/gui/frontend/guiscreenviewmovies.h
new file mode 100644
index 0000000..5513f34
--- /dev/null
+++ b/game/code/presentation/gui/frontend/guiscreenviewmovies.h
@@ -0,0 +1,53 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenViewMovies
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENVIEWMOVIES_H
+#define GUISCREENVIEWMOVIES_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenViewMovies : public CGuiScreen
+{
+public:
+ CGuiScreenViewMovies( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenViewMovies();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ CGuiMenu* m_pMenu;
+
+};
+
+#endif // GUISCREENVIEWMOVIES_H
diff --git a/game/code/presentation/gui/guientity.cpp b/game/code/presentation/gui/guientity.cpp
new file mode 100644
index 0000000..d2a1a6a
--- /dev/null
+++ b/game/code/presentation/gui/guientity.cpp
@@ -0,0 +1,61 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiEntity
+//
+// Description: Implementation of the CGuiEntity class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/09/21 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/guientity.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiEntity::CGuiEntity
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiEntity::CGuiEntity( CGuiEntity* pParent )
+: m_pParent( pParent )
+{
+}
+
+//===========================================================================
+// CGuiEntity::~CGuiEntity
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiEntity::~CGuiEntity()
+{
+}
diff --git a/game/code/presentation/gui/guientity.h b/game/code/presentation/gui/guientity.h
new file mode 100644
index 0000000..8fc7afb
--- /dev/null
+++ b/game/code/presentation/gui/guientity.h
@@ -0,0 +1,184 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiEntity
+//
+// Description: Interface for the CGuiEntity class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/09/20 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef GUIENTITY_H
+#define GUIENTITY_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+#ifndef NULL
+ #define NULL 0
+#endif
+
+#ifdef RAD_GAMECUBE
+ const int PLATFORM_TEXT_INDEX = 0;
+#endif
+#ifdef RAD_PS2
+ const int PLATFORM_TEXT_INDEX = 1;
+#endif
+#ifdef RAD_XBOX
+ const int PLATFORM_TEXT_INDEX = 2;
+#endif
+#ifdef RAD_WIN32 // parallel the xbox for now.
+ const int PLATFORM_TEXT_INDEX = 2;
+#endif
+
+enum eGuiMessage
+{
+ GUI_MSG_UPDATE, // GUI system -> Manager -> current screen
+ GUI_MSG_CONTROLLER_ALPHA, // begin controller messages
+ GUI_MSG_CONTROLLER_UP, //
+ GUI_MSG_CONTROLLER_DOWN,
+ GUI_MSG_CONTROLLER_LEFT,
+ GUI_MSG_CONTROLLER_RIGHT,
+ GUI_MSG_CONTROLLER_AUX_UP, // on right analog stick
+ GUI_MSG_CONTROLLER_AUX_DOWN, // on right analog stick
+ GUI_MSG_CONTROLLER_AUX_LEFT, // on right analog stick
+ GUI_MSG_CONTROLLER_AUX_RIGHT, // on right analog stick
+ GUI_MSG_CONTROLLER_START,
+ GUI_MSG_CONTROLLER_SELECT,
+ GUI_MSG_CONTROLLER_BACK,
+ GUI_MSG_CONTROLLER_AUX_X,
+ GUI_MSG_CONTROLLER_AUX_Y,
+ GUI_MSG_CONTROLLER_L1,
+ GUI_MSG_CONTROLLER_R1,
+ GUI_MSG_CONTROLLER_CONNECT,
+ GUI_MSG_CONTROLLER_DISCONNECT, //
+ GUI_MSG_CONTROLLER_OMEGA, // end controller messages
+ GUI_MSG_PROJECT_LOAD_COMPLETE, // Scrooby File Handler -> GUI System
+ GUI_MSG_INIT_BOOTUP, // client -> System
+ GUI_MSG_RELEASE_BOOTUP, // client -> System
+ GUI_MSG_INIT_FRONTEND, // client -> System
+ GUI_MSG_RELEASE_FRONTEND, // client -> System
+ GUI_MSG_INIT_MINIGAME, // client -> System
+ GUI_MSG_RELEASE_MINIGAME, // client -> System
+ GUI_MSG_INIT_INGAME, // client -> System
+ GUI_MSG_RELEASE_INGAME, // client -> System
+ GUI_MSG_PRE_RUN_BACKEND, // ManagerInGame -> ManagerBackEnd
+ GUI_MSG_RUN_BACKEND, // client -> System
+ GUI_MSG_RUN_FRONTEND, // client -> System
+ GUI_MSG_RUN_MINIGAME, // client -> System
+ GUI_MSG_RUN_INGAME, // client -> System
+ GUI_MSG_RUN_DEMO, // client -> System
+ GUI_MSG_PAUSE_INGAME, // System -> ManagerInGame
+ GUI_MSG_UNPAUSE_INGAME, // Pause Menu Screen -> ManagerInGame
+ GUI_MSG_RESUME_INGAME, // System -> ManagerInGame
+ GUI_MSG_QUIT_BOOTUP, // client -> ManagerBootUp
+ GUI_MSG_QUIT_BACKEND, // client -> ManagerBackEnd
+ GUI_MSG_QUIT_FRONTEND, // Screen -> ManagerFrontEnd
+ GUI_MSG_QUIT_MINIGAME, // Screen -> ManagerMiniGame
+ GUI_MSG_QUIT_INGAME, // PauseMenu -> ManagerInGame
+ GUI_MSG_QUIT_INGAME_FOR_RELOAD, // MissionSelect -> ManagerInGame
+ GUI_MSG_QUIT_DEMO, // client/screen -> ManagerBackEnd
+ GUI_MSG_QUIT_GAME, // pc. Screen -> ManagerFrontEnd
+ GUI_MSG_BOOTUP_LOAD_COMPLETED, // screen -> ManagerBootUp
+ GUI_MSG_LANGUAGE_SELECTION_DONE, // screen -> ManagerBootUp
+ GUI_MSG_MEMCARD_CHECK_COMPLETED, // screen -> ManagerBootUp / ManagerFrontEnd
+ GUI_MSG_SPLASH_SCREEN_DONE, // screen -> ManagerFrontEnd
+ GUI_MSG_GOTO_SCREEN, // screen -> ManagerFrontEnd (param1 = screen id)
+ GUI_MSG_BACK_SCREEN, // screen -> Manager
+ GUI_MSG_SHOW_HUD_OVERLAY, // client -> In-game HUD (param1 = overlay id)
+ GUI_MSG_HIDE_HUD_OVERLAY, // client -> In-game HUD (param1 = overlay id)
+ GUI_MSG_INGAME_MISSION_COMPLETE, // client -> ManagerInGame
+ GUI_MSG_INGAME_MISSION_FAILED, // client -> ManagerInGame
+ GUI_MSG_INGAME_MISSION_LOAD_BEGIN, // client -> ManagerInGame
+ GUI_MSG_INGAME_MISSION_LOAD_END, // client -> ManagerInGame
+ GUI_MSG_INGAME_DISPLAY_PROMPT, // client -> ManagerInGame
+ GUI_MSG_WINDOW_ENTER, // Manager -> Window
+ GUI_MSG_WINDOW_EXIT, // Manager -> Window
+ GUI_MSG_WINDOW_FINISHED, // Window -> Manager
+ GUI_MSG_WINDOW_PAUSE, // client -> Window
+ GUI_MSG_WINDOW_RESUME, // client -> Window
+ GUI_MSG_DEMOLOOP_BEGIN, // ManagerFrontEnd->Screen
+ GUI_MSG_DEMOLOOP_END, // ManagerFrontEnd->Screen
+ GUI_MSG_RESTART_GAME, // Pause Menu -> ManagerInGame
+ GUI_MSG_MENU_SELECTION_CHANGED, // Menu -> Screen
+ GUI_MSG_MENU_SELECTION_VALUE_CHANGED, // Menu -> Screen
+ GUI_MSG_MENU_SELECTION_MADE, // Menu -> Screen
+ GUI_MSG_MENU_SLIDER_NOT_CHANGING, // Menu -> Screen
+ GUI_MSG_ON_DISPLAY_MESSAGE, // Message Screen -> Screen
+ GUI_MSG_MENU_PROMPT_RESPONSE, // Prompt Screen -> Screen
+ GUI_MSG_ERROR_PROMPT_RESPONSE, // Prompt Screen -> Screen
+ GUI_MSG_PROMPT_START_RESPONSE, // Prompt Screen -> Screen, only on ps2
+ GUI_MSG_DEATH_VOLUME_START, // Play the death volume transition
+ GUI_MSG_MANUAL_RESET, // Play the death volume transition
+ GUI_MSG_START_IRIS_WIPE_CLOSE, // Do an iris wipe closing
+ GUI_MSG_START_IRIS_WIPE_OPEN, // Do an iris wipe opening
+ GUI_MSG_INGAME_FADE_OUT, // Fade from IN-GAME to BLACK
+ GUI_MSG_INGAME_FADE_IN, // Fade from BLACK to IN-GAME
+ GUI_MSG_INGAME_FADE_OUT_CANCEL, // Cancel fading from IN-GAME to BLACK
+ GUI_MSG_INGAME_FADE_IN_CANCEL, // Cancel fading from BLACK to IN-GAME
+ GUI_MSG_LOAD_RESOURCES, // GUI manager -> Screen
+ GUI_MSG_SET_GOTO_SCREEN_PARAMETERS, // GUI system -> GUI manager
+ GUI_MSG_ON_SAVE_GAME_COMPLETE, // save game screen -> GUI in-game manager
+ GUI_MSG_PROMPT_UPDATE, // Prompt Screen -> Screen called during CGuiScreenPrompt::HandleMessage GUI_MSG_UPDATE
+ GUI_MSG_MESSAGE_UPDATE, // Message Screen -> Screen called during CGuiScreenMessage::HandleMessage GUI_MSG_UPDATE
+#ifdef RAD_WIN32
+ GUI_MSG_MOUSE_OVER, // Called when a mouse cursor is on a hotspot.
+ GUI_MSG_MOUSE_LCLICK, // Called when a mouse clicks the left button and releases.
+ GUI_MSG_MOUSE_RCLICK, // Called when a mouse clicks the right button and releases.
+ GUI_MSG_MOUSE_LCLICKHOLD, // Called when a mouse clicks a hotspot and holds with the left button.
+ GUI_MSG_MOUSE_RCLICKHOLD, // Called when a mouse clicks a hotspot and holds with the right button.
+ GUI_MSG_MOUSE_LCLICKDRAG, // Called when a mouse left clicks on a hotspot and drags.
+ GUI_MSG_QUIT_TO_SYSTEM,
+#endif
+
+ GUI_MSG_TOTAL
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiEntity
+{
+public:
+ CGuiEntity( CGuiEntity* pParent );
+ virtual ~CGuiEntity();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 ) = 0;
+
+ static bool IsControllerMessage( eGuiMessage message );
+
+protected:
+ CGuiEntity* m_pParent;
+
+private:
+ //---------------------------------------------------------------------
+ // Private Functions
+ //---------------------------------------------------------------------
+
+ // No copying or assignement. Declare but don't define.
+ //
+ CGuiEntity( const CGuiEntity& );
+ CGuiEntity& operator= ( const CGuiEntity& );
+
+};
+
+inline bool
+CGuiEntity::IsControllerMessage( eGuiMessage message )
+{
+ return (message > GUI_MSG_CONTROLLER_ALPHA && message < GUI_MSG_CONTROLLER_OMEGA);
+}
+
+#endif // GUIENTITY_H
diff --git a/game/code/presentation/gui/guimanager.cpp b/game/code/presentation/gui/guimanager.cpp
new file mode 100644
index 0000000..8a0ab88
--- /dev/null
+++ b/game/code/presentation/gui/guimanager.cpp
@@ -0,0 +1,650 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiManager
+//
+// Description: Implementation of the CGuiManager class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/09/21 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guisystem.h> // for loading callback
+#include <presentation/gui/guiscreen.h>
+#include <presentation/gui/guiscreenmessage.h>
+#include <presentation/gui/guiscreenprompt.h>
+#include <input/inputmanager.h>
+
+#include <gameflow/gameflow.h>
+#include <memory/srrmemory.h>
+
+#include <raddebug.hpp> // Foundation
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+CGuiManager::eMemoryCardCheckingState
+CGuiManager::s_memcardCheckState = CGuiManager::MEM_CARD_CHECK_NOT_DONE;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiManager::CGuiManager
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiManager::CGuiManager
+(
+ Scrooby::Project* pProject,
+ CGuiEntity* pParent
+)
+: CGuiEntity( pParent ),
+ m_numWindows( 0 ),
+ m_pScroobyProject( pProject ),
+ m_currentScreen( CGuiWindow::GUI_WINDOW_ID_UNDEFINED ),
+ m_nextScreen( CGuiWindow::GUI_WINDOW_ID_UNDEFINED ),
+ m_state( GUI_FE_UNINITIALIZED ),
+ m_windowHistoryCount( 0 ),
+ m_gotoScreenUserParam1( 0 ),
+ m_gotoScreenUserParam2( 0 )
+{
+ for( unsigned int i = 0; i < sizeof( m_windows ) /
+ sizeof( m_windows[ 0 ] ); i++ )
+ {
+ m_windows[ i ] = NULL;
+ }
+
+ for( unsigned int j = 0; j < sizeof( m_windowHistory ) /
+ sizeof( m_windowHistory[ 0 ] ); j++ )
+ {
+ m_windowHistory[ j ] = CGuiWindow::GUI_WINDOW_ID_UNDEFINED;
+ }
+ //Load the mouse cursor.
+#ifdef RAD_WIN32
+ tDrawable* pMouseCursor = p3d::find<tDrawable>("mouse_cursor.png");
+ GetInputManager()->GetFEMouse()->InitMouseCursor( pMouseCursor );
+#endif
+}
+
+
+//===========================================================================
+// CGuiManager::~CGuiManager
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiManager::~CGuiManager()
+{
+ // Remove all existing screens.
+ //
+ this->RemoveAllWindows();
+}
+
+
+//===========================================================================
+// CGuiManager::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiManager::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ switch( message )
+ {
+ case GUI_MSG_SET_GOTO_SCREEN_PARAMETERS:
+ {
+ m_gotoScreenUserParam1 = param1;
+ m_gotoScreenUserParam2 = param2;
+
+ break;
+ }
+
+ case GUI_MSG_GOTO_SCREEN:
+ {
+ CGuiWindow::eGuiWindowID nextScreen = static_cast<CGuiWindow::eGuiWindowID>( param1 );
+
+ if( this->FindWindowByID( nextScreen ) == NULL )
+ {
+ // ignore if screen not found
+ //
+ break;
+ }
+
+ if( (nextScreen == m_currentScreen) &&
+ (param2 & FORCE_WINDOW_RELOAD) == 0 )
+ {
+ if( m_nextScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED )
+ {
+ m_nextScreen = nextScreen;
+ }
+
+ // ignore if we are already on the requested screen,
+ // unless we're trying to force a screen reload
+ //
+ break;
+ }
+
+ m_nextScreen = nextScreen;
+
+ rDebugPrintf( "GUI GoTo Screen Request: (next screen ID = %d)\n", m_nextScreen );
+
+ // push current screen onto history stack, unless requested
+ // to keep existing history
+ //
+ if( (param2 & KEEP_WINDOW_HISTORY) == 0 )
+ {
+ this->PushScreenHistory( m_currentScreen );
+ }
+
+ // clear screen history, if requested
+ //
+ if( (param2 & CLEAR_WINDOW_HISTORY) > 0 )
+ {
+ this->ClearScreenHistory();
+ }
+
+ m_state = GUI_FE_CHANGING_SCREENS;
+
+ // Tell the current screen to shut down.
+ //
+ if( m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED )
+ {
+ this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT );
+ }
+
+ if( (param2 & FORCE_WINDOW_CHANGE_IMMEDIATE) > 0 )
+ {
+ m_currentScreen = m_nextScreen;
+
+ CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) );
+ rAssert( nextScreen != NULL );
+ m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this );
+ }
+
+ break;
+ }
+
+ case GUI_MSG_BACK_SCREEN:
+ {
+ CGuiWindow::eGuiWindowID nextScreen = CGuiWindow::GUI_WINDOW_ID_UNDEFINED;
+
+ // param1 = number of extra screens to go back
+ //
+ for( unsigned int numBackScreens = 0; numBackScreens < (param1 + 1); numBackScreens++ )
+ {
+ nextScreen = this->PopScreenHistory();
+ }
+
+ if( nextScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED )
+ {
+ m_nextScreen = nextScreen;
+
+ m_state = GUI_FE_CHANGING_SCREENS;
+
+ // Tell the current screen to shut down.
+ //
+ rAssert( m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED );
+ this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT );
+ }
+
+ break;
+ }
+
+ case GUI_MSG_MEMCARD_CHECK_COMPLETED:
+ {
+ s_memcardCheckState = MEM_CARD_CHECK_COMPLETED;
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiManager::OnGotoScreenComplete
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiManager::OnGotoScreenComplete()
+{
+ m_state = GUI_FE_SCREEN_RUNNING;
+
+ rAssert( CGuiWindow::GUI_WINDOW_ID_UNDEFINED != m_nextScreen );
+
+ m_currentScreen = m_nextScreen;
+
+ this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_ENTER,
+ m_gotoScreenUserParam1,
+ m_gotoScreenUserParam2 );
+
+ // reset goto screen user parameters
+ //
+ m_gotoScreenUserParam1 = 0;
+ m_gotoScreenUserParam2 = 0;
+}
+
+
+//===========================================================================
+// CGuiManager::FindWindowByID
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters:
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiWindow* CGuiManager::FindWindowByID
+(
+ CGuiWindow::eGuiWindowID id
+)
+{
+/*
+ for( int i = 0; i < m_windows.mSize; ++i )
+ {
+ if( m_windows[i]->GetWindowID() == id )
+ {
+ return( m_windows[i] );
+ }
+ }
+*/
+ CGuiWindow* window = NULL;
+
+ if( this->IsValidWindowID( id ) )
+ {
+ window = m_windows[ id ];
+ }
+
+ return window;
+}
+
+//===========================================================================
+// CGuiManager::GetCurrentWindow
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters:
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiWindow* CGuiManager::GetCurrentWindow()
+{
+ return FindWindowByID( m_currentScreen );
+}
+
+
+//===========================================================================
+// CGuiManager::DisplayMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters:
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiManager::DisplayMessage
+(
+ int messageIndex,
+ CGuiEntity* pCallback
+)
+{
+ CGuiScreenMessage::Display( messageIndex, pCallback );
+
+ this->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_GENERIC_MESSAGE,
+ KEEP_WINDOW_HISTORY | FORCE_WINDOW_RELOAD );
+}
+
+
+//===========================================================================
+// CGuiManager::DisplayPrompt
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters:
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiManager::DisplayPrompt
+(
+ int messageIndex,
+ CGuiEntity* pCallback,
+ eGenericPromptType promptType,
+ bool enableDefaultToNo
+)
+{
+ switch( promptType )
+ {
+ case PROMPT_TYPE_YES_NO:
+ {
+ CGuiMenuPrompt::ePromptResponse responses[] =
+ {
+ CGuiMenuPrompt::RESPONSE_YES,
+ CGuiMenuPrompt::RESPONSE_NO
+ };
+
+ CGuiScreenPrompt::Display( messageIndex, pCallback, 2, responses );
+ CGuiScreenPrompt::EnableDefaultToNo( enableDefaultToNo );
+
+ break;
+ }
+ case PROMPT_TYPE_CONTINUE:
+ {
+ CGuiMenuPrompt::ePromptResponse responses[] =
+ {
+ CGuiMenuPrompt::RESPONSE_CONTINUE
+ };
+
+ CGuiScreenPrompt::Display( messageIndex, pCallback, 1, responses );
+
+ break;
+ }
+ case PROMPT_TYPE_OK:
+ {
+ CGuiMenuPrompt::ePromptResponse responses[] =
+ {
+ CGuiMenuPrompt::RESPONSE_OK
+ };
+
+ CGuiScreenPrompt::Display( messageIndex, pCallback, 1, responses );
+
+ break;
+ }
+ case PROMPT_TYPE_DELETE:
+ {
+ CGuiMenuPrompt::ePromptResponse responses[] =
+ {
+ CGuiMenuPrompt::RESPONSE_DELETE
+ };
+
+ CGuiScreenPrompt::Display( messageIndex, pCallback, 1, responses );
+
+ break;
+ }
+ case PROMPT_TYPE_LOAD:
+ {
+ CGuiMenuPrompt::ePromptResponse responses[] =
+ {
+ CGuiMenuPrompt::RESPONSE_LOAD
+ };
+
+ CGuiScreenPrompt::Display( messageIndex, pCallback, 1, responses );
+
+ break;
+ }
+ case PROMPT_TYPE_SAVE:
+ {
+ CGuiMenuPrompt::ePromptResponse responses[] =
+ {
+ CGuiMenuPrompt::RESPONSE_SAVE
+ };
+
+ CGuiScreenPrompt::Display( messageIndex, pCallback, 1, responses );
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( 0, "*** ERROR: Invalid prompt type!" );
+
+ break;
+ }
+ }
+
+ this->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT,
+ KEEP_WINDOW_HISTORY | FORCE_WINDOW_RELOAD );
+}
+
+
+//===========================================================================
+// CGuiManager::DisplayErrorPrompt
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters:
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiManager::DisplayErrorPrompt
+(
+ int messageIndex,
+ CGuiEntity* pCallback,
+ int promptResponses
+)
+{
+ int numResponses = 0;
+ CGuiMenuPrompt::ePromptResponse responses[ CGuiMenuPrompt::MAX_NUM_RESPONSES ];
+
+
+ if( promptResponses & ERROR_RESPONSE_CONTINUE )
+ {
+ responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_CONTINUE;
+ }
+
+ if( promptResponses & ERROR_RESPONSE_CONTINUE_WITHOUT_SAVE )
+ {
+ responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_CONTINUE_WITHOUT_SAVE;
+ }
+
+ if( promptResponses & ERROR_RESPONSE_RETRY )
+ {
+ responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_RETRY;
+ }
+
+ if( promptResponses & ERROR_RESPONSE_DELETE )
+ {
+ responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_DELETE;
+ }
+
+ if( promptResponses & ERROR_RESPONSE_YES )
+ {
+ responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_YES;
+ }
+
+ if( promptResponses & ERROR_RESPONSE_NO )
+ {
+ responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_NO;
+ }
+
+ if( promptResponses & ERROR_RESPONSE_FORMAT )
+ {
+#ifdef RAD_XBOX
+ responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_FORMAT_XBOX;
+#endif
+#ifdef RAD_WIN32
+ responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_FORMAT_XBOX;
+#endif
+#ifdef RAD_GAMECUBE
+ responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_FORMAT_GC;
+#endif
+#ifdef RAD_PS2
+ responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_FORMAT_PS2;
+#endif
+ }
+
+ if( promptResponses & ERROR_RESPONSE_MANAGE )
+ {
+ responses[ numResponses++ ] = CGuiMenuPrompt::RESPONSE_MANAGE_MEMCARDS;
+ }
+
+ CGuiScreenPrompt::Display( messageIndex, pCallback, numResponses, responses );
+ CGuiScreenPrompt::EnableDefaultToNo( false );
+
+ this->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT,
+ KEEP_WINDOW_HISTORY | FORCE_WINDOW_RELOAD );
+}
+
+
+CGuiWindow::eGuiWindowID
+CGuiManager::GetPreviousScreen( int fromCurrentScreen ) const
+{
+ CGuiWindow::eGuiWindowID previousScreenID = CGuiWindow::GUI_WINDOW_ID_UNDEFINED;
+
+ int windowHistoryCount = m_windowHistoryCount - fromCurrentScreen;
+ if( windowHistoryCount > 0 )
+ {
+ previousScreenID = m_windowHistory[ windowHistoryCount - 1 ];
+ }
+
+ return previousScreenID;
+}
+
+CGuiWindow::eGuiWindowID CGuiManager::GetCurrentScreen() const
+{
+ return m_currentScreen;
+}
+
+//===========================================================================
+// Protected Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiManager::AddWindow
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiManager::AddWindow
+(
+ CGuiWindow::eGuiWindowID windowID,
+ CGuiWindow* pWindow
+)
+{
+ rAssert( this->IsValidWindowID( windowID ) && pWindow != NULL );
+
+ rAssert( m_windows[ windowID ] == NULL );
+ m_windows[ windowID ] = pWindow;
+
+ m_numWindows++;
+}
+
+void
+CGuiManager::RemoveWindow( CGuiWindow::eGuiWindowID windowID )
+{
+ rAssert( this->IsValidWindowID( windowID ) );
+
+ if( m_windows[ windowID ] != NULL )
+ {
+ delete m_windows[ windowID ];
+ m_windows[ windowID ] = NULL;
+
+ m_numWindows--;
+ }
+}
+
+void
+CGuiManager::RemoveAllWindows()
+{
+ for( int i = 0; i < CGuiWindow::NUM_GUI_WINDOW_IDS; i++ )
+ {
+ if( m_windows[ i ] != NULL )
+ {
+ delete m_windows[ i ];
+ m_windows[ i ] = NULL;
+ }
+ }
+
+ m_numWindows = 0;
+}
+
+void
+CGuiManager::PushScreenHistory( CGuiWindow::eGuiWindowID windowID )
+{
+ if( this->IsValidWindowID( windowID ) )
+ {
+ rAssert( m_windowHistoryCount < MAX_WINDOW_HISTORY );
+
+ m_windowHistory[ m_windowHistoryCount ] = windowID;
+ m_windowHistoryCount++;
+ }
+}
+
+CGuiWindow::eGuiWindowID
+CGuiManager::PopScreenHistory()
+{
+ CGuiWindow::eGuiWindowID windowID = CGuiWindow::GUI_WINDOW_ID_UNDEFINED;
+
+ if( m_windowHistoryCount > 0 )
+ {
+ m_windowHistoryCount--;
+
+ windowID = m_windowHistory[ m_windowHistoryCount ];
+ }
+
+ return windowID;
+}
+
+//===========================================================================
+// Private Member Functions
+//===========================================================================
+
diff --git a/game/code/presentation/gui/guimanager.h b/game/code/presentation/gui/guimanager.h
new file mode 100644
index 0000000..6e21afa
--- /dev/null
+++ b/game/code/presentation/gui/guimanager.h
@@ -0,0 +1,207 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiManager
+//
+// Description: Interface for the CGuiManager class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/09/20 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef GUIMANAGER_H
+#define GUIMANAGER_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guientity.h>
+#include <presentation/gui/guiwindow.h>
+#include <events/eventlistener.h>
+#include <project.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+struct IGuiLoadingCallback;
+
+//===========================================================================
+// Constants
+//===========================================================================
+
+const int MAX_WINDOW_HISTORY = 8;
+
+enum eWindowCommand
+{
+ CLEAR_WINDOW_HISTORY = 1,
+ KEEP_WINDOW_HISTORY = 2,
+ FORCE_WINDOW_CHANGE_IMMEDIATE = 4,
+ FORCE_WINDOW_RELOAD = 8,
+
+ NUM_WINDOW_COMMANDS
+};
+
+enum eGenericPromptType
+{
+ PROMPT_TYPE_YES_NO,
+ PROMPT_TYPE_CONTINUE,
+ PROMPT_TYPE_OK,
+ PROMPT_TYPE_DELETE,
+ PROMPT_TYPE_LOAD,
+ PROMPT_TYPE_SAVE,
+
+ NUM_GENERIC_PROMPT_TYPES
+};
+
+enum eErrorPromptResponse
+{
+ ERROR_RESPONSE_NONE = 0,
+
+ ERROR_RESPONSE_CONTINUE = 1,
+ ERROR_RESPONSE_RETRY = 2,
+ ERROR_RESPONSE_YES = 4,
+ ERROR_RESPONSE_NO = 8,
+ ERROR_RESPONSE_FORMAT = 16,
+ ERROR_RESPONSE_MANAGE = 32,
+ ERROR_RESPONSE_CONTINUE_WITHOUT_SAVE = 64,
+ ERROR_RESPONSE_DELETE = 128,
+ ERROR_RESPONSE_ALL = ~0
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiManager : public CGuiEntity,
+ public Scrooby::GotoScreenCallback,
+ public EventListener
+{
+ public:
+
+ CGuiManager( Scrooby::Project* pProject,
+ CGuiEntity* pParent );
+
+ virtual ~CGuiManager();
+
+ virtual void Populate() = 0;
+ virtual void Start( CGuiWindow::eGuiWindowID initialWindow = CGuiWindow::GUI_WINDOW_ID_UNDEFINED ) = 0;
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ Scrooby::Project* GetScroobyProject() const { return m_pScroobyProject; }
+
+ virtual void OnGotoScreenComplete();
+
+ CGuiWindow* FindWindowByID( CGuiWindow::eGuiWindowID id );
+
+ CGuiWindow* GetCurrentWindow();
+
+ void DisplayMessage( int messageIndex,
+ CGuiEntity* pCallback = NULL );
+
+ void DisplayPrompt( int messageIndex,
+ CGuiEntity* pCallback,
+ eGenericPromptType promptType = PROMPT_TYPE_YES_NO,
+ bool enableDefaultToNo = true );
+
+ void DisplayErrorPrompt( int messageIndex,
+ CGuiEntity* pCallback,
+ int promptResponses = ERROR_RESPONSE_NONE );
+
+ CGuiWindow::eGuiWindowID GetPreviousScreen( int fromCurrentScreen = 0 ) const;
+ CGuiWindow::eGuiWindowID GetCurrentScreen() const;
+
+ // Implements EventListener
+ virtual void HandleEvent( EventEnum id, void* pEventData ) {};
+
+ enum eMemoryCardCheckingState
+ {
+ MEM_CARD_CHECK_NOT_DONE,
+ MEM_CARD_CHECK_IN_PROGRESS,
+ MEM_CARD_CHECK_COMPLETED,
+
+ NUM_MEM_CARD_CHECK_STATES
+ };
+
+ static eMemoryCardCheckingState s_memcardCheckState;
+
+ protected:
+
+ //---------------------------------------------------------------------
+ // Protected Functions
+ //---------------------------------------------------------------------
+
+ void AddWindow( CGuiWindow::eGuiWindowID windowID, CGuiWindow* pWindow );
+ void RemoveWindow( CGuiWindow::eGuiWindowID windowID );
+ void RemoveAllWindows();
+
+ void PushScreenHistory( CGuiWindow::eGuiWindowID windowID );
+ CGuiWindow::eGuiWindowID PopScreenHistory();
+ void ClearScreenHistory();
+
+ //---------------------------------------------------------------------
+ // Protected Data
+ //---------------------------------------------------------------------
+
+ CGuiWindow* m_windows[ CGuiWindow::NUM_GUI_WINDOW_IDS ];
+ int m_numWindows;
+
+ Scrooby::Project* m_pScroobyProject;
+
+ CGuiWindow::eGuiWindowID m_currentScreen;
+ CGuiWindow::eGuiWindowID m_nextScreen;
+
+ enum eGuiFrontEndState
+ {
+ GUI_FE_UNINITIALIZED,
+ GUI_FE_SCREEN_RUNNING,
+ GUI_FE_CHANGING_SCREENS,
+ GUI_FE_DYNAMIC_LOADING,
+ GUI_FE_SHUTTING_DOWN,
+ GUI_FE_TERMINATED
+ };
+
+ eGuiFrontEndState m_state;
+
+ private:
+
+ //---------------------------------------------------------------------
+ // Private Functions
+ //---------------------------------------------------------------------
+
+ // No copying or assignment. Declare but don't define.
+ //
+ CGuiManager( const CGuiManager& );
+ CGuiManager& operator= ( const CGuiManager& );
+
+ bool IsValidWindowID( CGuiWindow::eGuiWindowID windowID ) const;
+
+ //---------------------------------------------------------------------
+ // Private Data
+ //---------------------------------------------------------------------
+ CGuiWindow::eGuiWindowID m_windowHistory[ MAX_WINDOW_HISTORY ];
+ int m_windowHistoryCount;
+
+ unsigned int m_gotoScreenUserParam1;
+ unsigned int m_gotoScreenUserParam2;
+};
+
+inline void
+CGuiManager::ClearScreenHistory()
+{
+ m_windowHistoryCount = 0;
+}
+
+inline bool
+CGuiManager::IsValidWindowID( CGuiWindow::eGuiWindowID windowID ) const
+{
+ return (windowID >= 0 && windowID < CGuiWindow::NUM_GUI_WINDOW_IDS);
+}
+
+#endif // GUIMANAGER_H
diff --git a/game/code/presentation/gui/guimenu.cpp b/game/code/presentation/gui/guimenu.cpp
new file mode 100644
index 0000000..5c52b35
--- /dev/null
+++ b/game/code/presentation/gui/guimenu.cpp
@@ -0,0 +1,1367 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiMenu
+//
+// Description: Implementation of the CGuiMenu class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/12/4 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guiscreen.h>
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/guiuserinputhandler.h>
+#include <presentation/gui/utility/specialfx.h>
+
+#include <input/inputmanager.h>
+#include <memory/srrmemory.h>
+#include <events/eventmanager.h>
+
+#include <raddebug.hpp> // Foundation
+#include <radmath/trig.hpp> // RadMath
+
+// Scrooby
+//
+#include <group.h>
+#include <page.h>
+#include <sprite.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+const tColour DEFAULT_SELECTED_ITEM_COLOUR( 255, 255, 0 );
+const tColour DEFAULT_DISABLED_ITEM_COLOUR( 128, 128, 128 ); // the same as in guiscreenmemorycard.cpp
+
+const tColour DEFAULT_OUTLINE_COLOUR( 0, 0, 0, 192 );
+
+const float SLIDER_FULL_RANGE_TIME = 2000; // in milliseconds
+const int SELECTION_MADE_DURATION = 250; // in milliseconds
+
+#ifdef RAD_WIN32
+const float ARROW_SCALE = 0.5f;
+#endif
+
+//===========================================================================
+// Public Member Functions - CGuiMenu
+//===========================================================================
+
+//===========================================================================
+// CGuiMenu::CGuiMenu
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiMenu::CGuiMenu( CGuiEntity* pParent, int maxNumItems,
+ eMenuType menuType,
+ int specialEffects )
+: CGuiEntity( pParent ),
+ m_menuType( menuType ),
+ m_specialEffects( static_cast<short>( specialEffects ) ),
+ m_menuItems( NULL ),
+ m_numItems( 0 ),
+ m_selection( NO_SELECTION ),
+ m_pCursor( NULL ),
+ m_isSelectionMade( false ),
+ m_isHighlightEnabled( true ),
+ m_highlightColour( DEFAULT_SELECTED_ITEM_COLOUR ),
+ m_selectionMadeOutlineColour( tColour( 255, 0, 0, 192 ) ),
+ m_isGreyOutEnabled( true ),
+ m_elapsedTime( 0 ),
+ m_selectionMadeElapsedTime( 0 ),
+#ifdef RAD_WIN32
+ m_bIsSelectionOutlined( false ),
+ m_selectionOutlineColour( tColour( 0, 0, 255, 192 ) ),
+#endif
+ m_controllerID( -1 )
+{
+MEMTRACK_PUSH_GROUP( "GUIMenu" );
+ rAssertMsg( ( specialEffects & 0xFFFF0000 ) == 0, "Bitmask Overflow!" );
+
+ // create array of 'maxNumItems' menu items
+ //
+ rAssert( maxNumItems > 0 );
+ m_menuItems = new GuiMenuItem*[ maxNumItems ];
+ rAssert( m_menuItems != NULL );
+
+ for( int i = 0; i < maxNumItems; i++ )
+ {
+ m_menuItems[ i ] = NULL;
+ }
+MEMTRACK_POP_GROUP( "GUIMenu" );
+}
+
+//===========================================================================
+// CGuiMenu::~CGuiMenu
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiMenu::~CGuiMenu()
+{
+ if( m_menuItems != NULL )
+ {
+ for( int i = 0; i < m_numItems; i++ )
+ {
+ if( m_menuItems[ i ] != NULL )
+ {
+ delete m_menuItems[ i ];
+ m_menuItems[ i ] = NULL;
+ }
+ }
+
+ delete [] m_menuItems;
+ m_menuItems = NULL;
+ }
+}
+
+//===========================================================================
+// CGuiMenu::HandleMessage
+//===========================================================================
+// Description: Message handler for this class.
+//
+// Constraints: None.
+//
+// Parameters:
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiMenu::HandleMessage( eGuiMessage message, unsigned int param1,
+ unsigned int param2 )
+{
+ if( m_isSelectionMade && this->IsControllerMessage( message ) )
+ {
+ // selection has already been made, ignore all controller messages
+ //
+ return;
+ }
+
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ if( m_selection != NO_SELECTION )
+ {
+ this->UpdateCurrentSelection( param1 );
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_UP:
+ {
+ this->ChangeSelection( -1 );
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_DOWN:
+ {
+ this->ChangeSelection( +1 );
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_LEFT:
+ {
+ this->DecrementSelectionValue();
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_RIGHT:
+ {
+ this->IncrementSelectionValue();
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ this->MakeSelection();
+
+ break;
+ }
+#ifdef RAD_WIN32
+ case GUI_MSG_MOUSE_OVER:
+ {
+ this->SetNewSelection(param1);
+
+ break;
+ }
+ case GUI_MSG_MOUSE_LCLICKHOLD:
+ {
+ this->OutlineSelection( (param1!=0) );
+ break;
+ }
+#endif
+ default:
+ {
+ break;
+ }
+ }
+}
+
+//===========================================================================
+// CGuiMenu::AddMenuItem
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters:
+//
+// Return: N/A.
+//
+//===========================================================================
+GuiMenuItem* CGuiMenu::AddMenuItem( Scrooby::BoundedDrawable* pItem,
+ Scrooby::BoundedDrawable* pItemValue,
+ Scrooby::Polygon* pSlider,
+ Scrooby::Sprite* pSliderImage,
+ Scrooby::Sprite* pItemValueArrowL,
+ Scrooby::Sprite* pItemValueArrowR,
+ int attributes )
+{
+ rAssert( m_menuItems[ m_numItems ] == NULL );
+
+ // create a new menu item based on menu type
+ //
+ switch( m_menuType )
+ {
+ case GUI_TEXT_MENU:
+ {
+ m_menuItems[ m_numItems ] = new GuiMenuItemText;
+
+ break;
+ }
+ case GUI_SPRITE_MENU:
+ {
+ m_menuItems[ m_numItems ] = new GuiMenuItemSprite;
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Invalid menu type!" );
+
+ break;
+ }
+ }
+
+ rAssert( m_menuItems[ m_numItems ] != NULL );
+
+ GuiMenuItem* pMenuItem = m_menuItems[ m_numItems ];
+
+ m_menuItems[ m_numItems ]->SetItem( pItem );
+
+ // for items w/ value toggle
+ //
+ if( pItemValue != NULL )
+ {
+ m_menuItems[ m_numItems ]->SetItemValue( pItemValue );
+
+ // hide arrows by default, if exists
+ //
+ if( pItemValueArrowL != NULL )
+ {
+ pItemValueArrowL->SetVisible( false );
+#ifdef RAD_WIN32
+ pItemValueArrowL->ScaleAboutCenter( ARROW_SCALE );
+#endif
+ m_menuItems[ m_numItems ]->m_itemValueArrowL = pItemValueArrowL;
+ }
+ if( pItemValueArrowR != NULL )
+ {
+ pItemValueArrowR->SetVisible( false );
+#ifdef RAD_WIN32
+ pItemValueArrowR->ScaleAboutCenter( ARROW_SCALE );
+#endif
+ m_menuItems[ m_numItems ]->m_itemValueArrowR = pItemValueArrowR;
+ }
+ }
+
+ if( m_menuType == GUI_TEXT_MENU )
+ {
+ if( (attributes & TEXT_OUTLINE_ENABLED) > 0 )
+ {
+ // turn on text outlining
+ //
+ m_menuItems[ m_numItems ]->SetDisplayOutline( true );
+ }
+#ifdef RAD_WIN32
+ pItem->SetVerticalJustification( Scrooby::Top );
+#endif
+ }
+
+ // for items w/ sliders
+ //
+ if( pSliderImage != NULL )
+ {
+ m_menuItems[ m_numItems ]->m_slider.SetScroobyImage( pSliderImage );
+ }
+
+ m_menuItems[ m_numItems ]->m_attributes = attributes;
+ m_menuItems[ m_numItems ]->m_defaultColour = pItem->GetColour();
+ m_numItems++;
+
+ // select first item by default
+ //
+ if( m_numItems == 1 )
+ {
+ SelectItem( 0 );
+ }
+ return pMenuItem;
+}
+
+//===========================================================================
+// CGuiMenu::SetMenuItemEnabled
+//===========================================================================
+// Description: Enable/disable menu item.
+//
+// Constraints: None.
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+void CGuiMenu::SetMenuItemEnabled( int index, bool enabled, bool changeVisibility )
+{
+ GuiMenuItem* currentMenuItem = this->GetMenuItem( index );
+ rAssert( currentMenuItem != NULL );
+
+ Scrooby::BoundedDrawable* currentItem = currentMenuItem->GetItem();
+ rAssert( currentItem != NULL );
+
+ Scrooby::BoundedDrawable* currentItemValue = currentMenuItem->GetItemValue();
+
+ if( enabled )
+ {
+ currentMenuItem->m_attributes |= SELECTION_ENABLED;
+
+ if( index != m_selection )
+ {
+ if( m_isGreyOutEnabled )
+ {
+ // restore default item colour
+ //
+ currentItem->SetColour( currentMenuItem->m_defaultColour );
+ if( currentItemValue != NULL )
+ {
+ currentItemValue->SetColour( currentMenuItem->m_defaultColour );
+ }
+ }
+
+ // show cursor
+ //
+ if( m_pCursor != NULL )
+ {
+ m_pCursor->SetVisible( true );
+ }
+
+ if( m_selection == NO_SELECTION )
+ {
+ m_selection = 0;
+ this->SelectItem( index );
+ }
+ }
+ }
+ else // !enabled
+ {
+ currentMenuItem->m_attributes &= ~SELECTION_ENABLED;
+
+ // if item disabled is current selection, select next enabled item
+ //
+ if( index == m_selection )
+ {
+ this->ChangeSelection( +1, false );
+
+ if( index == m_selection )
+ {
+ // reset cursor to first selection, and hide it
+ //
+ this->MoveCursor( m_selection, 0 );
+ if( m_pCursor != NULL )
+ {
+ m_pCursor->SetVisible( false );
+ }
+
+ // this means all selections have been disabled
+ //
+ m_selection = NO_SELECTION;
+ }
+ }
+
+ if( m_isGreyOutEnabled )
+ {
+ // grey out item colour
+ //
+ currentItem->SetColour( DEFAULT_DISABLED_ITEM_COLOUR );
+
+ if( currentItemValue != NULL )
+ {
+ currentItemValue->SetColour( DEFAULT_DISABLED_ITEM_COLOUR );
+ }
+ }
+ }
+
+ if( changeVisibility )
+ {
+ currentItem->SetVisible( enabled );
+
+ if( currentItemValue != NULL )
+ {
+ currentItemValue->SetVisible( enabled );
+ }
+ }
+}
+
+bool CGuiMenu::IsMenuItemEnabled( int index )
+{
+ GuiMenuItem* currentMenuItem = this->GetMenuItem( index );
+ rAssert( currentMenuItem != NULL );
+ return (currentMenuItem->m_attributes & SELECTION_ENABLED);
+}
+
+//===========================================================================
+// CGuiMenu::Reset
+//===========================================================================
+// Description: Unselect all menu items.
+//
+// Constraints: None.
+//
+// Parameters: N/A.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiMenu::Reset( int defaultSelection )
+{
+ // un-select current item
+ if( m_selection != NO_SELECTION )
+ {
+ this->UnselectItem( m_selection );
+ }
+
+ // select first item
+ this->SelectItem( defaultSelection );
+}
+
+//===========================================================================
+// CGuiMenu::SetHighlightColour
+//===========================================================================
+// Description: Sets the menu highlight colour.
+//
+// Constraints: None.
+//
+// Parameters: N/A.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiMenu::SetHighlightColour( bool isEnabled, tColour colour )
+{
+ m_isHighlightEnabled = isEnabled;
+ m_highlightColour = colour;
+}
+
+//===========================================================================
+// CGuiMenu::SetSelectionValue
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: N/A.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiMenu::SetSelectionValue( int index, int value )
+{
+ if( value >= 0 && value < m_menuItems[ index ]->m_itemValueCount )
+ {
+ m_menuItems[ index ]->SetItemValueIndex( value );
+
+ // Notify screen that selection value has changed
+ m_pParent->HandleMessage( GUI_MSG_MENU_SELECTION_VALUE_CHANGED, index, value );
+ }
+}
+
+//===========================================================================
+// CGuiMenu::SetSelectionValueCount
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: N/A.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiMenu::SetSelectionValueCount( int index, int count )
+{
+ m_menuItems[ index ]->m_itemValueCount = count;
+
+// if( index == m_selection )
+ {
+ // show arrows if more than one value to toggle; otherwise, hide them (partially)
+ //
+ bool showArrows = (m_menuItems[ index ]->m_itemValueCount > 1);
+ if( m_menuItems[ index ]->m_itemValueArrowL != NULL &&
+ m_menuItems[ index ]->m_itemValueArrowR != NULL )
+ {
+ m_menuItems[ index ]->m_itemValueArrowL->SetAlpha( showArrows ? 1.0f : 0.4f );
+ m_menuItems[ index ]->m_itemValueArrowR->SetAlpha( showArrows ? 1.0f : 0.4f );
+ }
+ }
+}
+
+//===========================================================================
+// CGuiMenu::MakeSelection
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: N/A.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiMenu::MakeSelection( bool isSelectionMade )
+{
+ if (m_selection == NO_SELECTION) return;//------------->
+
+ if( (m_menuItems[ m_selection ]->m_attributes & SELECTABLE) > 0 )
+ {
+ if( isSelectionMade )
+ {
+ if( m_selection != NO_SELECTION )
+ {
+ if( m_menuType == GUI_TEXT_MENU )
+ {
+ m_menuItems[ m_selection ]->SetOutlineColour( m_selectionMadeOutlineColour );
+#ifdef RAD_WIN32
+ if( m_bIsSelectionOutlined )
+ m_menuItems[ m_selection ]->GetItem()->SetColour( DEFAULT_SELECTED_ITEM_COLOUR );
+#endif
+ }
+
+ m_selectionMadeElapsedTime = 0;
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT );
+
+ // tell parent screen to ignore all controller inputs until
+ // selection-made effect is completed
+ //
+ CGuiScreen* parentScreen = static_cast<CGuiScreen*>( m_pParent );
+ rAssert( parentScreen );
+ parentScreen->SetIngoreControllerInputs( true );
+
+ m_isSelectionMade = true;
+ }
+ }
+ else
+ {
+ CGuiScreen* parentScreen = static_cast<CGuiScreen*>( m_pParent );
+ rAssert( parentScreen );
+ parentScreen->SetIngoreControllerInputs( false );
+
+ if( m_menuType == GUI_TEXT_MENU )
+ {
+ m_menuItems[ m_selection ]->SetOutlineColour( DEFAULT_OUTLINE_COLOUR );
+ }
+
+ // restore current item's regular L/R arrows, if exist
+ //
+ if( m_menuItems[ m_selection ]->m_itemValueArrowL != NULL &&
+ m_menuItems[ m_selection ]->m_itemValueArrowR != NULL )
+ {
+ m_menuItems[ m_selection ]->m_itemValueArrowL->SetIndex( 0 );
+ m_menuItems[ m_selection ]->m_itemValueArrowR->SetIndex( 0 );
+ }
+
+ m_pParent->HandleMessage( GUI_MSG_MENU_SELECTION_MADE, m_selection );
+
+ m_isSelectionMade = false;
+ }
+ }
+}
+
+//===========================================================================
+// Protected Member Functions - CGuiMenu
+//===========================================================================
+
+//===========================================================================
+// CGuiMenu::SelectItem
+//===========================================================================
+// Description: Select specified item.
+//
+// Constraints: None.
+//
+// Parameters: N/A.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiMenu::SelectItem( int index )
+{
+ rAssert( index >= 0 && index < m_numItems );
+ rAssert( m_menuItems[ index ] != NULL );
+
+ // move cursor
+ if( index != m_selection )
+ {
+ this->MoveCursor( m_selection, index );
+ }
+
+ // reset elapsed time
+ m_elapsedTime = 0;
+
+ if( m_isHighlightEnabled && m_menuType == GUI_TEXT_MENU )
+ {
+ m_menuItems[ index ]->GetItem()->SetColour( m_highlightColour );
+ }
+
+ // apply to item value also, if exists
+ if( m_menuItems[ index ]->GetItemValue() != NULL )
+ {
+ if( m_isHighlightEnabled && m_menuType == GUI_TEXT_MENU )
+ {
+ m_menuItems[ index ]->GetItemValue()->SetColour( m_highlightColour );
+ }
+
+ // show arrows, if exists
+ //
+ if( m_menuItems[ index ]->m_itemValueArrowL != NULL &&
+ m_menuItems[ index ]->m_itemValueArrowR != NULL )
+ {
+ m_menuItems[ index ]->m_itemValueArrowL->SetVisible( true );
+ m_menuItems[ index ]->m_itemValueArrowR->SetVisible( true );
+ }
+ }
+/*
+ if( m_specialEffects & MENU_SFX_DROP_SHADOW )
+ {
+ // turn on drop shadow
+ m_menuItems[ index ]->m_item->SetDisplayShadow( true );
+
+ // apply to item value also, if exists
+ if( m_menuItems[ index ]->m_itemValue != NULL )
+ {
+ m_menuItems[ index ]->m_itemValue->SetDisplayShadow( true );
+ }
+ }
+*/
+ m_selection = index;
+}
+
+//===========================================================================
+// CGuiMenu::UnselectItem
+//===========================================================================
+// Description: Unselect specified item.
+//
+// Constraints: None.
+//
+// Parameters: N/A.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiMenu::UnselectItem( int index )
+{
+ rAssert( index >= 0 && index < m_numItems );
+ rAssert( m_menuItems[ index ] != NULL );
+
+ if( m_menuType == GUI_TEXT_MENU )
+ {
+ m_menuItems[ index ]->GetItem()->SetColour( m_menuItems[ index ]->m_defaultColour );
+ }
+
+ // apply to item value also, if exists
+ if( m_menuItems[ index ]->GetItemValue() != NULL )
+ {
+ if( m_menuType == GUI_TEXT_MENU )
+ {
+ m_menuItems[ index ]->GetItemValue()->SetColour( m_menuItems[ index ]->m_defaultColour );
+ }
+
+ // hide arrows until item is selected
+ //
+ if( m_menuItems[ index ]->m_itemValueArrowL != NULL &&
+ m_menuItems[ index ]->m_itemValueArrowR != NULL )
+ {
+ m_menuItems[ index ]->m_itemValueArrowL->SetVisible( false );
+ m_menuItems[ index ]->m_itemValueArrowR->SetVisible( false );
+ }
+ }
+
+ if( m_specialEffects & MENU_SFX_SIZE_PULSE )
+ {
+ // reset scale
+ m_menuItems[ index ]->GetItem()->ResetTransformation();
+
+ // apply to item value also, if exists
+ if( m_menuItems[ index ]->GetItemValue() != NULL )
+ {
+ m_menuItems[ index ]->GetItemValue()->ResetTransformation();
+ }
+ }
+/*
+ if( m_specialEffects & MENU_SFX_DROP_SHADOW )
+ {
+ // turn off drop shadow
+ m_menuItems[ index ]->m_item->SetDisplayShadow( false );
+
+ // apply to item value also, if exists
+ if( m_menuItems[ index ]->m_itemValue != NULL )
+ {
+ m_menuItems[ index ]->m_itemValue->SetDisplayShadow( false );
+ }
+ }
+*/
+}
+
+//===========================================================================
+// CGuiMenu::ChangeSelection
+//===========================================================================
+// Description: Select the next menu item.
+//
+// Constraints: None.
+//
+// Parameters: N/A.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiMenu::ChangeSelection( int deltaItems, bool isUserInput )
+{
+ if( m_selection != NO_SELECTION )
+ {
+ rAssert( m_numItems > 0 );
+
+ // Increment and check for wrap around.
+ //
+ int newSelection = (m_selection + deltaItems + m_numItems) % m_numItems;
+
+ // Skip to next enabled selection if new selection is disabled
+ while( newSelection != m_selection )
+ {
+ if( m_menuItems[ newSelection ]->m_attributes & SELECTION_ENABLED )
+ {
+ // Unselect the current item.
+ //
+ this->UnselectItem( m_selection );
+
+ // Notify screen that menu selection has changed
+ // (param1 = new selection, param2 = old selection)
+ //
+ m_pParent->HandleMessage( GUI_MSG_MENU_SELECTION_CHANGED, newSelection, m_selection );
+
+ // Make the new selection.
+ //
+ this->SelectItem( newSelection );
+
+ if( isUserInput )
+ {
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ }
+
+ break;
+ }
+
+ newSelection = (newSelection + deltaItems + m_numItems) % m_numItems;
+ }
+ }
+}
+
+#ifdef RAD_WIN32
+//===========================================================================
+// CGuiMenu::ChangeSelection
+//===========================================================================
+// Description: Select a specific selection.
+//
+// Constraints: None.
+//
+// Parameters: N/A.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiMenu::SetNewSelection( int newSelection, bool isUserInput )
+{
+ if( m_selection != NO_SELECTION )
+ {
+ rAssert( m_numItems > 0 );
+
+ if( newSelection != m_selection )
+ {
+ if( m_menuItems[ newSelection ]->m_attributes & SELECTION_ENABLED )
+ {
+ // Unselect the current item.
+ //
+ this->UnselectItem( m_selection );
+
+ // Notify screen that menu selection has changed
+ // (param1 = new selection, param2 = old selection)
+ //
+ m_pParent->HandleMessage( GUI_MSG_MENU_SELECTION_CHANGED, newSelection, m_selection );
+
+ // Make the new selection.
+ //
+ this->SelectItem( newSelection );
+
+ if( isUserInput )
+ {
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ }
+ }
+ }
+ }
+}
+//===========================================================================
+// CGuiMenu::OutlineSelection
+//===========================================================================
+// Description: Outlines a specific selection.
+//
+// Constraints: None.
+//
+// Parameters: N/A.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiMenu::OutlineSelection( bool bOutline )
+{
+ if (m_selection == NO_SELECTION) return;//------------->
+
+ if( (m_menuItems[ m_selection ]->m_attributes & SELECTABLE) > 0 )
+ {
+ if( m_menuType == GUI_TEXT_MENU )
+ {
+ if( bOutline )
+ m_menuItems[ m_selection ]->GetItem()->SetColour( m_selectionOutlineColour );
+ else
+ m_menuItems[ m_selection ]->GetItem()->SetColour( DEFAULT_SELECTED_ITEM_COLOUR );
+
+ m_bIsSelectionOutlined = bOutline;
+ }
+ }
+}
+
+#endif
+
+//===========================================================================
+// CGuiMenu::IncrementSelectionValue
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: N/A.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiMenu::IncrementSelectionValue( bool isUserInput )
+{
+ if( m_selection != NO_SELECTION &&
+ m_menuItems[ m_selection ]->GetItemValue() != NULL )
+ {
+ int currentIndex = m_menuItems[ m_selection ]->GetItemValueIndex();
+ int newIndex = currentIndex;
+
+ if( currentIndex < m_menuItems[ m_selection ]->m_itemValueCount - 1 )
+ {
+ newIndex = currentIndex + 1;
+ }
+ else if( m_menuItems[ m_selection ]->m_attributes & VALUES_WRAPPED )
+ {
+ // wrap around to beginning
+ newIndex = 0;
+ }
+
+ if( newIndex != currentIndex )
+ {
+ m_menuItems[ m_selection ]->SetItemValueIndex( newIndex );
+
+ // Notify screen that selection value has changed
+ m_pParent->HandleMessage( GUI_MSG_MENU_SELECTION_VALUE_CHANGED, m_selection, newIndex );
+
+ if( isUserInput )
+ {
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ }
+ }
+ }
+}
+
+//===========================================================================
+// CGuiMenu::DecrementSelectionValue
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: N/A.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiMenu::DecrementSelectionValue( bool isUserInput )
+{
+ if( m_selection != NO_SELECTION &&
+ m_menuItems[ m_selection ]->GetItemValue() != NULL )
+ {
+ int currentIndex = m_menuItems[ m_selection ]->GetItemValueIndex();
+ int newIndex = currentIndex;
+
+ if( currentIndex > 0 )
+ {
+ newIndex = currentIndex - 1;
+ }
+ else if( m_menuItems[ m_selection ]->m_attributes & VALUES_WRAPPED )
+ {
+ // wrap around to end
+ newIndex = m_menuItems[ m_selection ]->m_itemValueCount - 1;
+ }
+
+ if( newIndex != currentIndex )
+ {
+ rAssertMsg( newIndex != -1, "This means item value count is zero!" );
+
+ m_menuItems[ m_selection ]->SetItemValueIndex( newIndex );
+
+ // Notify screen that selection value has changed
+ m_pParent->HandleMessage( GUI_MSG_MENU_SELECTION_VALUE_CHANGED, m_selection, newIndex );
+
+ if( isUserInput )
+ {
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ }
+ }
+ }
+}
+
+//===========================================================================
+// Private Member Functions - CGuiMenu
+//===========================================================================
+
+//===========================================================================
+// CGuiMenu::UpdateCurrentSelection
+//===========================================================================
+// Description: Updates current selection.
+//
+// Constraints: None.
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+void CGuiMenu::UpdateCurrentSelection( int elapsedTime )
+{
+ rAssert( m_selection >= 0 && m_selection < m_numItems );
+
+ Scrooby::BoundedDrawable* currentItem = m_menuItems[ m_selection ]->GetItem();
+ rAssert( currentItem != NULL );
+
+ if( m_isSelectionMade ) // update "selection made" effect
+ {
+ m_selectionMadeElapsedTime += elapsedTime;
+
+ if( m_selectionMadeElapsedTime > SELECTION_MADE_DURATION )
+ {
+ this->MakeSelection( false );
+ }
+ }
+ else // update current selection
+ {
+ const unsigned int ITEM_PULSE_PERIOD = 600; // in milliseconds
+
+ if( m_specialEffects & MENU_SFX_COLOUR_PULSE )
+ {
+ // pulse text colour
+ //
+ tColour textColour;
+ GuiSFX::ModulateColour( &textColour,
+ (float)m_elapsedTime,
+ (float)ITEM_PULSE_PERIOD,
+ tColour( 255, 224, 32 ), // m_menuItems[ m_selection ]->m_defaultColour,
+ m_highlightColour );
+
+ currentItem->SetColour( textColour );
+ }
+
+ if( m_specialEffects & MENU_SFX_SIZE_PULSE )
+ {
+ // pulse text size
+ //
+ const float ITEM_SCALE_FACTOR = 0.10f;
+
+ currentItem->ResetTransformation();
+
+// if( m_elapsedTime < ITEM_PULSE_PERIOD )
+ {
+ // TC: [IMPROVE] Man, this looks ugly!
+ //
+ static const float THETA_OFFSET = -rmt::ASin( -0.5f ); // = -ASin( (1 - center) / amplitude )
+
+ float scale = GuiSFX::Pulse( (float)m_elapsedTime,
+ (float)ITEM_PULSE_PERIOD,
+ 1.0f + ITEM_SCALE_FACTOR / 2,
+ ITEM_SCALE_FACTOR,
+ THETA_OFFSET );
+
+ int width = 0;
+ int height = 0;
+ currentItem->GetBoundingBoxSize( width, height );
+
+ // scale text about (left center, right center, or middle center)
+ //
+ if( currentItem->GetHorizontalJustification() == Scrooby::Left )
+ {
+ currentItem->ScaleAboutPoint( scale, 0, height / 2 );
+ }
+ else if( currentItem->GetHorizontalJustification() == Scrooby::Right )
+ {
+ currentItem->ScaleAboutPoint( scale, width, height / 2 );
+ }
+ else
+ {
+ currentItem->ScaleAboutCenter( scale );
+ }
+ }
+ }
+
+ // update slider, if exists on current selection
+ //
+ ImageSlider* currentItemSlider = &(m_menuItems[ m_selection ]->m_slider);
+ if( currentItemSlider->m_pImage != NULL )
+ {
+ bool hasSliderValueChanged = false;
+
+ int numUserInputHandlers = GetGuiSystem()->GetNumUserInputHandlers();
+ for( int i = 0; i < numUserInputHandlers; i++ )
+ {
+ if( m_controllerID != -1 && m_controllerID != static_cast<short>( i ) )
+ {
+ // ignore other controller inputs
+ //
+ continue;
+ }
+
+ CGuiUserInputHandler* userInputHandler = GetGuiSystem()->GetUserInputHandler( i );
+ if( userInputHandler != NULL )
+ {
+#ifdef RAD_WIN32
+ if( userInputHandler->IsXAxisOnLeft() ||
+ GetInputManager()->GetFEMouse()->OnSliderHorizontalClickDrag() == MDIR_LEFT )
+#else
+ if( userInputHandler->IsButtonDown( GuiInput::Left ) ||
+ userInputHandler->IsXAxisOnLeft() )
+#endif
+ {
+ float newValue = currentItemSlider->m_value - elapsedTime / SLIDER_FULL_RANGE_TIME;
+ if( newValue < 0.0f )
+ {
+ newValue = 0.0f; // clamp lower-end at 0.0
+ }
+
+ if( newValue != currentItemSlider->m_value )
+ {
+ currentItemSlider->SetValue( newValue );
+ hasSliderValueChanged = true;
+ }
+ }
+
+#ifdef RAD_WIN32
+ if( userInputHandler->IsXAxisOnRight() ||
+ GetInputManager()->GetFEMouse()->OnSliderHorizontalClickDrag() == MDIR_RIGHT )
+#else
+ if( userInputHandler->IsButtonDown( GuiInput::Right ) ||
+ userInputHandler->IsXAxisOnRight() )
+#endif
+ {
+ float newValue = currentItemSlider->m_value + elapsedTime / SLIDER_FULL_RANGE_TIME;
+ if( newValue > 1.0f )
+ {
+ newValue = 1.0f; // clamp higher-end at 1.0
+ }
+
+ if( newValue != currentItemSlider->m_value )
+ {
+ currentItemSlider->SetValue( newValue );
+ hasSliderValueChanged = true;
+ }
+ }
+ }
+ }
+
+ if( hasSliderValueChanged )
+ {
+ // notify screen that slider value has changed
+ //
+ m_pParent->HandleMessage( GUI_MSG_MENU_SELECTION_VALUE_CHANGED, m_selection );
+ }
+ else
+ {
+ // otherwise, notify screen that slider value is currently not changing
+ //
+ m_pParent->HandleMessage( GUI_MSG_MENU_SLIDER_NOT_CHANGING, m_selection );
+ }
+ }
+
+ // update L/R arrows (if exists for current selection)
+ //
+ if( m_menuItems[ m_selection ]->m_itemValueArrowL != NULL &&
+ m_menuItems[ m_selection ]->m_itemValueArrowR != NULL )
+ {
+ m_menuItems[ m_selection ]->m_itemValueArrowL->SetIndex( 0 );
+ m_menuItems[ m_selection ]->m_itemValueArrowR->SetIndex( 0 );
+
+ // if there are more than one item to choose from
+ //
+ if( m_menuItems[ m_selection ]->m_itemValueCount > 1 )
+ {
+ int numUserInputHandlers = GetGuiSystem()->GetNumUserInputHandlers();
+ for( int i = 0; i < numUserInputHandlers; i++ )
+ {
+ if( m_controllerID != -1 && m_controllerID != static_cast<short>( i ) )
+ {
+ // ignore other controller inputs
+ //
+ continue;
+ }
+
+ CGuiUserInputHandler* userInputHandler = GetGuiSystem()->GetUserInputHandler( i );
+ if( userInputHandler != NULL )
+ {
+#ifdef RAD_WIN32
+ if( userInputHandler->IsXAxisOnLeft() ||
+ GetInputManager()->GetFEMouse()->LeftButtonDownOn() == HOTSPOT_ARROWLEFT )
+#else
+ if( userInputHandler->IsButtonDown( GuiInput::Left ) ||
+ userInputHandler->IsXAxisOnLeft() )
+#endif
+ {
+ rAssert( m_menuItems[ m_selection ]->m_itemValueArrowL->GetNumOfImages() > 1 );
+ m_menuItems[ m_selection ]->m_itemValueArrowL->SetIndex( 1 );
+ }
+
+#ifdef RAD_WIN32
+ if( userInputHandler->IsXAxisOnRight() ||
+ GetInputManager()->GetFEMouse()->LeftButtonDownOn() == HOTSPOT_ARROWRIGHT )
+#else
+ if( userInputHandler->IsButtonDown( GuiInput::Right ) ||
+ userInputHandler->IsXAxisOnRight() )
+#endif
+ {
+ rAssert( m_menuItems[ m_selection ]->m_itemValueArrowR->GetNumOfImages() > 1 );
+ m_menuItems[ m_selection ]->m_itemValueArrowR->SetIndex( 1 );
+ }
+ }
+ }
+ }
+ }
+
+ // update elapsed time
+ //
+ m_elapsedTime = (m_elapsedTime + elapsedTime) % ITEM_PULSE_PERIOD;
+ }
+}
+
+//===========================================================================
+// CGuiMenu::MoveCursor
+//===========================================================================
+// Description: Move cursor from previous selection to next selection.
+//
+// Constraints: None.
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+void CGuiMenu::MoveCursor( int previousIndex, int nextIndex )
+{
+ // if cursor exists
+ //
+ if( m_pCursor != NULL && previousIndex != NO_SELECTION )
+ {
+ Scrooby::BoundedDrawable* item = NULL;
+ int x1, y1, x2, y2;
+
+ // get location of previous item
+ item = m_menuItems[ previousIndex ]->GetItem();
+ rAssert( item != NULL );
+ item->GetOriginPosition( x1, y1 );
+
+ // get location of next item
+ item = m_menuItems[ nextIndex ]->GetItem();
+ rAssert( item != NULL );
+ item->GetOriginPosition( x2, y2 );
+
+ // translate cursor
+ m_pCursor->Translate( x2 - x1, y2 - y1 );
+ }
+}
+
+
+//===========================================================================
+// Public Member Functions - CGuiMenu2D
+//===========================================================================
+
+CGuiMenu2D::CGuiMenu2D( CGuiEntity* pParent,
+ int numItems,
+ int numColumns,
+ eMenuType menuType,
+ int specialEffects )
+: CGuiMenu( pParent, numItems, menuType, specialEffects ),
+ m_numColumns( static_cast<short>( numColumns ) )
+{
+}
+
+CGuiMenu2D::~CGuiMenu2D()
+{
+}
+
+void
+CGuiMenu2D::HandleMessage( eGuiMessage message, unsigned int param1,
+ unsigned int param2 )
+{
+ if( m_isSelectionMade && this->IsControllerMessage( message ) )
+ {
+ // selection has already been made, ignore all controller messages
+ //
+ return;
+ }
+
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_LEFT:
+ {
+ this->ChangeSelection( -1 );
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_RIGHT:
+ {
+ this->ChangeSelection( +1 );
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_UP:
+ {
+ this->ChangeSelection( -m_numColumns );
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_DOWN:
+ {
+ this->ChangeSelection( +m_numColumns );
+
+ break;
+ }
+ default:
+ {
+ CGuiMenu::HandleMessage( message, param1, param2 );
+
+ break;
+ }
+ }
+}
+
+
+//===========================================================================
+// Public Member Functions - CGuiMenuPrompt
+//===========================================================================
+
+CGuiMenuPrompt::CGuiMenuPrompt( CGuiEntity* pParent,
+ Scrooby::Page* pPage,
+ int numResponses,
+ int specialEffects )
+:
+ CGuiMenu( pParent, numResponses, GUI_TEXT_MENU, specialEffects ),
+ m_numResponses( static_cast<short>( numResponses ) )
+{
+ rAssert( pPage != NULL );
+
+ Scrooby::Group* menu = pPage->GetGroup( "Menu" );
+ rAssert( menu != NULL );
+ // add response menu items
+ //
+ for( short i = 0; i < m_numResponses; i++ )
+ {
+ char textName[ 32 ];
+ sprintf( textName, "Response%d", i );
+ this->AddMenuItem( menu->GetText( textName ) );
+ }
+}
+
+CGuiMenuPrompt::~CGuiMenuPrompt()
+{
+}
+
+void
+CGuiMenuPrompt::SetNumResponses( int numResponses )
+{
+ for( short i = 0; i < m_numResponses; i++ )
+ {
+ this->SetMenuItemEnabled( i, (i < numResponses), true );
+ }
+}
+
+void
+CGuiMenuPrompt::SetResponse( int index, ePromptResponse response )
+{
+ rAssert( static_cast<short>( index ) >= 0 && static_cast<short>( index ) < m_numResponses );
+
+ GuiMenuItem* menuItem = this->GetMenuItem( index );
+ rAssert( menuItem != NULL );
+
+ Scrooby::Text* textItem = dynamic_cast<Scrooby::Text*>( menuItem->GetItem() );
+ rAssert( textItem != NULL );
+ textItem->SetIndex( response );
+}
+
+CGuiMenuPrompt::ePromptResponse
+CGuiMenuPrompt::GetResponse( int index ) const
+{
+ rAssert( static_cast<short>( index ) >= 0 && static_cast<short>( index ) < m_numResponses );
+
+ GuiMenuItem* menuItem = this->GetMenuItem( index );
+ rAssert( menuItem != NULL );
+
+ Scrooby::Text* textItem = dynamic_cast<Scrooby::Text*>( menuItem->GetItem() );
+ rAssert( textItem != NULL );
+
+ return static_cast<ePromptResponse>( textItem->GetIndex() );
+}
+
+CGuiMenuPrompt::ePromptResponse
+CGuiMenuPrompt::GetCurrentResponse() const
+{
+ return this->GetResponse( m_selection );
+}
+
diff --git a/game/code/presentation/gui/guimenu.h b/game/code/presentation/gui/guimenu.h
new file mode 100644
index 0000000..0361079
--- /dev/null
+++ b/game/code/presentation/gui/guimenu.h
@@ -0,0 +1,251 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiMenu
+//
+// Description:
+//
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/12/4 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef GUIMENU_H
+#define GUIMENU_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guientity.h>
+#include <presentation/gui/guimenuitem.h>
+
+namespace Scrooby
+{
+ class Page;
+ class Drawable;
+ class BoundedDrawable;
+ class Sprite;
+}
+
+enum eMenuType
+{
+ GUI_TEXT_MENU,
+ GUI_SPRITE_MENU,
+
+ NUM_MENU_TYPES
+};
+
+enum eMenuSpecialEffect
+{
+ MENU_SFX_NONE = 0,
+
+ MENU_SFX_COLOUR_PULSE = 1,
+ MENU_SFX_SIZE_PULSE = 2,
+
+ MENU_SFX_ALL = ~0
+};
+
+//===========================================================================
+// Interface Definitions - CGuiMenu
+//===========================================================================
+class CGuiMenu : public CGuiEntity
+{
+public:
+ CGuiMenu( CGuiEntity* pParent,
+ int maxNumItems = 1,
+ eMenuType menuType = GUI_TEXT_MENU,
+ int specialEffects = MENU_SFX_SIZE_PULSE );
+
+ virtual ~CGuiMenu();
+
+ void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ GuiMenuItem* AddMenuItem( Scrooby::BoundedDrawable* pItem,
+ Scrooby::BoundedDrawable* pItemValue = NULL,
+ Scrooby::Polygon* pSlider = NULL,
+ Scrooby::Sprite* pSliderImage = NULL,
+ Scrooby::Sprite* pItemValueArrowL = NULL,
+ Scrooby::Sprite* pItemValueArrowR = NULL,
+ int attributes = ALL_ATTRIBUTES_ON );
+
+ void SetMenuItemEnabled( int index, bool enabled,
+ bool changeVisibility = false );
+
+ bool IsMenuItemEnabled( int index );
+
+ void SetCursor( Scrooby::Drawable* pCursor ) { m_pCursor = pCursor; }
+ Scrooby::Drawable* GetCursor() const { return m_pCursor; }
+
+ // Reset Menu
+ //
+ void Reset( int defaultSelection = 0 );
+
+ // Menu Highlight Colour
+ //
+ void SetHighlightColour( bool isEnabled, tColour colour );
+ tColour GetHighlightColour() const { return m_highlightColour; }
+
+ void SetGreyOutEnabled( bool isEnabled ) { m_isGreyOutEnabled = isEnabled; }
+
+ // Selection Made Outline Colour
+ //
+ void SetSelectionMadeOutlineColour( tColour colour ) { m_selectionMadeOutlineColour = colour; }
+
+ // Set Selection Values and Value Counts
+ //
+ void SetSelectionValue( int index, int value );
+ void SetSelectionValueCount( int index, int count );
+
+ // Make Menu Selection and Query Menu Selection Made
+ //
+ void MakeSelection( bool isSelectionMade = true );
+ bool HasSelectionBeenMade() const { return m_isSelectionMade; }
+
+ // Set Specific Controller ID
+ //
+ void SetControllerID( int controllerID );
+
+ // Menu Accessors
+ //
+ GuiMenuItem* GetMenuItem( int index ) const;
+ int GetNumItems() const { return m_numItems; }
+ int GetSelection() const { return m_selection; }
+ int GetSelectionValue( int index ) const;
+
+protected:
+ enum eSelection { NO_SELECTION = -1 };
+
+ void SelectItem( int index );
+ void UnselectItem( int index );
+
+ void ChangeSelection( int deltaItems, bool isUserInput = true );
+#ifdef RAD_WIN32
+ void SetNewSelection( int newSelection, bool isUserInput = false );
+ void OutlineSelection( bool bOutline = true );
+#endif
+ void IncrementSelectionValue( bool isUserInput = true );
+ void DecrementSelectionValue( bool isUserInput = true );
+
+ eMenuType m_menuType;
+ short m_specialEffects; // bitmask
+
+ GuiMenuItem** m_menuItems;
+ int m_numItems;
+
+ int m_selection;
+#ifdef RAD_WIN32
+ bool m_bIsSelectionOutlined;
+ tColour m_selectionOutlineColour;
+#endif
+ Scrooby::Drawable* m_pCursor;
+ bool m_isSelectionMade : 1;
+
+private:
+ void UpdateCurrentSelection( int elapsedTime );
+ void MoveCursor( int previousIndex, int nextIndex );
+
+ bool m_isHighlightEnabled : 1;
+ tColour m_highlightColour;
+ tColour m_selectionMadeOutlineColour;
+
+ bool m_isGreyOutEnabled : 1;
+
+ unsigned int m_elapsedTime;
+ int m_selectionMadeElapsedTime;
+
+ short m_controllerID;
+};
+
+inline void CGuiMenu::SetControllerID( int controllerID )
+{
+ m_controllerID = static_cast<short>( controllerID );
+}
+
+inline GuiMenuItem* CGuiMenu::GetMenuItem( int index ) const
+{
+ rAssert( index >= 0 && index < m_numItems );
+ return m_menuItems[ index ];
+}
+
+inline int CGuiMenu::GetSelectionValue( int index ) const
+{
+ rAssert( index >= 0 && index < m_numItems );
+ return m_menuItems[ index ]->GetItemValueIndex();
+}
+
+//===========================================================================
+// Interface Definitions - CGuiMenu2D
+//===========================================================================
+class CGuiMenu2D : public CGuiMenu
+{
+public:
+ CGuiMenu2D( CGuiEntity* pParent,
+ int numItems,
+ int numColumns,
+ eMenuType menuType = GUI_TEXT_MENU,
+ int specialEffects = MENU_SFX_SIZE_PULSE );
+
+ virtual ~CGuiMenu2D();
+
+ void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+private:
+ short m_numColumns;
+
+};
+
+//===========================================================================
+// Interface Definitions - CGuiMenuPrompt
+//===========================================================================
+class CGuiMenuPrompt : public CGuiMenu
+{
+public:
+ enum ePromptResponse
+ {
+ RESPONSE_NO,
+ RESPONSE_YES,
+ RESPONSE_CONTINUE,
+ RESPONSE_CONTINUE_WITHOUT_SAVE,
+ RESPONSE_RETRY,
+ RESPONSE_MANAGE_MEMCARDS,
+ RESPONSE_FORMAT_GC,
+ RESPONSE_FORMAT_PS2,
+ RESPONSE_FORMAT_XBOX,
+ RESPONSE_CONTINUE_WITHOUT_FORMAT,
+ RESPONSE_DELETE,
+ RESPONSE_OK,
+ RESPONSE_LOAD,
+ RESPONSE_SAVE,
+
+ NUM_PROMPT_RESPONSES
+ };
+
+ static const int MAX_NUM_RESPONSES = 3;
+
+ CGuiMenuPrompt( CGuiEntity* pParent,
+ Scrooby::Page* pPage,
+ int numResponses = MAX_NUM_RESPONSES,
+ int specialEffects = MENU_SFX_SIZE_PULSE );
+
+ virtual ~CGuiMenuPrompt();
+
+ void SetNumResponses( int numResponses );
+ void SetResponse( int index, ePromptResponse response );
+ ePromptResponse GetResponse( int index ) const;
+ ePromptResponse GetCurrentResponse() const;
+
+private:
+ short m_numResponses;
+
+};
+
+#endif // GUIMENU_H
diff --git a/game/code/presentation/gui/guimenuitem.cpp b/game/code/presentation/gui/guimenuitem.cpp
new file mode 100644
index 0000000..daf6490
--- /dev/null
+++ b/game/code/presentation/gui/guimenuitem.cpp
@@ -0,0 +1,318 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: GuiMenuItem
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/19 TChu Created
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/guimenuitem.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions - GuiMenuItem
+//===========================================================================
+
+GuiMenuItem::GuiMenuItem()
+: m_attributes( ALL_ATTRIBUTES_OFF ),
+ m_defaultColour( 0, 0, 0 ),
+ m_itemValueArrowL( NULL ),
+ m_itemValueArrowR( NULL ),
+ m_itemValueCount( 0 )
+{
+}
+
+GuiMenuItem::~GuiMenuItem()
+{
+}
+
+//===========================================================================
+// Public Member Functions - GuiMenuItemText
+//===========================================================================
+
+GuiMenuItemText::GuiMenuItemText()
+: GuiMenuItem(),
+ m_item( NULL ),
+ m_itemValue( NULL )
+{
+}
+
+//===========================================================================
+// GuiMenuItemText::SetItem
+//===========================================================================
+// Description: Sets the text drawable menu item.
+//
+// Parameters: pointer to a Scrooby text drawable
+//
+// Return: n/a
+//
+//===========================================================================
+void
+GuiMenuItemText::SetItem( Scrooby::BoundedDrawable* item )
+{
+ m_item = dynamic_cast<Scrooby::Text*>( item );
+ rAssert( m_item != NULL );
+}
+
+//===========================================================================
+// GuiMenuItemText::SetItemValue
+//===========================================================================
+// Description: Sets the text drawable menu item value.
+//
+// Parameters: pointer to a Scrooby text drawable
+//
+// Return: n/a
+//
+//===========================================================================
+void
+GuiMenuItemText::SetItemValue( Scrooby::BoundedDrawable* itemValue )
+{
+ m_itemValue = dynamic_cast<Scrooby::Text*>( itemValue );
+ rAssert( m_itemValue != NULL );
+
+ m_itemValueCount = m_itemValue->GetNumOfStrings();
+}
+
+//===========================================================================
+// GuiMenuItemText::SetItemValueIndex
+//===========================================================================
+// Description: Sets the current item value index.
+//
+// Parameters: text index
+//
+// Return: n/a
+//
+//===========================================================================
+void
+GuiMenuItemText::SetItemValueIndex( int index )
+{
+ rAssert( m_itemValue != NULL );
+ m_itemValue->SetIndex( index );
+}
+
+//===========================================================================
+// GuiMenuItemText::GetItemValueIndex
+//===========================================================================
+// Description: Gets the current item value index.
+//
+// Parameters: n/a
+//
+// Return: text index
+//
+//===========================================================================
+int
+GuiMenuItemText::GetItemValueIndex() const
+{
+ rAssert( m_itemValue != NULL );
+ return m_itemValue->GetIndex();
+}
+
+//===========================================================================
+// GuiMenuItemText::SetDisplayOutline
+//===========================================================================
+// Description: Enables/Disables text outlining.
+//
+// Parameters: enable/disable flag
+//
+// Return: n/a
+//
+//===========================================================================
+void
+GuiMenuItemText::SetDisplayOutline( bool enable )
+{
+ rAssert( m_item != NULL );
+ m_item->SetDisplayOutline( enable );
+
+ if( m_itemValue != NULL )
+ {
+ m_itemValue->SetDisplayOutline( enable );
+ }
+}
+
+//===========================================================================
+// GuiMenuItemText::SetOutlineColour
+//===========================================================================
+// Description: Sets the current text outline colour.
+//
+// Parameters: colour
+//
+// Return: n/a
+//
+//===========================================================================
+void
+GuiMenuItemText::SetOutlineColour( tColour colour )
+{
+ rAssert( m_item != NULL );
+ m_item->SetOutlineColour( colour );
+
+ if( m_itemValue != NULL )
+ {
+ m_itemValue->SetOutlineColour( colour );
+ }
+}
+
+//===========================================================================
+// GuiMenuItemText::GetOutlineColour
+//===========================================================================
+// Description: Gets the current text outline colour.
+//
+// Parameters: n/a
+//
+// Return: colour
+//
+//===========================================================================
+tColour
+GuiMenuItemText::GetOutlineColour() const
+{
+ rAssert( m_item != NULL );
+ return m_item->GetOutlineColour();
+}
+
+
+//===========================================================================
+// Public Member Functions - GuiMenuItemSprite
+//===========================================================================
+
+GuiMenuItemSprite::GuiMenuItemSprite()
+: GuiMenuItem(),
+ m_item( NULL ),
+ m_itemValue( NULL )
+{
+}
+
+//===========================================================================
+// GuiMenuItemSprite::SetItem
+//===========================================================================
+// Description: Sets the text drawable menu item.
+//
+// Parameters: pointer to a Scrooby sprite drawable
+//
+// Return: n/a
+//
+//===========================================================================
+void
+GuiMenuItemSprite::SetItem( Scrooby::BoundedDrawable* item )
+{
+ m_item = dynamic_cast<Scrooby::Sprite*>( item );
+ rAssert( m_item != NULL );
+}
+
+//===========================================================================
+// GuiMenuItemSprite::SetItemValue
+//===========================================================================
+// Description: Sets the text drawable menu item value.
+//
+// Parameters: pointer to a Scrooby sprite drawable
+//
+// Return: n/a
+//
+//===========================================================================
+void
+GuiMenuItemSprite::SetItemValue( Scrooby::BoundedDrawable* itemValue )
+{
+ m_itemValue = dynamic_cast<Scrooby::Sprite*>( itemValue );
+ rAssert( m_itemValue != NULL );
+
+ m_itemValueCount = m_itemValue->GetNumOfImages();
+}
+
+//===========================================================================
+// GuiMenuItemSprite::SetItemValueIndex
+//===========================================================================
+// Description: Sets the current item value index.
+//
+// Parameters: sprite index
+//
+// Return: n/a
+//
+//===========================================================================
+void
+GuiMenuItemSprite::SetItemValueIndex( int index )
+{
+ rAssert( m_itemValue != NULL );
+ m_itemValue->SetIndex( index );
+}
+
+//===========================================================================
+// GuiMenuItemSprite::GetItemValueIndex
+//===========================================================================
+// Description: Gets the current item value index.
+//
+// Parameters: n/a
+//
+// Return: sprite index
+//
+//===========================================================================
+int
+GuiMenuItemSprite::GetItemValueIndex() const
+{
+ rAssert( m_itemValue != NULL );
+ return m_itemValue->GetIndex();
+}
+
+//===========================================================================
+// GuiMenuItemSprite::SetDisplayOutline
+//===========================================================================
+// Description: Not applicable for GuiMenuItemSprite's and should never be
+// invoked.
+//
+// Parameters: n/a
+//
+// Return: n/a
+//
+//===========================================================================
+void
+GuiMenuItemSprite::SetDisplayOutline( bool enable )
+{
+ rAssertMsg( false, "No outlining on sprites!" );
+}
+
+//===========================================================================
+// GuiMenuItemSprite::SetOutlineColour
+//===========================================================================
+// Description: Not applicable for GuiMenuItemSprite's and should never be
+// invoked.
+//
+// Parameters: n/a
+//
+// Return: n/a
+//
+//===========================================================================
+void
+GuiMenuItemSprite::SetOutlineColour( tColour colour )
+{
+ rAssertMsg( false, "No outlining on sprites!" );
+}
+
+//===========================================================================
+// GuiMenuItemSprite::SetOutlineColour
+//===========================================================================
+// Description: Not applicable for GuiMenuItemSprite's and should never be
+// invoked.
+//
+// Parameters: n/a
+//
+// Return: n/a
+//
+//===========================================================================
+tColour
+GuiMenuItemSprite::GetOutlineColour() const
+{
+ rAssertMsg( false, "No outlining on sprites!" );
+
+ return tColour( 0, 0, 0 );
+}
+
diff --git a/game/code/presentation/gui/guimenuitem.h b/game/code/presentation/gui/guimenuitem.h
new file mode 100644
index 0000000..6d10730
--- /dev/null
+++ b/game/code/presentation/gui/guimenuitem.h
@@ -0,0 +1,164 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: GuiMenuItem
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/19 TChu Created
+//
+//===========================================================================
+
+#ifndef GUIMENUITEM_H
+#define GUIMENUITEM_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/utility/slider.h>
+
+#include <p3d/p3dtypes.hpp>
+
+// Scrooby
+//
+#include <text.h>
+#include <sprite.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+namespace Scrooby
+{
+ class BoundedDrawable;
+ class Sprite;
+ class Text;
+}
+
+enum eMenuAttribute
+{
+ ALL_ATTRIBUTES_OFF = 0,
+
+ SELECTION_ENABLED = 1,
+ SELECTABLE = 2,
+ VALUES_WRAPPED = 4,
+ TEXT_OUTLINE_ENABLED = 8,
+
+ ALL_ATTRIBUTES_ON = -1
+};
+
+//===========================================================================
+// Interface Definitions - GuiMenuItem (Abstract Base Class)
+//===========================================================================
+struct GuiMenuItem
+{
+ GuiMenuItem();
+ virtual ~GuiMenuItem();
+
+ virtual void SetItem( Scrooby::BoundedDrawable* item ) = 0;
+ virtual Scrooby::BoundedDrawable* GetItem() const = 0;
+
+ virtual void SetItemValue( Scrooby::BoundedDrawable* itemValue ) = 0;
+ virtual Scrooby::BoundedDrawable* GetItemValue() const = 0;
+
+ virtual void SetItemValueIndex( int index ) = 0;
+ virtual int GetItemValueIndex() const = 0;
+
+ virtual void SetDisplayOutline( bool enable ) = 0;
+ virtual void SetOutlineColour( tColour colour ) = 0;
+ virtual tColour GetOutlineColour() const = 0;
+
+ int m_attributes;
+ tColour m_defaultColour;
+
+ Scrooby::Sprite* m_itemValueArrowL;
+ Scrooby::Sprite* m_itemValueArrowR;
+ int m_itemValueCount;
+
+ ImageSlider m_slider;
+
+};
+
+//===========================================================================
+// Interface Definitions - GuiMenuItemText
+//===========================================================================
+struct GuiMenuItemText : public GuiMenuItem
+{
+ GuiMenuItemText();
+
+ virtual void SetItem( Scrooby::BoundedDrawable* item );
+ virtual Scrooby::BoundedDrawable* GetItem() const;
+
+ virtual void SetItemValue( Scrooby::BoundedDrawable* itemValue );
+ virtual Scrooby::BoundedDrawable* GetItemValue() const;
+
+ virtual void SetItemValueIndex( int index );
+ virtual int GetItemValueIndex() const;
+
+ virtual void SetDisplayOutline( bool enable );
+ virtual void SetOutlineColour( tColour colour );
+ virtual tColour GetOutlineColour() const;
+
+ Scrooby::Text* m_item;
+ Scrooby::Text* m_itemValue;
+
+};
+
+//===========================================================================
+// Inlines - GuiMenuItemText
+//===========================================================================
+
+inline Scrooby::BoundedDrawable* GuiMenuItemText::GetItem() const
+{
+ return m_item;
+}
+
+inline Scrooby::BoundedDrawable* GuiMenuItemText::GetItemValue() const
+{
+ return m_itemValue;
+}
+
+//===========================================================================
+// Interface Definitions - GuiMenuItemSprite
+//===========================================================================
+struct GuiMenuItemSprite : public GuiMenuItem
+{
+ GuiMenuItemSprite();
+
+ virtual void SetItem( Scrooby::BoundedDrawable* item );
+ virtual Scrooby::BoundedDrawable* GetItem() const;
+
+ virtual void SetItemValue( Scrooby::BoundedDrawable* itemValue );
+ virtual Scrooby::BoundedDrawable* GetItemValue() const;
+
+ virtual void SetItemValueIndex( int index );
+ virtual int GetItemValueIndex() const;
+
+ virtual void SetDisplayOutline( bool enable );
+ virtual void SetOutlineColour( tColour colour );
+ virtual tColour GetOutlineColour() const;
+
+ Scrooby::Sprite* m_item;
+ Scrooby::Sprite* m_itemValue;
+
+};
+
+//===========================================================================
+// Inlines - GuiMenuItemSprite
+//===========================================================================
+
+inline Scrooby::BoundedDrawable* GuiMenuItemSprite::GetItem() const
+{
+ return m_item;
+}
+
+inline Scrooby::BoundedDrawable* GuiMenuItemSprite::GetItemValue() const
+{
+ return m_itemValue;
+}
+
+
+#endif // GUIMENUITEM_H
diff --git a/game/code/presentation/gui/guiscreen.cpp b/game/code/presentation/gui/guiscreen.cpp
new file mode 100644
index 0000000..aee9b0e
--- /dev/null
+++ b/game/code/presentation/gui/guiscreen.cpp
@@ -0,0 +1,1314 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreen
+//
+// Description: Implementation of the CGuiScreen class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/09/21 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <memory/classsizetracker.h>
+#include <presentation/gui/guiscreen.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/utility/specialfx.h>
+
+#include <events/eventmanager.h>
+
+#include <app.h>
+#include <screen.h>
+#include <page.h>
+#include <layer.h>
+#include <group.h>
+#include <pure3dobject.h>
+#include <sprite.h>
+#include <text.h>
+
+#include <p3d/anim/multicontroller.hpp>
+#include <p3d/utility.hpp>
+#include <pddi/pddi.hpp>
+
+#include <raddebug.hpp>
+
+#include <string.h>
+
+#ifdef RAD_WIN32
+#include <input/inputmanager.h>
+#endif
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//#define PRINTSCREENUPDATES
+
+const char* FOREGROUND_LAYER = "Foreground";
+const char* BACKGROUND_LAYER = "Background";
+const char* FE_PURE3D_OBJECT = "CamAndSet";
+
+const float DEFAULT_SCREEN_FADE_TIME = 250.0f; // in msec
+const float DEFAULT_SCREEN_ZOOM_TIME = 250.0f; // in msec
+const float DEFAULT_SCREEN_SLIDE_TIME = 250.0f; // in msec
+const float DEFAULT_IRIS_WIPE_SPEED = 0.5f;
+
+const float WIDE_SCREEN_CORRECTION_SCALE = (4.0f / 3.0f) * (9.0f / 16.0f);
+
+const char* ACCEPT_PAGES[] =
+{
+ "Accept",
+ "Accept2",
+ "Accept3",
+ "Buy",
+ "Continue",
+
+ "" // dummy terminator
+};
+
+const int NUM_ACCEPT_PAGES = sizeof( ACCEPT_PAGES ) / sizeof( ACCEPT_PAGES[ 0 ] );
+
+const char* BACK_PAGES[] =
+{
+ "Back",
+ "Back2",
+ "Cancel",
+
+ "" // dummy terminator
+};
+
+const int NUM_BACK_PAGES = sizeof( BACK_PAGES ) / sizeof( BACK_PAGES[ 0 ] );
+
+tMultiController* CGuiScreen::s_p3dMultiController = NULL;
+float CGuiScreen::s_numIrisFrames = 0.0f;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreen::CGuiScreen
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreen::CGuiScreen
+(
+ Scrooby::Screen* pScroobyScreen,
+ CGuiEntity* pParent,
+ eGuiWindowID id,
+ unsigned int screenFX
+)
+: CGuiWindow( id, pParent ),
+ m_pScroobyScreen( pScroobyScreen ),
+ m_screenCover( NULL ),
+ m_p3dObject( NULL ),
+ m_p3dIris( NULL ),
+ m_irisController( NULL ),
+ m_currentIrisState( IRIS_STATE_IDLE ),
+ m_autoOpenIris( false ),
+ m_numForegroundLayers( 0 ),
+ m_numBackgroundLayers( 0 ),
+ m_ignoreControllerInputs( false ),
+ m_inverseFading( false ),
+ m_screenFX( screenFX ),
+ m_fadeTime( DEFAULT_SCREEN_FADE_TIME ),
+ m_elapsedFadeTime( -1 ),
+ m_zoomTime( DEFAULT_SCREEN_ZOOM_TIME ),
+ m_elapsedZoomTime( -1 ),
+ m_slideTime( DEFAULT_SCREEN_SLIDE_TIME ),
+ m_elapsedSlideTime( -1 ),
+ m_playTransitionAnimationLast( false )
+{
+ CLASSTRACKER_CREATE( CGuiScreen );
+ memset( m_foregroundLayers, 0, sizeof( m_foregroundLayers ) );
+ memset( m_backgroundLayers, 0, sizeof( m_backgroundLayers ) );
+ memset( m_buttonIcons, 0, sizeof( m_buttonIcons ) );
+
+ m_guiManager = static_cast<CGuiManager*>( m_pParent );
+ rAssert( m_guiManager );
+
+ rAssert( m_pScroobyScreen != NULL );
+
+ Scrooby::Page* pPage = NULL;
+
+ // Get foreground and background layers of all pages in screen
+ //
+ int numPages = m_pScroobyScreen->GetNumberOfPages();
+ for( int i = 0; i < numPages; i++ )
+ {
+ pPage = m_pScroobyScreen->GetPageByIndex( i );
+ rAssert( pPage );
+
+ Scrooby::Layer* pLayer = pPage->GetLayer( FOREGROUND_LAYER );
+ if( pLayer != NULL )
+ {
+ rAssert( m_numForegroundLayers < MAX_FOREGROUND_LAYERS );
+ m_foregroundLayers[ m_numForegroundLayers ] = pLayer;
+ m_numForegroundLayers++;
+
+ if( this->IsWideScreenDisplay() )
+ {
+ pLayer->ResetTransformation();
+ this->ApplyWideScreenCorrectionScale( pLayer );
+ }
+ }
+
+ pLayer = pPage->GetLayer( BACKGROUND_LAYER );
+ if( pLayer != NULL )
+ {
+ rAssert( m_numBackgroundLayers < MAX_BACKGROUND_LAYERS );
+ m_backgroundLayers[ m_numBackgroundLayers ] = pLayer;
+ m_numBackgroundLayers++;
+ }
+ }
+
+ this->RestoreScreenCover();
+
+ // Get pure3d object from "3dFE" page, if included
+ //
+ pPage = m_pScroobyScreen->GetPage( "3dFE" );
+ if( pPage != NULL )
+ {
+ m_p3dObject = pPage->GetPure3dObject( FE_PURE3D_OBJECT );
+ rAssert( m_p3dObject );
+ }
+
+ // Get iris pure3d object from "IrisCover" page, if included
+ //
+ pPage = m_pScroobyScreen->GetPage( "IrisCover" );
+ if( pPage != NULL )
+ {
+ // set iris layer visible
+ //
+ Scrooby::Layer* irisLayer = pPage->GetLayer( "IrisCover" );
+ rAssert( irisLayer != NULL );
+ irisLayer->SetVisible( true );
+
+ m_p3dIris = pPage->GetPure3dObject( "3dIris" );
+ rAssert( m_p3dIris != NULL );
+ m_p3dIris->SetZBufferEnabled( false );
+
+ m_irisController = p3d::find<tMultiController>( "IrisController" );
+ rAssert( m_irisController != NULL );
+ m_irisController->AddRef();
+
+ s_numIrisFrames = m_irisController->GetNumFrames();
+ }
+
+ // Get button icons
+ //
+ for( int j = 0; j < NUM_ACCEPT_PAGES; j++ )
+ {
+ pPage = m_pScroobyScreen->GetPage( ACCEPT_PAGES[ j ] );
+ if( pPage != NULL )
+ {
+ m_buttonIcons[ BUTTON_ICON_ACCEPT ] = pPage->GetGroup( "AcceptLabel" );
+ rAssert( m_buttonIcons[ BUTTON_ICON_ACCEPT ] != NULL );
+
+#ifndef RAD_WIN32
+ // add text outline to accept text
+ //
+ Scrooby::Text* accept = m_buttonIcons[ BUTTON_ICON_ACCEPT ]->GetText( "Accept" );
+ rAssert( accept != NULL );
+ accept->SetDisplayOutline( true );
+#endif
+
+ break;
+ }
+ }
+
+ for( int k = 0; k < NUM_BACK_PAGES; k++ )
+ {
+ pPage = m_pScroobyScreen->GetPage( BACK_PAGES[ k ] );
+ if( pPage != NULL )
+ {
+ m_buttonIcons[ BUTTON_ICON_BACK ] = pPage->GetGroup( "BackLabel" );
+ rAssert( m_buttonIcons[ BUTTON_ICON_BACK ] != NULL );
+
+#ifndef RAD_WIN32
+ // add text outline to accept text
+ //
+ Scrooby::Text* back = m_buttonIcons[ BUTTON_ICON_BACK ]->GetText( "Back" );
+ rAssert( back != NULL );
+ back->SetDisplayOutline( true );
+#endif
+
+ break;
+ }
+ }
+}
+
+//===========================================================================
+// CGuiScreen::~CGuiScreen
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreen::~CGuiScreen()
+{
+ CLASSTRACKER_DESTROY( CGuiScreen );
+ if( m_irisController != NULL )
+ {
+ m_irisController->Release();
+ m_irisController = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreen::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiScreen::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_ignoreControllerInputs &&
+ this->IsControllerMessage( message ) )
+ {
+ // ignore controller messages
+ return;
+ }
+
+
+#ifdef RAD_WIN32
+ if( message == GUI_MSG_WINDOW_ENTER )
+ {
+ // just entered screen, so re-enable mouse
+ GetInputManager()->GetFEMouse()->SetSelectable( true );
+ }
+ else if( message == GUI_MSG_WINDOW_EXIT )
+ {
+ // exiting screen, so disable mouse
+ GetInputManager()->GetFEMouse()->SetSelectable( false );
+ }
+#endif
+
+ switch( message )
+ {
+ case GUI_MSG_WINDOW_ENTER:
+ {
+ // reset any pending transitions
+ m_numTransitionsPending = 0;
+
+ if( !m_inverseFading )
+ {
+ if( m_screenFX & SCREEN_FX_FADE )
+ {
+ this->SetAlphaForLayers( 0.0f,
+ m_foregroundLayers,
+ m_numForegroundLayers );
+ }
+ }
+
+ if( m_screenFX & SCREEN_FX_ZOOM )
+ {
+ this->SetAlphaForLayers( 0.0f,
+ m_backgroundLayers,
+ m_numBackgroundLayers );
+ }
+
+ if( m_screenFX & SCREEN_FX_IRIS )
+ {
+ this->SetAlphaForLayers( 0.0f,
+ m_foregroundLayers,
+ m_numForegroundLayers );
+
+ this->SetAlphaForLayers( 0.0f,
+ m_backgroundLayers,
+ m_numBackgroundLayers );
+ }
+
+ // restore all button icon visibilities
+ this->RestoreButtons();
+
+ // follow-through
+ //
+ }
+ case GUI_MSG_WINDOW_EXIT:
+ {
+ if( m_screenFX & SCREEN_FX_FADE )
+ {
+ if( m_numForegroundLayers > 0 || m_screenCover != NULL )
+ {
+ // reset fade elapsed time
+ m_elapsedFadeTime = 0;
+
+ // increment number of pending transitions
+ m_numTransitionsPending++;
+ }
+ }
+
+ if( m_screenFX & SCREEN_FX_ZOOM )
+ {
+ // reset zoom elapsed time
+ m_elapsedZoomTime = 0;
+
+ // increment number of pending transitions
+ m_numTransitionsPending++;
+ }
+
+ if( m_screenFX & SCREEN_FX_SLIDE_X ||
+ m_screenFX & SCREEN_FX_SLIDE_Y )
+ {
+ m_elapsedSlideTime = 0;
+ m_numTransitionsPending++;
+ }
+
+ if( m_screenFX & SCREEN_FX_IRIS )
+ {
+ rAssert( m_irisController != NULL );
+ m_irisController->Reset();
+ m_irisController->SetRelativeSpeed( DEFAULT_IRIS_WIPE_SPEED );
+ m_irisController->SetFrameRange( 0.0f, s_numIrisFrames );
+ m_irisController->SetFrame( 0.0f );
+
+ m_currentIrisState = IRIS_STATE_CLOSING;
+
+ m_numTransitionsPending++;
+ }
+ break;
+ }
+
+ case GUI_MSG_UPDATE:
+ {
+ #ifdef PRINTSCREENUPDATES
+ const char* screenName = GetWatcherName();
+ rDebugPrintf( "Screen - %s\n", screenName );
+ #endif
+
+ switch( m_state )
+ {
+ case GUI_WINDOW_STATE_INTRO:
+ {
+ // update screen fade in
+ //
+ if( (m_screenFX & SCREEN_FX_FADE) &&
+ m_elapsedFadeTime != -1 )
+ {
+ if( m_inverseFading )
+ {
+ this->FadeOut( static_cast<float>( param1 ) );
+ }
+ else
+ {
+ this->FadeIn( static_cast<float>( param1 ) );
+ }
+ }
+
+ // update screen zoom in
+ //
+ if( (m_screenFX & SCREEN_FX_ZOOM) &&
+ m_elapsedZoomTime != -1 )
+ {
+ this->ZoomIn( static_cast<float>( param1 ) );
+ }
+
+ // update screen slide in
+ //
+ if( ((m_screenFX & SCREEN_FX_SLIDE_X) || (m_screenFX & SCREEN_FX_SLIDE_Y)) &&
+ m_elapsedSlideTime != -1 )
+ {
+ this->SlideIn( static_cast<float>( param1 ) );
+ }
+
+ // update transition in animation
+ //
+ if( m_p3dObject != NULL )
+ {
+ tMultiController* controller = m_p3dObject->GetMultiController();
+ if( controller != NULL )
+ {
+ if( controller->GetFrame() >= controller->GetNumFrames() )
+ {
+ // nullify multicontroller
+ m_p3dObject->SetMultiController( NULL );
+
+ // decrement number of pending transitions
+ m_numTransitionsPending--;
+ }
+ }
+ }
+
+ // update iris wipe
+ //
+ if( m_screenFX & SCREEN_FX_IRIS )
+ {
+ rAssert( m_irisController != NULL );
+ if( m_currentIrisState == IRIS_STATE_CLOSING )
+ {
+ if( m_irisController->GetFrame() > m_irisController->GetNumFrames() / 2 )
+ {
+ this->OnIrisWipeClosed();
+
+ this->SetAlphaForLayers( 1.0f,
+ m_foregroundLayers,
+ m_numForegroundLayers );
+
+ this->SetAlphaForLayers( 1.0f,
+ m_backgroundLayers,
+ m_numBackgroundLayers );
+ }
+ }
+ else if( m_currentIrisState == IRIS_STATE_OPENING )
+ {
+ if( m_irisController->LastFrameReached() )
+ {
+ m_numTransitionsPending--;
+
+ m_currentIrisState = IRIS_STATE_IDLE;
+ }
+ }
+ }
+
+ // get p3d multicontroller upon first time entering screen
+ // and store reference to it
+ //
+ if( m_firstTimeEntered )
+ {
+ if( m_p3dObject != NULL &&
+ s_p3dMultiController == NULL )
+ {
+ s_p3dMultiController = m_p3dObject->GetMultiController();
+ if( s_p3dMultiController != NULL )
+ {
+ s_p3dMultiController->AddRef();
+
+ m_p3dObject->SetMultiController( NULL );
+ }
+ }
+ }
+
+ break;
+ }
+ case GUI_WINDOW_STATE_OUTRO:
+ {
+ // update screen fade out
+ //
+ if( (m_screenFX & SCREEN_FX_FADE) &&
+ m_elapsedFadeTime != -1 )
+ {
+ if( m_inverseFading )
+ {
+ this->FadeIn( static_cast<float>( param1 ) );
+ }
+ else
+ {
+ this->FadeOut( static_cast<float>( param1 ) );
+ }
+ }
+
+ // update screen zoom out
+ //
+ if( (m_screenFX & SCREEN_FX_ZOOM) &&
+ m_elapsedZoomTime != -1 )
+ {
+ this->ZoomOut( static_cast<float>( param1 ) );
+ }
+
+ // update screen slide out
+ //
+ if( ((m_screenFX & SCREEN_FX_SLIDE_X) || (m_screenFX & SCREEN_FX_SLIDE_Y)) &&
+ m_elapsedSlideTime != -1 )
+ {
+ this->SlideOut( static_cast<float>( param1 ) );
+ }
+
+ // update transition out animation
+ //
+ if( m_p3dObject != NULL )
+ {
+ if( m_playTransitionAnimationLast )
+ {
+ if( m_numTransitionsPending == 1 )
+ {
+ s_p3dMultiController->Reset();
+ m_p3dObject->SetMultiController( s_p3dMultiController );
+ m_playTransitionAnimationLast = false;
+ }
+ }
+ else
+ {
+ tMultiController* controller = m_p3dObject->GetMultiController();
+ if( controller != NULL )
+ {
+ if( controller->GetFrame() >= controller->GetNumFrames() )
+ {
+ // nullify multicontroller
+ m_p3dObject->SetMultiController( NULL );
+
+ // decrement number of pending transitions
+ m_numTransitionsPending--;
+ }
+ }
+ }
+ }
+
+ // update iris wipe
+ //
+ if( m_screenFX & SCREEN_FX_IRIS )
+ {
+ rAssert( m_irisController != NULL );
+ if( m_currentIrisState == IRIS_STATE_CLOSING )
+ {
+ if( m_irisController->GetFrame() > m_irisController->GetNumFrames() / 2 )
+ {
+ this->OnIrisWipeClosed();
+
+ this->SetAlphaForLayers( 0.0f,
+ m_foregroundLayers,
+ m_numForegroundLayers );
+
+ this->SetAlphaForLayers( 0.0f,
+ m_backgroundLayers,
+ m_numBackgroundLayers );
+
+ m_currentIrisState = IRIS_STATE_CLOSED;
+ }
+ }
+ else if( m_currentIrisState == IRIS_STATE_OPENING )
+ {
+ if( m_irisController->LastFrameReached() )
+ {
+ m_numTransitionsPending--;
+
+ m_currentIrisState = IRIS_STATE_IDLE;
+ }
+ }
+ }
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ if( m_guiManager->GetPreviousScreen() != GUI_WINDOW_ID_UNDEFINED )
+ {
+ m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN );
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK );
+ }
+ }
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ };
+
+ // Pass the message up the heirarchy.
+ //
+ CGuiWindow::HandleMessage( message, param1, param2 );
+}
+
+void
+CGuiScreen::SetFadingEnabled( bool enable )
+{
+ if( enable )
+ {
+ m_screenFX |= SCREEN_FX_FADE;
+ }
+ else
+ {
+ m_screenFX &= ~SCREEN_FX_FADE;
+
+ this->SetAlphaForLayers( 1.0f,
+ m_foregroundLayers,
+ m_numForegroundLayers );
+
+ if( m_screenCover != NULL )
+ {
+ m_screenCover->SetVisible( false );
+ }
+ }
+}
+
+void
+CGuiScreen::SetZoomingEnabled( bool enable )
+{
+ if( enable )
+ {
+ m_screenFX |= SCREEN_FX_ZOOM;
+ }
+ else
+ {
+ m_screenFX &= ~SCREEN_FX_ZOOM;
+
+ m_pScroobyScreen->SetScale( 1.0f );
+
+ this->SetAlphaForLayers( 1.0f,
+ m_backgroundLayers,
+ m_numBackgroundLayers );
+ }
+}
+
+void
+CGuiScreen::SetSlidingEnabled( eScreenEffect slideType, bool enable )
+{
+ rAssert( slideType == SCREEN_FX_SLIDE_X ||
+ slideType == SCREEN_FX_SLIDE_Y );
+
+ rAssertMsg( !this->IsWideScreenDisplay() || slideType != SCREEN_FX_SLIDE_X,
+ "Horizontal screen sliding currently not supported for widescreen display!" );
+
+ if( enable )
+ {
+ m_screenFX |= slideType;
+ }
+ else
+ {
+ m_screenFX &= ~slideType;
+ }
+}
+
+void
+CGuiScreen::SetIrisWipeEnabled( bool enable, bool autoOpenIris )
+{
+ if( enable )
+ {
+ m_screenFX |= SCREEN_FX_IRIS;
+
+ m_autoOpenIris = autoOpenIris;
+ }
+ else
+ {
+ m_screenFX &= ~SCREEN_FX_IRIS;
+ }
+}
+
+bool
+CGuiScreen::IsEffectEnabled( eScreenEffect effect ) const
+{
+ return ((m_screenFX & effect) > 0);
+}
+
+void
+CGuiScreen::Reset3dFEMultiController()
+{
+ if( s_p3dMultiController != NULL )
+ {
+ s_p3dMultiController->Release();
+ s_p3dMultiController = NULL;
+ }
+}
+
+void
+CGuiScreen::SetButtonVisible( eButtonIcon button, bool isVisible )
+{
+ if( m_buttonIcons[ button ] != NULL )
+ {
+ m_buttonIcons[ button ]->SetVisible( isVisible );
+ }
+}
+
+bool
+CGuiScreen::IsButtonVisible( eButtonIcon button ) const
+{
+ if( m_buttonIcons[ button ] != NULL )
+ {
+ return m_buttonIcons[ button ]->IsVisible();
+ }
+
+ return false;
+}
+
+void
+CGuiScreen::StartTransitionAnimation( int startFrame,
+ int endFrame,
+ bool lastTransition )
+{
+ if( m_ignoreControllerInputs )
+ {
+ return;
+ }
+
+ if( m_p3dObject != NULL )
+ {
+ rAssert( s_p3dMultiController != NULL );
+
+ // if start and end frames are specified, set them for multicontroller
+ if( startFrame > -1 && endFrame > -1 )
+ {
+ s_p3dMultiController->SetFrameRange( (float)startFrame, (float)endFrame );
+ }
+
+ m_playTransitionAnimationLast = lastTransition;
+ if( !m_playTransitionAnimationLast )
+ {
+ // set multicontroller for p3dobject
+ s_p3dMultiController->Reset();
+ m_p3dObject->SetMultiController( s_p3dMultiController );
+ }
+
+ // increment number of pending transitions
+ m_numTransitionsPending++;
+ }
+}
+
+void
+CGuiScreen::ReloadScreen()
+{
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ this->m_ID,
+ KEEP_WINDOW_HISTORY );
+}
+
+void
+CGuiScreen::RestoreScreenCover()
+{
+ // Get screen cover, if Cover page included
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "COVER" );
+ if( pPage != NULL )
+ {
+ m_screenCover = pPage->GetLayerByIndex( 0 );
+ rAssert( m_screenCover != NULL );
+
+ m_screenCover->SetVisible( true );
+ m_screenCover->SetAlpha( 1.0f );
+ }
+}
+
+void
+CGuiScreen::RestoreButtons()
+{
+ for( int i = 0; i < NUM_BUTTON_ICONS; i++ )
+ {
+ if( m_buttonIcons[ i ] != NULL )
+ {
+ m_buttonIcons[ i ]->SetVisible( true );
+ }
+ }
+}
+
+bool
+CGuiScreen::IsWideScreenDisplay()
+{
+#ifdef RAD_XBOX
+ return p3d::display->IsWidescreen();
+#else
+ return false;
+#endif
+}
+
+void
+CGuiScreen::ApplyWideScreenCorrectionScale( Scrooby::Drawable* drawable )
+{
+ // Assumes drawable is currently screen-centered!
+ //
+ int screenWidthBy2 = static_cast<int>( Scrooby::App::GetInstance()->GetScreenWidth() ) / 2;
+
+ rAssert( drawable != NULL );
+ drawable->Translate( -screenWidthBy2, 0 );
+ drawable->Scale( WIDE_SCREEN_CORRECTION_SCALE, 1.0f, 1.0f );
+ drawable->Translate( screenWidthBy2, 0 );
+}
+
+#ifdef RAD_WIN32
+//===========================================================================
+// CGuiScreen::CheckCursorAgainstHotspots
+//===========================================================================
+// Description: Checks cursor position against its list of hotspots.
+//
+// Constraints: None.
+//
+// Parameters: float x - The x position of cursor in P3D coordinates.
+// float y - The y position of cursor in P3D coordinates.
+//
+// Return: N/A.
+//
+//===========================================================================
+eFEHotspotType CGuiScreen::CheckCursorAgainstHotspots( float x, float y )
+{
+ eFEHotspotType hotSpotType = HOTSPOT_NONE;
+ CGuiMenu* pCurrentMenu = HasMenu();
+ int numMenuItems = 0;
+ GuiMenuItem* pMenuItem = NULL;
+
+
+ if( pCurrentMenu )
+ {
+ numMenuItems = pCurrentMenu->GetNumItems();
+
+ for( int i = 0; i < numMenuItems; i++ )
+ {
+ bool bIsMenuItemEnabled = pCurrentMenu->IsMenuItemEnabled(i);
+ pMenuItem = pCurrentMenu->GetMenuItem( i );
+
+ if( pMenuItem && bIsMenuItemEnabled )
+ {
+ if( pMenuItem->GetItem()->IsVisible() )
+ {
+ // Just tests if the point is in the bounding rect of the sprite.
+ if( pMenuItem->GetItem()->IsPointInBoundingRect( x, y ) )
+ {
+ //rDebugPrintf( "Cursor is inside Sprite %d rectangle!\n", i );
+ pCurrentMenu->HandleMessage( GUI_MSG_MOUSE_OVER, i );
+ hotSpotType = HOTSPOT_BUTTON;
+
+ //After taking care of all the events for this menu item, just bail out.
+ break;
+ }
+ else if( pCurrentMenu->GetSelection() == i )
+ {
+ if( pMenuItem->m_itemValueArrowL )
+ {
+ if( pMenuItem->m_itemValueArrowL->IsPointInBoundingRect( x, y ) )
+ {
+ hotSpotType = HOTSPOT_ARROWLEFT;
+ break;
+ }
+ }
+
+ if( pMenuItem->m_itemValueArrowR )
+ {
+ if( pMenuItem->m_itemValueArrowR->IsPointInBoundingRect( x, y ) )
+ {
+ hotSpotType = HOTSPOT_ARROWRIGHT;
+ break;
+ }
+ }
+
+ if( pMenuItem->m_slider.m_pImage )
+ {
+ if( pMenuItem->m_slider.m_pImage->IsPointInBoundingRect( x, y ) )
+ {
+ hotSpotType = HOTSPOT_SLIDER;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return hotSpotType;
+}
+#endif
+
+//===========================================================================
+// Protected Member Functions
+//===========================================================================
+
+void
+CGuiScreen::RestoreDefaultFadeTime()
+{
+ m_fadeTime = DEFAULT_SCREEN_FADE_TIME;
+}
+
+void
+CGuiScreen::RestoreDefaultZoomTime()
+{
+ m_zoomTime = DEFAULT_SCREEN_ZOOM_TIME;
+}
+
+void
+CGuiScreen::IrisWipeOpen()
+{
+ rAssert( !m_autoOpenIris );
+
+ rAssert( m_irisController != NULL );
+ m_irisController->SetRelativeSpeed( DEFAULT_IRIS_WIPE_SPEED );
+
+ m_currentIrisState = IRIS_STATE_OPENING;
+}
+
+void CGuiScreen::SetAlphaForLayers( float alpha, Scrooby::Layer** layers, int numLayers )
+{
+ rAssert( layers );
+ rAssert( numLayers >= 0 );
+
+ for( int i = 0; i < numLayers; i++ )
+ {
+ layers[ i ]->SetAlpha( alpha );
+ }
+}
+
+void
+CGuiScreen::AutoScaleFrame( Scrooby::Page* pPage )
+{
+ if( pPage != NULL )
+ {
+ Scrooby::Group* pFrameGroup = pPage->GetGroup( "Frame" );
+ if( pFrameGroup != NULL )
+ {
+ const int SEGMENT_LENGTH = 40; // in pixels
+
+ Scrooby::Sprite* pFrameTop = pFrameGroup->GetSprite( "Frame_Top" );
+ rAssert( pFrameTop != NULL );
+ Scrooby::Sprite* pFrameBottom = pFrameGroup->GetSprite( "Frame_Bottom" );
+ rAssert( pFrameBottom != NULL );
+ Scrooby::Sprite* pFrameLeft = pFrameGroup->GetSprite( "Frame_Left" );
+ rAssert( pFrameLeft != NULL );
+ Scrooby::Sprite* pFrameRight = pFrameGroup->GetSprite( "Frame_Right" );
+ rAssert( pFrameRight != NULL );
+
+ int width = 0;
+ int height = 0;
+
+ // scale top and bottom frames horizontally
+ //
+ pFrameTop->GetBoundingBoxSize( width, height );
+ float scaleX = (width - SEGMENT_LENGTH) / (float)SEGMENT_LENGTH;
+
+ pFrameTop->ResetTransformation();
+ pFrameTop->ScaleAboutCenter( scaleX, 1.0f, 1.0f );
+ pFrameTop->Translate( +5, 0 );
+
+ pFrameBottom->ResetTransformation();
+ pFrameBottom->ScaleAboutCenter( scaleX, 1.0f, 1.0f );
+ pFrameBottom->Translate( +5, 0 );
+
+ // scale left and right frames vertically
+ //
+ pFrameLeft->GetBoundingBoxSize( width, height );
+ float scaleY = (height - SEGMENT_LENGTH) / (float)SEGMENT_LENGTH;
+
+ pFrameLeft->ResetTransformation();
+ pFrameLeft->ScaleAboutCenter( 1.0f, scaleY, 1.0f );
+
+ pFrameRight->ResetTransformation();
+ pFrameRight->ScaleAboutCenter( 1.0f, scaleY, 1.0f );
+
+#ifdef PAL
+ if( pPage == m_pScroobyScreen->GetPage( "BigBoard" ) )
+ {
+ pFrameGroup->ResetTransformation();
+ pFrameGroup->ScaleAboutCenter( 1.035f, 1.0f, 1.0f );
+ }
+#endif // PAL
+ }
+ }
+}
+
+//===========================================================================
+// Private Member Functions
+//===========================================================================
+
+void
+CGuiScreen::FadeIn( float elapsedTime )
+{
+ float alpha = (m_elapsedFadeTime + elapsedTime) / m_fadeTime;
+
+ if( alpha < 1.0f )
+ {
+ // for non-linear fading
+ //
+ alpha *= alpha;
+
+ this->SetAlphaForLayers( alpha,
+ m_foregroundLayers,
+ m_numForegroundLayers );
+
+ if( m_screenCover != NULL )
+ {
+ m_screenCover->SetVisible( true );
+ m_screenCover->SetAlpha( 1.0f - alpha );
+ }
+ }
+ else
+ {
+ this->SetAlphaForLayers( 1.0f,
+ m_foregroundLayers,
+ m_numForegroundLayers );
+
+ if( m_screenCover != NULL )
+ {
+ m_screenCover->SetAlpha( 0.0f );
+ }
+ }
+
+ if( m_elapsedFadeTime < m_fadeTime )
+ {
+ m_elapsedFadeTime += elapsedTime;
+ }
+ else
+ {
+ m_elapsedFadeTime = -1;
+
+ // decrement number of pending transitions
+ m_numTransitionsPending--;
+ }
+}
+
+void
+CGuiScreen::FadeOut( float elapsedTime )
+{
+ float alpha = 1.0f - (m_elapsedFadeTime + elapsedTime) / m_fadeTime;
+
+ if( alpha > 0.0f )
+ {
+ // for non-linear fading
+ //
+ alpha *= alpha;
+
+ this->SetAlphaForLayers( alpha,
+ m_foregroundLayers,
+ m_numForegroundLayers );
+
+ if( m_screenCover != NULL )
+ {
+ m_screenCover->SetVisible( true );
+ m_screenCover->SetAlpha( 1.0f - alpha );
+ }
+ }
+ else
+ {
+ this->SetAlphaForLayers( 0.0f,
+ m_foregroundLayers,
+ m_numForegroundLayers );
+
+ if( m_screenCover != NULL )
+ {
+ m_screenCover->SetAlpha( 1.0f );
+ }
+ }
+
+ if( m_elapsedFadeTime < m_fadeTime )
+ {
+ m_elapsedFadeTime += elapsedTime;
+ }
+ else
+ {
+ m_elapsedFadeTime = -1;
+
+ // decrement number of pending transitions
+ m_numTransitionsPending--;
+ }
+}
+
+void
+CGuiScreen::ZoomIn( float elapsedTime )
+{
+ rAssert( m_pScroobyScreen );
+
+ float zoomValue = (m_elapsedZoomTime + elapsedTime) / m_zoomTime;
+ rAssert( zoomValue >= 0.0f );
+
+ if( zoomValue < 1.0f )
+ {
+ // scale screen
+ m_pScroobyScreen->SetScale( zoomValue );
+
+ // apply alpha to background layers
+ this->SetAlphaForLayers( zoomValue,
+ m_backgroundLayers,
+ m_numBackgroundLayers );
+ }
+ else
+ {
+ m_pScroobyScreen->SetScale( 1.0f );
+
+ this->SetAlphaForLayers( 1.0f,
+ m_backgroundLayers,
+ m_numBackgroundLayers );
+ }
+
+ if( m_elapsedZoomTime < m_zoomTime )
+ {
+ m_elapsedZoomTime += elapsedTime;
+ }
+ else
+ {
+ m_elapsedZoomTime = -1;
+
+ // decrement number of pending transitions
+ m_numTransitionsPending--;
+ }
+}
+
+void
+CGuiScreen::ZoomOut( float elapsedTime )
+{
+ rAssert( m_pScroobyScreen );
+
+ float zoomValue = 1.0f - (m_elapsedZoomTime + elapsedTime) / m_zoomTime;
+ rAssert( zoomValue <= 1.0f );
+
+ if( zoomValue > 0.0f )
+ {
+ // scale screen
+ m_pScroobyScreen->SetScale( zoomValue );
+
+ // apply alpha to background layers
+ this->SetAlphaForLayers( zoomValue,
+ m_backgroundLayers,
+ m_numBackgroundLayers );
+ }
+ else
+ {
+ m_pScroobyScreen->SetScale( 0.0f );
+
+ this->SetAlphaForLayers( 0.0f,
+ m_backgroundLayers,
+ m_numBackgroundLayers );
+ }
+
+ if( m_elapsedZoomTime < m_zoomTime )
+ {
+ m_elapsedZoomTime += elapsedTime;
+ }
+ else
+ {
+ m_elapsedZoomTime = -1;
+
+ // decrement number of pending transitions
+ m_numTransitionsPending--;
+ }
+}
+
+void
+CGuiScreen::SlideIn( float elapsedTime )
+{
+ bool done = false;
+
+ for( int i = 0; i < m_numForegroundLayers; i++ )
+ {
+ rAssert( m_foregroundLayers[ i ] );
+
+ if( m_screenFX & SCREEN_FX_SLIDE_X )
+ {
+ done = GuiSFX::SlideX( m_foregroundLayers[ i ],
+ m_elapsedSlideTime,
+ m_slideTime,
+ true,
+ GuiSFX::SLIDE_BORDER_RIGHT );
+ }
+
+ if( m_screenFX & SCREEN_FX_SLIDE_Y )
+ {
+ done = GuiSFX::SlideY( m_foregroundLayers[ i ],
+ m_elapsedSlideTime,
+ m_slideTime,
+ true,
+ GuiSFX::SLIDE_BORDER_TOP );
+
+ if( this->IsWideScreenDisplay() )
+ {
+ this->ApplyWideScreenCorrectionScale( m_foregroundLayers[ i ] );
+ }
+ }
+ }
+
+ if( done )
+ {
+ m_elapsedSlideTime = -1;
+ m_numTransitionsPending--;
+ }
+ else
+ {
+ m_elapsedSlideTime += elapsedTime;
+ }
+}
+
+void
+CGuiScreen::SlideOut( float elapsedTime )
+{
+ bool done = false;
+
+ for( int i = 0; i < m_numForegroundLayers; i++ )
+ {
+ rAssert( m_foregroundLayers[ i ] );
+
+ if( m_screenFX & SCREEN_FX_SLIDE_X )
+ {
+ done = GuiSFX::SlideX( m_foregroundLayers[ i ],
+ m_elapsedSlideTime,
+ m_slideTime,
+ false,
+ GuiSFX::SLIDE_BORDER_LEFT );
+ }
+
+ if( m_screenFX & SCREEN_FX_SLIDE_Y )
+ {
+ done = GuiSFX::SlideY( m_foregroundLayers[ i ],
+ m_elapsedSlideTime,
+ m_slideTime,
+ false,
+ GuiSFX::SLIDE_BORDER_TOP );
+
+ if( this->IsWideScreenDisplay() )
+ {
+ this->ApplyWideScreenCorrectionScale( m_foregroundLayers[ i ] );
+ }
+ }
+ }
+
+ if( done )
+ {
+ m_elapsedSlideTime = -1;
+ m_numTransitionsPending--;
+ }
+ else
+ {
+ m_elapsedSlideTime += elapsedTime;
+ }
+}
+
+void
+CGuiScreen::OnIrisWipeClosed()
+{
+ if( m_autoOpenIris )
+ {
+ this->IrisWipeOpen();
+ }
+ else
+ {
+ rAssert( m_irisController != NULL );
+ m_irisController->SetRelativeSpeed( 0.0f );
+
+ m_currentIrisState = IRIS_STATE_CLOSED;
+ }
+}
+
+#ifdef DEBUGWATCH
+const char* CGuiScreen::GetWatcherName() const
+{
+ return "No Name";
+}
+#endif \ No newline at end of file
diff --git a/game/code/presentation/gui/guiscreen.h b/game/code/presentation/gui/guiscreen.h
new file mode 100644
index 0000000..3d82cd2
--- /dev/null
+++ b/game/code/presentation/gui/guiscreen.h
@@ -0,0 +1,234 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreen
+//
+// Description:
+//
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/09/20 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREEN_H
+#define GUISCREEN_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiwindow.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiManager;
+class tMultiController;
+
+namespace Scrooby
+{
+ class Screen;
+ class Page;
+ class Layer;
+ class Group;
+ class Drawable;
+ class Sprite;
+ class Text;
+ class Polygon;
+ class Pure3dObject;
+}
+
+//class tCameraAnimationController;
+
+const int MAX_FOREGROUND_LAYERS = 8;
+const int MAX_BACKGROUND_LAYERS = 2;
+
+enum eScreenEffect
+{
+ SCREEN_FX_ALL = ~0,
+ SCREEN_FX_NONE = 0,
+
+ SCREEN_FX_FADE = 1,
+ SCREEN_FX_ZOOM = 2,
+ SCREEN_FX_SLIDE_X = 4,
+ SCREEN_FX_SLIDE_Y = 8,
+ SCREEN_FX_IRIS = 16,
+
+ NUM_SCREEN_FX
+};
+
+enum eButtonIcon
+{
+ BUTTON_ICON_ACCEPT,
+ BUTTON_ICON_BACK,
+
+ NUM_BUTTON_ICONS
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreen : public CGuiWindow
+{
+ public:
+
+ CGuiScreen( Scrooby::Screen* pScroobyScreen,
+ CGuiEntity* pParent,
+ eGuiWindowID id,
+ unsigned int screenFX = SCREEN_FX_FADE );
+
+ virtual ~CGuiScreen();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ void SetScroobyScreen( Scrooby::Screen* pScreen ) { m_pScroobyScreen = pScreen; }
+ Scrooby::Screen* GetScroobyScreen() const { return m_pScroobyScreen; }
+
+ virtual CGuiMenu* HasMenu() { return NULL; }
+
+ void SetFadingEnabled( bool enable );
+ void SetZoomingEnabled( bool enable );
+ void SetSlidingEnabled( eScreenEffect slideType, bool enable );
+ void SetIrisWipeEnabled( bool enable, bool autoOpenIris = false );
+
+ bool IsEffectEnabled( eScreenEffect effect ) const;
+
+ static void Reset3dFEMultiController();
+
+ void SetIngoreControllerInputs( bool ignore ) { m_ignoreControllerInputs = ignore; }
+ bool IsIgnoringControllerInputs() const { return m_ignoreControllerInputs; }
+
+ void SetButtonVisible( eButtonIcon button, bool isVisible );
+ bool IsButtonVisible( eButtonIcon button ) const;
+
+ void StartTransitionAnimation( int startFrame = -1,
+ int endFrame = -1,
+ bool lastTransition = true );
+
+ void ReloadScreen();
+ void RestoreScreenCover();
+ void RestoreButtons();
+
+ static bool IsWideScreenDisplay();
+ static void ApplyWideScreenCorrectionScale( Scrooby::Drawable* drawable );
+
+#ifdef RAD_WIN32
+ virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y );
+#endif
+
+ protected:
+
+ //---------------------------------------------------------------------
+ // Protected Functions
+ //---------------------------------------------------------------------
+
+ void SetFadeTime( float fadeTime ) { m_fadeTime = fadeTime; }
+ void RestoreDefaultFadeTime();
+
+ void SetZoomTime( float zoomTime ) { m_zoomTime = zoomTime; }
+ void RestoreDefaultZoomTime();
+
+ void IrisWipeOpen();
+
+ void SetAlphaForLayers( float alpha,
+ Scrooby::Layer** layers,
+ int numLayers );
+
+ void AutoScaleFrame( Scrooby::Page* pPage );
+ #ifdef DEBUGWATCH
+ virtual const char* GetWatcherName() const;
+ #endif
+
+ //---------------------------------------------------------------------
+ // Protected Data
+ //---------------------------------------------------------------------
+
+ CGuiManager* m_guiManager;
+
+ Scrooby::Screen* m_pScroobyScreen;
+ Scrooby::Layer* m_screenCover;
+ Scrooby::Pure3dObject* m_p3dObject;
+
+ static tMultiController* s_p3dMultiController;
+
+ enum eIrisState
+ {
+ IRIS_STATE_IDLE,
+ IRIS_STATE_CLOSING,
+ IRIS_STATE_CLOSED,
+ IRIS_STATE_OPENING,
+
+ NUM_IRIS_STATES
+ };
+
+ Scrooby::Pure3dObject* m_p3dIris;
+ tMultiController* m_irisController;
+ eIrisState m_currentIrisState;
+ bool m_autoOpenIris : 1;
+
+ Scrooby::Layer* m_foregroundLayers[ MAX_FOREGROUND_LAYERS ];
+ int m_numForegroundLayers;
+
+ Scrooby::Layer* m_backgroundLayers[ MAX_BACKGROUND_LAYERS ];
+ int m_numBackgroundLayers;
+
+ Scrooby::Group* m_buttonIcons[ NUM_BUTTON_ICONS ];
+
+ bool m_ignoreControllerInputs : 1;
+ bool m_inverseFading : 1;
+
+ private:
+
+ //---------------------------------------------------------------------
+ // Private Functions
+ //---------------------------------------------------------------------
+
+ // No copying or asignment. Declare but don't define.
+ //
+ CGuiScreen( const CGuiScreen& );
+ CGuiScreen& operator= ( const CGuiScreen& );
+
+ // Screen Fade In/Out Effects
+ void FadeIn( float elapsedTime );
+ void FadeOut( float elapsedTime );
+
+ // Screen Zoom In/Out Effects
+ void ZoomIn( float elapsedTime );
+ void ZoomOut( float elapsedTime );
+
+ // Screen Slide In/Out Effects
+ void SlideIn( float elapsedTime );
+ void SlideOut( float elapsedTime );
+
+ // Iris Wipe Closed
+ //
+ void OnIrisWipeClosed();
+
+ //---------------------------------------------------------------------
+ // Private Data
+ //---------------------------------------------------------------------
+
+ static float s_numIrisFrames;
+
+ unsigned int m_screenFX; // bit mask for screen effects
+
+ float m_fadeTime;
+ float m_elapsedFadeTime;
+
+ float m_zoomTime;
+ float m_elapsedZoomTime;
+
+ float m_slideTime;
+ float m_elapsedSlideTime;
+
+ bool m_playTransitionAnimationLast : 1;
+
+};
+
+#endif // GUISCREEN_H
diff --git a/game/code/presentation/gui/guiscreenmemcardcheck.cpp b/game/code/presentation/gui/guiscreenmemcardcheck.cpp
new file mode 100644
index 0000000..71ccab6
--- /dev/null
+++ b/game/code/presentation/gui/guiscreenmemcardcheck.cpp
@@ -0,0 +1,518 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMemCardCheck
+//
+// Description: Implementation of the CGuiScreenMemCardCheck class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/guiscreenmemcardcheck.h>
+#include <presentation/gui/guiscreenmemorycard.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/frontend/guiscreenloadgame.h>
+#include <presentation/gui/guiscreenprompt.h>
+
+#include <main/game.h>
+#include <main/platform.h>
+#include <memory/createheap.h>
+
+#include <raddebug.hpp> // Foundation
+#include <layer.h>
+#include <page.h>
+#include <screen.h>
+#include <text.h>
+
+#ifdef RAD_GAMECUBE
+#include <main/gamecube_extras/gcmanager.h>
+#endif
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+#ifndef RAD_E3
+ // This will enable auto-loading the most recent saved game immediately
+ // after the memory card check.
+ //
+ #define ENABLE_AUTOLOAD_AFTER_MEMCHECK
+#endif
+
+enum eMemCardCheckMessage
+{
+ CHECKING_MEMCARDS_GC,
+ CHECKING_MEMCARD_B_GC,
+ CHECKING_MEMCARDS_PS2,
+ CHECKING_MEMCARD_2_PS2,
+ CHECKING_HARDDISK_XBOX,
+ CHECKING_HARDDISK_PC,
+
+ NUM_MEMCARD_CHECK_MESSAGES
+};
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenMemCardCheck::CGuiScreenMemCardCheck
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMemCardCheck::CGuiScreenMemCardCheck
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MEMORY_CARD_CHECK ),
+ m_messageText( NULL ),
+ m_minimumFormatTime(1000),
+ m_formatState(false),
+ m_StatusPromptShown(false),
+ m_isAutoLoadPending( false )
+{
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "MemCardCheck" );
+ rAssert( pPage );
+
+ Scrooby::Layer* foreground = pPage->GetLayer( "Foreground" );
+
+ m_messageText = foreground->GetText( "CheckingMemoryCards" );
+ rAssert( m_messageText );
+ m_messageText->SetTextMode( Scrooby::TEXT_WRAP );
+
+#ifdef RAD_GAMECUBE
+ m_messageText->SetIndex( CHECKING_MEMCARDS_GC );
+#endif
+
+#ifdef RAD_PS2
+ m_messageText->SetIndex( CHECKING_MEMCARDS_PS2 );
+
+ #ifndef PAL
+ // no need to display checking message on PS2
+ //
+ m_messageText->SetVisible( false );
+ this->SetFadingEnabled( false );
+ #endif
+#endif
+
+#ifdef RAD_XBOX
+ m_messageText->SetIndex( CHECKING_HARDDISK_XBOX );
+#endif
+
+#ifdef RAD_WIN32
+ m_messageText->SetIndex( CHECKING_HARDDISK_PC );
+ // no need to display checking message on WIN32
+ m_messageText->SetVisible( false );
+ this->SetFadingEnabled( false );
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenMemCardCheck::~CGuiScreenMemCardCheck
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMemCardCheck::~CGuiScreenMemCardCheck()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenMemCardCheck::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMemCardCheck::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if (message == GUI_MSG_MESSAGE_UPDATE)
+ {
+ if (m_formatState)
+ {
+ m_elapsedFormatTime += param1;
+
+ if (m_elapsedFormatTime > m_minimumFormatTime && m_formatDone)
+ {
+ m_StatusPromptShown = true;
+ if( m_formatResult == Success )
+ {
+ m_guiManager->DisplayPrompt(PROMPT_FORMAT_SUCCESS_GC + PLATFORM_TEXT_INDEX, this, PROMPT_TYPE_CONTINUE); // format success
+ m_formatState = false;
+ }
+ else if (m_formatResult)
+ {
+ m_guiManager->DisplayPrompt(PROMPT_FORMAT_FAIL_GC + PLATFORM_TEXT_INDEX, this, PROMPT_TYPE_CONTINUE); // format fail
+ m_formatState = false;
+ }
+ }
+ }
+ }
+ else if (message == GUI_MSG_PROMPT_UPDATE)
+ {
+#if defined( RAD_GAMECUBE ) || defined( RAD_PS2 )
+ // detect memcard unplugged in prompt
+ // update so status up to date
+ GetMemoryCardManager()->Update( param1 );
+ if (m_StatusPromptShown==false) { // check for user unplugging memcard if not showing status
+
+ if( !GetMemoryCardManager()->IsCurrentDrivePresent(CGuiScreenMemoryCard::s_currentMemoryCardSlot) )
+ ReloadScreen();
+ }
+#endif
+ }
+ else if ( message == GUI_MSG_MENU_PROMPT_RESPONSE || message == GUI_MSG_ERROR_PROMPT_RESPONSE)
+ {
+ switch ( param1 )
+ {
+ case PROMPT_FORMAT_SUCCESS_GC:
+ case PROMPT_FORMAT_SUCCESS_PS2:
+ case PROMPT_FORMAT_SUCCESS_XBOX: // format ok
+ this->OnContinue();
+ break;
+
+ case PROMPT_FORMAT_FAIL_GC:
+ case PROMPT_FORMAT_FAIL_PS2:
+ case PROMPT_FORMAT_FAIL_XBOX: // format fail
+ this->ReloadScreen(); // user has to retry
+
+ GetMemoryCardManager()->ClearCurrentDrive();
+ break;
+ case PROMPT_FORMAT_CONFIRM2_GC:
+ case PROMPT_FORMAT_CONFIRM2_PS2:
+ case PROMPT_FORMAT_CONFIRM2_XBOX: // really format
+ if (param2==CGuiMenuPrompt::RESPONSE_YES)
+ {
+ m_guiManager->DisplayMessage(CGuiScreenMessage::MSG_ID_FORMATTING_GC + PLATFORM_TEXT_INDEX, this);
+ m_formatState = true;
+ m_elapsedFormatTime = 0;
+ m_formatDone = false;
+ GetMemoryCardManager()->FormatDrive(CGuiScreenMemoryCard::s_currentMemoryCardSlot, this);
+ }
+ else
+ {
+ this->ReloadScreen(); // user has to retry
+ GetMemoryCardManager()->ClearCurrentDrive();
+ }
+ break;
+
+ default:
+ switch( param2 )
+ {
+ case (CGuiMenuPrompt::RESPONSE_YES):
+ case (CGuiMenuPrompt::RESPONSE_CONTINUE):
+ case (CGuiMenuPrompt::RESPONSE_CONTINUE_WITHOUT_SAVE):
+ {
+ /*
+ if( GetMemoryCardManager()->GetMemcardCheckingState() != MemoryCardManager::MEMCARD_CHECKING_DONE )
+ {
+ rAssert( m_messageText );
+ #ifdef RAD_GAMECUBE
+ m_messageText->SetIndex( CHECKING_MEMCARD_B_GC );
+ #endif
+ #ifdef RAD_PS2
+ m_messageText->SetIndex( CHECKING_MEMCARD_2_PS2 );
+ #endif
+ this->ReloadScreen();
+ }
+ else
+ */
+ this->OnContinue();
+
+ break;
+ }
+ case (CGuiMenuPrompt::RESPONSE_NO):
+ case (CGuiMenuPrompt::RESPONSE_RETRY):
+ {
+ /*
+ GetMemoryCardManager()->ResetMemoryCardCheck();
+
+ rAssert( m_messageText );
+ #ifdef RAD_GAMECUBE
+ m_messageText->SetIndex( CHECKING_MEMCARDS_GC );
+ #endif
+ #ifdef RAD_PS2
+ m_messageText->SetIndex( CHECKING_MEMCARDS_PS2 );
+ #endif
+ */
+ this->ReloadScreen();
+
+ break;
+ }
+ case (CGuiMenuPrompt::RESPONSE_FORMAT_GC):
+ case (CGuiMenuPrompt::RESPONSE_FORMAT_XBOX):
+ case (CGuiMenuPrompt::RESPONSE_FORMAT_PS2):
+ {
+ m_StatusPromptShown = false;
+ m_guiManager->DisplayPrompt(PROMPT_FORMAT_CONFIRM2_GC + PLATFORM_TEXT_INDEX,this);
+ break;
+ }
+ case (CGuiMenuPrompt::RESPONSE_MANAGE_MEMCARDS):
+ {
+ #ifdef RAD_GAMECUBE
+ GCManager::GetInstance()->Reset();
+ GCManager::GetInstance()->PerformReset( true, true );
+ #else
+ IRadMemoryAllocator* allocator = GetAllocator( GMA_PERSISTENT );
+ IRadMemoryHeap* staticHeap = dynamic_cast< IRadMemoryHeap* >( allocator );
+ staticHeap->AllowFreeing( true );
+ GetGame()->GetPlatform()->LaunchDashboard();
+ #endif
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ GetMemoryCardManager()->UpdateMemoryCardCheck( param1 );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+void
+CGuiScreenMemCardCheck::OnFormatOperationComplete( radFileError errorCode )
+{
+ if (m_formatDone != true) // check if we already received an error or not
+ m_formatResult = errorCode;
+ m_formatDone = true;
+}
+
+void
+CGuiScreenMemCardCheck::OnMemoryCardCheckDone( radFileError errorCode,
+ IRadDrive::MediaInfo::MediaState mediaState,
+ int driveIndex,
+ int mostRecentSaveGameDriveIndex,
+ int mostRecentSaveGameSlot )
+{
+#ifdef RAD_WIN32
+ GetMemoryCardManager()->SetCurrentDrive( static_cast<unsigned int>( 0 ) );
+#endif
+
+#ifdef ENABLE_AUTOLOAD_AFTER_MEMCHECK
+ if( mostRecentSaveGameSlot != -1 )
+ {
+ CGuiScreenMemoryCard::s_currentMemoryCardSlot = mostRecentSaveGameDriveIndex;
+ GetMemoryCardManager()->SetCurrentDrive( static_cast<unsigned int>( mostRecentSaveGameDriveIndex ) );
+
+ CGuiScreenAutoLoad::SetGameSlot( mostRecentSaveGameSlot );
+
+ m_isAutoLoadPending = true;
+ }
+#endif
+
+ if( errorCode == Success && mediaState == IRadDrive::MediaInfo::MediaPresent )
+ {
+ this->OnContinue();
+ }
+ else
+ {
+ CGuiScreenMemoryCard::s_currentMemoryCardSlot = driveIndex;
+
+ m_StatusPromptShown = true;
+
+ int errorMessage = -1;
+ if( mediaState != IRadDrive::MediaInfo::MediaPresent )
+ {
+ errorMessage = GetErrorMessageIndex( mediaState );
+ }
+ else if( errorCode != Success )
+ {
+ errorMessage = GetErrorMessageIndex( errorCode, ERROR_DURING_CHECKING );
+ }
+
+ int format_response = 0;
+
+ // TC: (PS2 TRC) formatting should NOT be offered to the user during the
+ // boot-up check, but only during save contexts
+ //
+#ifndef RAD_PS2
+ if (mediaState==IRadDrive::MediaInfo::MediaNotFormatted)
+ format_response = ERROR_RESPONSE_FORMAT;
+#endif
+
+#ifdef RAD_GAMECUBE
+ if( mediaState == IRadDrive::MediaInfo::MediaEncodingErr )
+ {
+ format_response = ERROR_RESPONSE_FORMAT;
+ }
+#endif
+
+ rAssert( errorMessage != -1 );
+
+#ifdef RAD_GAMECUBE
+ int manage_response = ERROR_RESPONSE_MANAGE;
+
+ if (mediaState == IRadDrive::MediaInfo::MediaNotPresent
+ || mediaState == IRadDrive::MediaInfo::MediaInvalid
+ || mediaState == IRadDrive::MediaInfo::MediaDamaged)
+ manage_response = 0; // no manage when no memory card
+ if (format_response)
+ manage_response = 0; // don't show both format and manage
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ format_response | manage_response | ERROR_RESPONSE_CONTINUE_WITHOUT_SAVE | ERROR_RESPONSE_RETRY );
+#endif // RAD_GAMECUBE
+
+#ifdef RAD_PS2
+ // add retry if card full, or no card
+ if( errorCode == NoFreeSpace || mediaState == IRadDrive::MediaInfo::MediaNotPresent)
+ {
+ m_guiManager->DisplayErrorPrompt( errorMessage, this, ERROR_RESPONSE_CONTINUE_WITHOUT_SAVE | ERROR_RESPONSE_RETRY );
+ }
+ else
+ {
+ if (format_response)
+ { // detect unplugged if we are asking for format
+ m_StatusPromptShown = false;
+ }
+ m_guiManager->DisplayErrorPrompt( errorMessage, this, format_response | ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY);
+ }
+#endif // RAD_PS2
+
+#ifdef RAD_XBOX
+ m_guiManager->DisplayErrorPrompt( errorMessage, this, ERROR_RESPONSE_CONTINUE );
+#endif // RAD_XBOX
+
+#ifdef RAD_WIN32 //parallel the xbox for now.
+ m_guiManager->DisplayErrorPrompt( errorMessage, this, ERROR_RESPONSE_CONTINUE );
+#endif // RAD_WIN32
+ }
+}
+
+//===========================================================================
+// CGuiScreenMemCardCheck::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMemCardCheck::InitIntro()
+{
+ if( m_firstTimeEntered )
+ {
+ GetMemoryCardManager()->LoadMemcardInfo();
+ }
+ m_StatusPromptShown = false;
+}
+
+
+//===========================================================================
+// CGuiScreenMemCardCheck::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMemCardCheck::InitRunning()
+{
+ GetMemoryCardManager()->StartMemoryCardCheck( this );
+}
+
+
+//===========================================================================
+// CGuiScreenMemCardCheck::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMemCardCheck::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenMemCardCheck::OnContinue()
+{
+ GetMemoryCardManager()->UnloadMemcardInfo();
+
+#ifdef RAD_PS2
+ bool isCurrentDriveReady = true;
+#else
+ bool isCurrentDriveReady = GetMemoryCardManager()->IsCurrentDriveReady( true );
+#endif
+
+ if( m_isAutoLoadPending && isCurrentDriveReady )
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_AUTO_LOAD, CLEAR_WINDOW_HISTORY );
+ }
+ else
+ {
+ m_pParent->HandleMessage( GUI_MSG_MEMCARD_CHECK_COMPLETED );
+ }
+
+ m_isAutoLoadPending = false;
+}
+
diff --git a/game/code/presentation/gui/guiscreenmemcardcheck.h b/game/code/presentation/gui/guiscreenmemcardcheck.h
new file mode 100644
index 0000000..4183829
--- /dev/null
+++ b/game/code/presentation/gui/guiscreenmemcardcheck.h
@@ -0,0 +1,74 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMemCardCheck
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/23 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMEMCARDCHECK_H
+#define GUISCREENMEMCARDCHECK_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <data/memcard/memorycardmanager.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMemCardCheck : public CGuiScreen,
+ public IMemoryCardCheckCallback,
+ public IMemoryCardFormatCallback
+{
+public:
+ CGuiScreenMemCardCheck( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenMemCardCheck();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual void OnMemoryCardCheckDone( radFileError errorCode,
+ IRadDrive::MediaInfo::MediaState mediaState,
+ int driveIndex,
+ int mostRecentSaveGameDriveIndex,
+ int mostRecentSaveGameSlot );
+
+ // Implements IMemoryCardFormatCallback
+ //
+ virtual void OnFormatOperationComplete(radFileError err);
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ void OnContinue();
+
+ Scrooby::Text* m_messageText;
+
+ unsigned int m_minimumFormatTime;
+ unsigned int m_elapsedFormatTime;
+ radFileError m_formatResult;
+ bool m_formatState : 1;
+ bool m_formatDone : 1;
+ bool m_StatusPromptShown : 1;
+ bool m_isAutoLoadPending : 1;
+
+};
+
+#endif // GUISCREENMEMCARDCHECK_H
diff --git a/game/code/presentation/gui/guiscreenmemorycard.cpp b/game/code/presentation/gui/guiscreenmemorycard.cpp
new file mode 100644
index 0000000..fe85922
--- /dev/null
+++ b/game/code/presentation/gui/guiscreenmemorycard.cpp
@@ -0,0 +1,920 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMemoryCard
+//
+// Description: Implementation of the CGuiScreenMemoryCard class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/guiscreenmemorycard.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/gui/guiscreenprompt.h>
+#include <presentation/gui/guimanager.h>
+
+#include <data/gamedatamanager.h>
+#include <data/memcard/memorycardmanager.h>
+#include <events/eventmanager.h>
+#include <gameflow/gameflow.h>
+#include <memory/srrmemory.h>
+
+#include <raddebug.hpp> // Foundation
+#include <layer.h>
+#include <group.h>
+#include <page.h>
+#include <screen.h>
+#include <strings/unicodestring.h>
+#include <text.h>
+#ifdef RAD_PS2
+#include <libmtap.h>
+#endif
+
+const tColour DEFAULT_DISABLED_ITEM_COLOUR_GREY( 128, 128, 128 ); // the same as in guimenu.cpp
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+enum eMemoryCardMenuItem
+{
+ MENU_ITEM_MEMORY_DEVICE,
+
+ NUM_MEMORY_CARD_MENU_ITEMS
+};
+
+bool CGuiScreenLoadSave::s_forceGotoMemoryCardScreen = false;
+
+int CGuiScreenMemoryCard::s_currentMemoryCardSlot = 0;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+CGuiScreenLoadSave::CGuiScreenLoadSave( Scrooby::Screen* pScreen )
+: m_currentSlot( -1 ),
+ m_lastError( Success ),
+ m_currentMemoryDevice( NULL ),
+ m_currentDriveIndex( -1 ),
+ m_minimumFormatTime(1000),
+ m_formatState(false),
+ m_operation( SCREEN_OP_IDLE )
+{
+ rAssert( pScreen != NULL );
+#ifdef RAD_WIN32
+ Scrooby::Page* pPage = pScreen->GetPage( "GameSlots" );
+ if( pPage != NULL )
+ {
+ Scrooby::Text* pText = pPage->GetText( "LoadSaveMessage" );
+ if( pText != NULL )
+ {
+ pText->SetTextMode( Scrooby::TEXT_WRAP );
+ }
+ }
+#else
+ Scrooby::Page* pPage = pScreen->GetPage( "SelectMemoryDevice" );
+ if( pPage != NULL )
+ {
+ Scrooby::Layer* foreground = pPage->GetLayer( "Foreground" );
+ Scrooby::Text* pText = foreground->GetText( "LoadSave" );
+ if( pText != NULL )
+ {
+ pText->SetTextMode( Scrooby::TEXT_WRAP );
+ }
+
+ m_currentMemoryDevice = foreground->GetText( "CurrentMemoryDevice" );
+ rAssert( m_currentMemoryDevice != NULL );
+ m_currentMemoryDevice->SetTextMode( Scrooby::TEXT_WRAP );
+
+ // set platform-specific text
+ //
+ Scrooby::Group* selectMemoryDevice = foreground->GetGroup( "SelectMemoryDevice" );
+ rAssert( selectMemoryDevice != NULL );
+
+#ifdef RAD_XBOX
+ selectMemoryDevice->SetVisible( false );
+#endif
+
+ pText = selectMemoryDevice->GetText( "SelectMemoryDevice" );
+ if( pText != NULL )
+ {
+ pText->SetIndex( PLATFORM_TEXT_INDEX );
+
+ // and apply wrapping
+ //
+ pText->SetTextMode( Scrooby::TEXT_WRAP );
+ }
+ }
+#endif
+}
+
+CGuiScreenLoadSave::~CGuiScreenLoadSave()
+{
+}
+
+void
+CGuiScreenLoadSave::HandleMessage( eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2 )
+{
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ GetMemoryCardManager()->Update( param1 );
+
+ if( !GetMemoryCardManager()->IsCurrentDriveReady() )
+ {
+ this->GotoMemoryCardScreen();
+
+ return;
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_AUX_X:
+ {
+#if defined( RAD_GAMECUBE ) || defined( RAD_PS2 )
+ this->GotoMemoryCardScreen();
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT );
+#endif
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+void
+CGuiScreenLoadSave::FormatCurrentDrive()
+{
+ m_formatState = true;
+ m_elapsedFormatTime = 0;
+ int currentDrive = GetMemoryCardManager()->GetCurrentDriveIndex();
+ m_formatDone = false;
+ GetMemoryCardManager()->FormatDrive(currentDrive, this);
+}
+
+void
+CGuiScreenLoadSave::OnFormatOperationComplete( radFileError errorCode )
+{
+ if (m_formatDone != true) // check if we already received an error or not
+ m_formatResult = errorCode;
+ m_formatDone = true;
+}
+
+void
+CGuiScreenLoadSave::UpdateCurrentMemoryDevice()
+{
+#ifndef RAD_WIN32
+ IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive();
+ if( currentDrive != NULL )
+ {
+ char textBibleEntry[ 32 ];
+#ifdef RAD_GAMECUBE
+ sprintf( textBibleEntry, "GC_%s", currentDrive->GetDriveName() );
+#endif
+#ifdef RAD_PS2
+ sprintf( textBibleEntry, "PS2_MEMCARD1A:" );
+#endif
+#ifdef RAD_XBOX
+ sprintf( textBibleEntry, "XBOX_%s", currentDrive->GetDriveName() );
+#endif
+
+ HeapMgr()->PushHeap( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ?
+ GMA_LEVEL_FE : GMA_LEVEL_HUD );
+
+ UnicodeString deviceName;
+ deviceName.ReadUnicode( GetTextBibleString( textBibleEntry ) );
+
+#ifdef RAD_PS2
+ int port_number = CGuiScreenMemoryCard::s_currentMemoryCardSlot/4;
+ if (sceMtapGetConnection(port_number)==1) { // is multitap
+ deviceName.Append('1' + (CGuiScreenMemoryCard::s_currentMemoryCardSlot/4));
+ deviceName.Append('-' );
+ deviceName.Append('A' + (CGuiScreenMemoryCard::s_currentMemoryCardSlot%4));
+ }
+ else {
+ deviceName.Append('1' + (CGuiScreenMemoryCard::s_currentMemoryCardSlot/4));
+ }
+#endif
+#ifdef RAD_XBOX
+ const char *volname = GetMemoryCardManager()->GetCurrentDriveVolumeName();
+ UnicodeString muName;
+ if (volname[0]!=0)
+ {
+ if (p3d::UnicodeStrLen((P3D_UNICODE*)( volname ) ) < MAX_MEM_CARD_NAME)
+ muName.ReadUnicode((P3D_UNICODE*) volname );
+ else
+ {
+ muName.ReadUnicode((P3D_UNICODE*) volname, MAX_MEM_CARD_NAME-1);
+ UnicodeString ellipsis;
+ ellipsis.ReadAscii("...");
+ muName += ellipsis;
+ }
+ deviceName.Append(' ');
+ deviceName.Append('(');
+ deviceName += muName;
+ deviceName.Append(')');
+ }
+#endif
+
+ rAssert( m_currentMemoryDevice != NULL );
+ m_currentMemoryDevice->SetString( 0, deviceName );
+
+ HeapMgr()->PopHeap(GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ?
+ GMA_LEVEL_FE : GMA_LEVEL_HUD);
+ }
+#endif
+
+ // update current drive index
+ //
+ m_currentDriveIndex = GetMemoryCardManager()->GetCurrentDriveIndex();
+}
+
+void
+CGuiScreenLoadSave::HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response )
+{
+}
+
+
+//===========================================================================
+// CGuiScreenMemoryCard::CGuiScreenMemoryCard
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMemoryCard::CGuiScreenMemoryCard
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MEMORY_CARD,
+ SCREEN_FX_FADE | SCREEN_FX_SLIDE_Y ),
+ m_layerSelectMemoryDevice( NULL ),
+ m_layerNoMemoryDevice( NULL ),
+#ifdef RAD_XBOX
+ m_numFreeBlocks( NULL ),
+#endif
+ m_pMenu( NULL ),
+ m_numAttachedDevices( -1 )
+{
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage;
+ pPage = m_pScroobyScreen->GetPage( "MemoryCard" );
+ rAssert( pPage );
+
+ m_layerSelectMemoryDevice = pPage->GetGroup( "SelectMemoryDevice" );
+ rAssert( m_layerSelectMemoryDevice );
+ m_layerSelectMemoryDevice->SetVisible( false );
+
+ m_layerNoMemoryDevice = pPage->GetGroup( "NoMemoryDevice" );
+ rAssert( m_layerNoMemoryDevice );
+ m_layerNoMemoryDevice->SetVisible( false );
+
+ m_memStatusText = pPage->GetText("Status");
+ rAssert(m_memStatusText);
+
+ m_memStatusText->SetTextMode( Scrooby::TEXT_WRAP );
+
+#ifdef RAD_XBOX
+ Scrooby::Group* freeSpace = pPage->GetGroup( "FreeSpace" );
+ rAssert( freeSpace != NULL );
+ m_numFreeBlocks = freeSpace->GetText( "NumFreeBlocks" );
+#else
+ // hide free space display for non-Xbox platforms
+ //
+ Scrooby::Group* freeSpace = pPage->GetGroup( "FreeSpace" );
+ rAssert( freeSpace != NULL );
+ freeSpace->SetVisible( false );
+#endif
+
+ // set platform-specific text
+ //
+ Scrooby::Text* pText = m_layerSelectMemoryDevice->GetText( "SelectMemoryDevice" );
+ if( pText != NULL )
+ {
+ pText->SetIndex( PLATFORM_TEXT_INDEX );
+
+ // and apply wrapping
+ //
+ pText->SetTextMode( Scrooby::TEXT_WRAP );
+ }
+
+ pText = m_layerNoMemoryDevice->GetText( "NoMemoryDevice" );
+ if( pText != NULL )
+ {
+ pText->SetIndex( PLATFORM_TEXT_INDEX );
+
+ // and apply wrapping
+ //
+ pText->SetTextMode( Scrooby::TEXT_WRAP );
+ }
+
+ pText = m_layerSelectMemoryDevice->GetText( "MemoryDevice" );
+ if( pText != NULL )
+ {
+ pText->SetTextMode( Scrooby::TEXT_WRAP );
+ }
+
+ // Create a menu.
+ //
+ m_pMenu = new CGuiMenu( this, NUM_MEMORY_CARD_MENU_ITEMS, GUI_TEXT_MENU, MENU_SFX_NONE );
+ rAssert( m_pMenu != NULL );
+
+ // Add menu items
+ //
+ Scrooby::Group* selectMemoryDevice = pPage->GetGroup( "SelectMemoryDevice" );
+ m_pMenu->AddMenuItem( selectMemoryDevice->GetText( "SelectMemoryDevice" ),
+ selectMemoryDevice->GetText( "MemoryDevice" ),
+ NULL,
+ NULL,
+ selectMemoryDevice->GetSprite( "LArrow" ),
+ selectMemoryDevice->GetSprite( "RArrow" ) );
+
+ Scrooby::Text * selectDeviceText = selectMemoryDevice->GetText( "SelectMemoryDevice" );
+ selectDeviceText->SetTextMode( Scrooby::TEXT_WRAP );
+
+ this->AutoScaleFrame( m_pScroobyScreen->GetPage( "BigBoard" ) );
+#ifdef RAD_XBOX
+ for(int j = 0; j < radFileDriveMax; j++ )
+ {
+ m_driveMountedFlag[j] = NULL;
+ }
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenMemoryCard::~CGuiScreenMemoryCard
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMemoryCard::~CGuiScreenMemoryCard()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMemoryCard::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMemoryCard::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if ( message==GUI_MSG_PROMPT_START_RESPONSE )
+ {
+ m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME );
+ }
+ else if( m_state == GUI_WINDOW_STATE_RUNNING || message == GUI_MSG_MENU_PROMPT_RESPONSE)
+ {
+ switch( message )
+ {
+ #ifdef RAD_PS2
+ case GUI_MSG_CONTROLLER_START:
+ {
+ if ( GetGameFlow()->GetCurrentContext() == CONTEXT_PAUSE )
+ m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME );
+
+ break;
+ }
+ #endif
+ case GUI_MSG_UPDATE:
+ {
+ GetMemoryCardManager()->Update( param1 );
+
+ this->UpdateDeviceList();
+
+ break;
+ }
+
+ case GUI_MSG_MENU_SELECTION_VALUE_CHANGED:
+ {
+ rAssert( param1 == MENU_ITEM_MEMORY_DEVICE );
+
+ this->UpdateFreeSpace( param2 );
+
+ break;
+ }
+
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ rAssert( param1 == MENU_ITEM_MEMORY_DEVICE );
+
+ int selectedDevice = m_pMenu->GetSelectionValue( MENU_ITEM_MEMORY_DEVICE );
+
+#ifdef RAD_XBOX
+ // check if user selected full xbox hd
+ if ( selectedDevice==0
+ && !GetMemoryCardManager()->EnoughFreeSpace( 0 )
+ && !GetGameDataManager()->DoesSaveGameExist(m_availableDrives[ 0 ], false) )
+ {
+ m_guiManager->DisplayPrompt(PROMPT_HD_FULL_XBOX, this, PROMPT_TYPE_CONTINUE);
+
+ break;
+ }
+#endif
+ GetMemoryCardManager()->SetCurrentDrive( m_availableDrives[ selectedDevice ] );
+
+ s_currentMemoryCardSlot = GetMemoryCardManager()->GetCurrentDriveIndex();
+
+ CGuiScreenLoadSave::s_forceGotoMemoryCardScreen = false;
+
+ m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN );
+
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ if( !GetMemoryCardManager()->IsCurrentDriveReady( true ) ||
+ CGuiScreenLoadSave::s_forceGotoMemoryCardScreen )
+ {
+ if( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND )
+ {
+ this->StartTransitionAnimation( 230, 260 );
+ }
+
+ m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN, 1 );
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK );
+ }
+
+ break;
+ }
+ case GUI_MSG_MENU_PROMPT_RESPONSE:
+ {
+ ReloadScreen();
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenMemoryCard::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMemoryCard::InitIntro()
+{
+
+
+ this->UpdateDeviceList( true );
+
+ // set selection to current device, if still attached
+ //
+ IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive();
+ if( currentDrive != NULL )
+ {
+ if( GetMemoryCardManager()->IsCurrentDriveReady( true ) )
+ {
+ for( int i = 0; i < m_numAttachedDevices; i++ )
+ {
+ if( m_availableDrives[ i ] == currentDrive )
+ {
+ rAssert( m_pMenu );
+ m_pMenu->SetSelectionValue( MENU_ITEM_MEMORY_DEVICE, i );
+
+ break;
+ }
+ }
+ }
+ }
+ this->UpdateFreeSpace( m_pMenu->GetSelectionValue( MENU_ITEM_MEMORY_DEVICE ) );
+}
+
+
+//===========================================================================
+// CGuiScreenMemoryCard::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMemoryCard::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenMemoryCard::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMemoryCard::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenMemoryCard::UpdateDeviceList( bool forceUpdate )
+{
+ IRadDrive* currentSelectedDrive = NULL;
+
+#ifdef RAD_XBOX
+ IRadDrive *driveMountedFlag[radFileDriveMax];
+ int numAvailableDrives = GetMemoryCardManager()->GetAvailableDrives( m_availableDrives,
+ m_mediaInfos,
+ driveMountedFlag);
+#else
+ if( m_numAttachedDevices > 0 )
+ {
+ currentSelectedDrive = m_availableDrives[ m_pMenu->GetSelectionValue( MENU_ITEM_MEMORY_DEVICE ) ];
+ }
+
+ int numAvailableDrives = GetMemoryCardManager()->GetAvailableDrives( m_availableDrives,
+ m_mediaInfos);
+#endif
+
+ bool hasMoreDrive = false;
+ bool memoryDevicesAvailable = (numAvailableDrives > 0);
+
+// this->SetButtonVisible( BUTTON_ICON_BACK, !memoryDevicesAvailable );
+
+ if( numAvailableDrives == m_numAttachedDevices &&
+ !forceUpdate )
+ {
+ // since number of attached memory devices remain the same,
+ // assume no other changes occurred since last poll
+ //
+ return;
+ }
+ else
+ {
+ if (numAvailableDrives > m_numAttachedDevices)
+ hasMoreDrive = true;
+ // update number of attached memory devices
+ //
+ m_numAttachedDevices = numAvailableDrives;
+ }
+
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, memoryDevicesAvailable );
+
+ for( int i = 0; i < numAvailableDrives; i++ )
+ {
+ rAssert( m_availableDrives[ i ] );
+ rAssert( m_mediaInfos[ i ] );
+
+ char textBibleEntry[ 32 ];
+#ifdef RAD_GAMECUBE
+ sprintf( textBibleEntry, "GC_%s", m_availableDrives[ i ]->GetDriveName() );
+#endif
+#ifdef RAD_PS2
+ sprintf( textBibleEntry, "PS2_MEMCARD1A:" );
+#endif
+#ifdef RAD_XBOX
+ sprintf( textBibleEntry, "XBOX_%s", m_availableDrives[ i ]->GetDriveName() );
+#endif
+#ifdef RAD_WIN32
+ sprintf( textBibleEntry, "XBOX_U:" ); // Temp.
+#endif
+
+ HeapMgr()->PushHeap( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ?
+ GMA_LEVEL_FE : GMA_LEVEL_HUD );
+
+ UnicodeString deviceName;
+ deviceName.ReadUnicode( GetTextBibleString( textBibleEntry ) );
+
+#ifdef RAD_PS2
+ int drive_index = GetMemoryCardManager()->GetDriveIndex(m_availableDrives[ i ]);
+ int port_number = drive_index/4;
+ if (sceMtapGetConnection(port_number)==1) { // is multitap
+ deviceName.Append('1' + (drive_index/4));
+ deviceName.Append('-' );
+ deviceName.Append('A' + (drive_index%4));
+ }
+ else {
+ deviceName.Append('1' + drive_index/4);
+ }
+#endif
+
+#ifdef RAD_XBOX
+ if (i > 0 && m_mediaInfos[ i ]->m_VolumeName[0]!=0) // i==0 is the hard disk
+ {
+ UnicodeString muName;
+ if (p3d::UnicodeStrLen((P3D_UNICODE*)( m_mediaInfos[ i ]->m_VolumeName) ) < MAX_MEM_CARD_NAME)
+ muName.ReadUnicode((P3D_UNICODE*) m_mediaInfos[ i ]->m_VolumeName);
+ else
+ {
+ muName.ReadUnicode((P3D_UNICODE*) m_mediaInfos[ i ]->m_VolumeName, MAX_MEM_CARD_NAME-1);
+ UnicodeString ellipsis;
+ ellipsis.ReadAscii("...");
+ muName += ellipsis;
+ }
+ deviceName.Append(' ');
+ deviceName.Append('(');
+ deviceName += muName;
+ deviceName.Append(')');
+
+
+ }
+#endif
+
+
+
+
+ Scrooby::Text* memoryDeviceText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_ITEM_MEMORY_DEVICE )->GetItemValue() );
+ rAssert( memoryDeviceText != NULL );
+ memoryDeviceText->SetString( i, deviceName );
+
+ HeapMgr()->PopHeap(GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ?
+ GMA_LEVEL_FE : GMA_LEVEL_HUD);
+
+ }
+
+ m_layerSelectMemoryDevice->SetVisible( memoryDevicesAvailable );
+ m_layerNoMemoryDevice->SetVisible( !memoryDevicesAvailable );
+
+ rAssert( m_pMenu );
+ if( memoryDevicesAvailable )
+ {
+ m_pMenu->GetMenuItem( MENU_ITEM_MEMORY_DEVICE )->m_attributes |= SELECTABLE;
+ }
+ else
+ {
+ m_pMenu->GetMenuItem( MENU_ITEM_MEMORY_DEVICE )->m_attributes &= ~SELECTABLE;
+ m_pMenu->SetSelectionValueCount( MENU_ITEM_MEMORY_DEVICE, 1 ); // to disable left/right scrolling
+ }
+// m_pMenu->SetMenuItemEnabled( MENU_ITEM_MEMORY_DEVICE, memoryDevicesAvailable );
+
+ if( memoryDevicesAvailable )
+ {
+ m_pMenu->SetSelectionValueCount( MENU_ITEM_MEMORY_DEVICE, numAvailableDrives );
+
+ m_pMenu->SetSelectionValue( MENU_ITEM_MEMORY_DEVICE, 0 );
+
+#ifndef RAD_XBOX
+ for( int i = 0; i < m_numAttachedDevices; i++ )
+ {
+ if( m_availableDrives[ i ] == currentSelectedDrive )
+ {
+ m_pMenu->SetSelectionValue( MENU_ITEM_MEMORY_DEVICE, i );
+
+ break;
+ }
+ }
+#endif
+ }
+#ifdef RAD_XBOX
+ int j;
+ if (hasMoreDrive) // find which drive is new and select it
+ {
+ for(j = 0; j < radFileDriveMax; j++ )
+ {
+ if (driveMountedFlag[j] && m_driveMountedFlag[j]==NULL)
+ {
+ for (int x = 0; x < numAvailableDrives; x++)
+ {
+ if (m_availableDrives[x] == driveMountedFlag[j])
+ {
+ m_pMenu->SetSelectionValue( MENU_ITEM_MEMORY_DEVICE, x );
+ break;
+ }
+ }
+ break;
+ }
+ }
+ rAssert(j<radFileDriveMax); // we must find the different drive
+ }
+
+ for(j = 0; j < radFileDriveMax; j++ )
+ {
+ m_driveMountedFlag[j] = driveMountedFlag[j];
+ }
+#endif
+}
+
+void
+CGuiScreenMemoryCard::UpdateFreeSpace( unsigned int currentDriveIndex )
+{
+ Scrooby::BoundedDrawable* menu_drawable
+ = m_pMenu->GetMenuItem(MENU_ITEM_MEMORY_DEVICE)->GetItemValue();
+
+ menu_drawable->SetColour(m_pMenu->GetHighlightColour());
+
+ m_memStatusText->SetVisible(false);
+
+ // enable selection
+ //
+ if( m_numAttachedDevices > 0 )
+ {
+ m_pMenu->GetMenuItem( MENU_ITEM_MEMORY_DEVICE )->m_attributes |= SELECTABLE;
+ SetButtonVisible( BUTTON_ICON_ACCEPT, true );
+ }
+
+ HeapMgr()->PushHeap( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ?
+ GMA_LEVEL_FE : GMA_LEVEL_HUD );
+
+#ifdef RAD_XBOX
+ if( static_cast<int>( currentDriveIndex ) < m_numAttachedDevices )
+ {
+ const unsigned int MAX_NUM_FREE_BLOCKS = 50000;
+ unsigned int numFreeBlocks = m_mediaInfos[ currentDriveIndex ]->m_FreeSpace /
+ NUM_BYTES_PER_BLOCK;
+
+ char buffer[ 16 ];
+ if( numFreeBlocks > MAX_NUM_FREE_BLOCKS )
+ {
+ sprintf( buffer, "50,000+" );
+ }
+ else
+ {
+ if( numFreeBlocks < 1000 )
+ {
+ sprintf( buffer, "%d", numFreeBlocks );
+ }
+ else
+ {
+ sprintf( buffer, "%d,%03d", numFreeBlocks / 1000, numFreeBlocks % 1000 );
+ }
+ }
+
+ rAssert( m_numFreeBlocks != NULL );
+ m_numFreeBlocks->SetString( 0, buffer );
+
+ m_pMenu->GetMenuItem( MENU_ITEM_MEMORY_DEVICE )->m_attributes |= SELECTABLE;
+ SetButtonVisible(BUTTON_ICON_ACCEPT , true);
+ }
+#endif // RAD_XBOX
+
+ if (((int)currentDriveIndex < m_numAttachedDevices) && m_mediaInfos[ currentDriveIndex ]->m_MediaState != IRadDrive::MediaInfo::MediaPresent)
+ {
+ m_memStatusText->SetVisible(true);
+ m_memStatusText->SetIndex(
+ (m_mediaInfos[ currentDriveIndex ]->m_MediaState - IRadDrive::MediaInfo::MediaNotFormatted) * 3
+ + PLATFORM_TEXT_INDEX);
+ bool disable = true;
+
+#ifdef RAD_GAMECUBE
+ // on GameCube, if memory card is unformatted or formatted for another market, allow it to be
+ // selected so that if can be formatted
+ //
+ if( m_mediaInfos[ currentDriveIndex ]->m_MediaState == IRadDrive::MediaInfo::MediaNotFormatted ||
+ m_mediaInfos[ currentDriveIndex ]->m_MediaState == IRadDrive::MediaInfo::MediaEncodingErr )
+ {
+ disable = false;
+
+ m_memStatusText->SetVisible( false ); // no need to display status text
+ }
+#endif // RAD_GAMECUBE
+
+#ifdef RAD_PS2
+ // on PS2, if memory card is unformatted, allow it to be selected so that it can be formatted
+ //
+ if( m_mediaInfos[ currentDriveIndex ]->m_MediaState == IRadDrive::MediaInfo::MediaNotFormatted )
+ {
+ disable = false;
+
+ m_memStatusText->SetVisible( false ); // no need to display status text
+ }
+#endif // RAD_PS2
+
+ if (disable)
+ {
+ // disable selection
+ m_pMenu->GetMenuItem( MENU_ITEM_MEMORY_DEVICE )->m_attributes &= ~SELECTABLE;
+ SetButtonVisible(BUTTON_ICON_ACCEPT , false);
+ // change color
+ menu_drawable->SetColour( DEFAULT_DISABLED_ITEM_COLOUR_GREY );
+ }
+ }
+ else // no error
+ {
+ if ( ((int)currentDriveIndex < m_numAttachedDevices) && GetMemoryCardManager()->IsMemcardInfoLoaded() )
+ {
+ // this drive index is different than currentDriveIndex
+ int memcard_driveindex = GetMemoryCardManager()->GetDriveIndex(m_availableDrives[ currentDriveIndex ]);
+ rTuneAssert(memcard_driveindex >= 0);
+ if ( GetMemoryCardManager()->EnoughFreeSpace( memcard_driveindex )==false
+ && GetGameDataManager()->DoesSaveGameExist(m_availableDrives[ currentDriveIndex ], false)==false ) // check for full without save game
+ {
+ int message_index = 5 * 3 + PLATFORM_TEXT_INDEX;
+ #ifdef RAD_XBOX
+ if (currentDriveIndex==0) // hd
+ message_index ++;
+ #endif
+ m_memStatusText->SetVisible(true);
+ m_memStatusText->SetIndex( message_index );
+
+#ifdef RAD_GAMECUBE
+ // append "Use Memory Card Screen" text to message; this is done in
+ // code because the text bible compiler can't handle strings with
+ // more than 255 characters
+ //
+ UnicodeString useMemCardScreen;
+ useMemCardScreen.ReadUnicode( GetTextBibleString( "USE_MEMORY_CARD_SCREEN" ) );
+
+ UnicodeString newString;
+ newString.ReadUnicode( GetTextBibleString( "MU_FULL_STATUS_(GC)" ) );
+ newString.Append( ' ' );
+ newString += useMemCardScreen;
+
+ m_memStatusText->SetString( message_index, newString );
+#endif // RAD_GAMECUBE
+
+ bool disable = true;
+#ifdef RAD_XBOX
+ if (currentDriveIndex==0) // hd
+ disable = false;
+#endif
+
+ if (disable)
+ {
+ // change color
+ menu_drawable->SetColour( DEFAULT_DISABLED_ITEM_COLOUR_GREY );
+
+ // disable selection
+ m_pMenu->GetMenuItem( MENU_ITEM_MEMORY_DEVICE )->m_attributes &= ~SELECTABLE;
+ SetButtonVisible(BUTTON_ICON_ACCEPT , false);
+ }
+
+ }
+ }
+ }
+
+ HeapMgr()->PopHeap( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ?
+ GMA_LEVEL_FE : GMA_LEVEL_HUD );
+
+}
+
diff --git a/game/code/presentation/gui/guiscreenmemorycard.h b/game/code/presentation/gui/guiscreenmemorycard.h
new file mode 100644
index 0000000..29c5d1a
--- /dev/null
+++ b/game/code/presentation/gui/guiscreenmemorycard.h
@@ -0,0 +1,206 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMemoryCard
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/30 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMEMORYCARD_H
+#define GUISCREENMEMORYCARD_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guiscreenmessage.h>
+#include <data/memcard/memorycardmanager.h>
+
+#include <radfile.hpp>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+#ifdef RAD_XBOX
+ const unsigned int NUM_BYTES_PER_BLOCK = 16 * 1024;
+#endif
+
+class CGuiMenu;
+struct IRadDrive;
+
+namespace Scrooby
+{
+ class Group;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenLoadSave : public IMemoryCardFormatCallback
+{
+public:
+ CGuiScreenLoadSave( Scrooby::Screen* pScreen );
+ virtual ~CGuiScreenLoadSave();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ static bool s_forceGotoMemoryCardScreen;
+ // Implements IMemoryCardFormatCallback
+ //
+ virtual void OnFormatOperationComplete(radFileError err);
+
+protected:
+ enum ScreenOperation
+ {
+ SCREEN_OP_IDLE,
+ LOAD,
+ SAVE,
+ FORMAT,
+ DELETE_GAME,
+
+ NUM_SCREEN_OPS
+ };
+
+ void UpdateCurrentMemoryDevice();
+ virtual void GotoMemoryCardScreen( bool isFromPrompt = false ) = 0;
+ virtual void HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response );
+
+ void FormatCurrentDrive();
+
+ int m_currentSlot;
+ radFileError m_lastError;
+
+ Scrooby::Text* m_currentMemoryDevice;
+ int m_currentDriveIndex;
+
+ unsigned int m_minimumFormatTime;
+ unsigned int m_elapsedFormatTime;
+ radFileError m_formatResult;
+ bool m_formatState;
+ bool m_formatDone;
+
+
+ ScreenOperation m_operation;
+
+
+};
+
+class CGuiScreenMemoryCard : public CGuiScreen
+{
+public:
+ CGuiScreenMemoryCard( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenMemoryCard();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+ static int s_currentMemoryCardSlot;
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ void UpdateDeviceList( bool forceUpdate = false );
+ void UpdateFreeSpace( unsigned int currentDriveIndex );
+
+ Scrooby::Group* m_layerSelectMemoryDevice;
+ Scrooby::Group* m_layerNoMemoryDevice;
+
+#ifdef RAD_XBOX
+ Scrooby::Text* m_numFreeBlocks;
+ IRadDrive *m_driveMountedFlag[radFileDriveMax];
+#endif
+ Scrooby::Text* m_memStatusText;
+
+ CGuiMenu* m_pMenu;
+
+ IRadDrive* m_availableDrives[ radFileDriveMax ];
+ IRadDrive::MediaInfo* m_mediaInfos[ radFileDriveMax ];
+ int m_numAttachedDevices;
+
+
+};
+
+const int NUM_RADFILE_ERROR_MESSAGES = DataCorrupt; // should be last enum
+const int NUM_MEDIA_INFO_STATES = IRadDrive::MediaInfo::MediaDamaged; // should be last enum
+
+
+const int MAX_MEM_CARD_NAME = 16; // max display for memory card
+
+enum eErrorMessageMode
+{
+ ERROR_DURING_CHECKING,
+ ERROR_DURING_LOADING,
+ ERROR_DURING_SAVING,
+
+ NUM_ERROR_MESSAGE_MODES
+};
+
+inline int GetErrorMessageIndex( radFileError errorCode, eErrorMessageMode mode )
+{
+ const int NUM_PLATFORMS = 3;
+
+ // radfile error messages are offset by media info states
+ //
+ int messageIndex = NUM_MEDIA_INFO_STATES;
+
+ switch( mode )
+ {
+ case ERROR_DURING_CHECKING:
+ {
+ messageIndex += (errorCode - 1);
+
+ break;
+ }
+ case ERROR_DURING_LOADING:
+ {
+ messageIndex += (errorCode - 1) + NUM_RADFILE_ERROR_MESSAGES;
+
+ break;
+ }
+ case ERROR_DURING_SAVING:
+ {
+ messageIndex += (errorCode - 1) + NUM_RADFILE_ERROR_MESSAGES * 2;
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "ERROR: *** Invalid error message mode!" );
+ break;
+ }
+ }
+
+ // return platform-specific message index
+ //
+ return( messageIndex * NUM_PLATFORMS + PLATFORM_TEXT_INDEX );
+};
+
+inline int GetErrorMessageIndex( IRadDrive::MediaInfo::MediaState mediaState )
+{
+ const int NUM_PLATFORMS = 3;
+
+ int messageIndex = mediaState - 1;
+
+ // return platform-specific message index
+ //
+ return( messageIndex * NUM_PLATFORMS + PLATFORM_TEXT_INDEX );
+};
+
+#endif // GUISCREENMEMORYCARD_H
diff --git a/game/code/presentation/gui/guiscreenmessage.cpp b/game/code/presentation/gui/guiscreenmessage.cpp
new file mode 100644
index 0000000..4f47623
--- /dev/null
+++ b/game/code/presentation/gui/guiscreenmessage.cpp
@@ -0,0 +1,629 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMessage
+//
+// Description: Implementation of the CGuiScreenMessage class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/guiscreenmessage.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <presentation/gui/guiscreenmemorycard.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/gui/ingame/guimanageringame.h>
+
+#include <data/memcard/memorycardmanager.h>
+#include <gameflow/gameflow.h>
+#include <memory/srrmemory.h>
+
+#include <p3d/unicode.hpp>
+#include <raddebug.hpp> // Foundation
+#include <layer.h>
+#include <page.h>
+#include <screen.h>
+#include <sprite.h>
+#include <text.h>
+
+#ifdef RAD_PS2
+#include <libmtap.h>
+#endif
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+int CGuiScreenMessage::s_ControllerDisconnectedPort = 0;
+
+int CGuiScreenMessage::s_messageIndex = -1;
+CGuiEntity* CGuiScreenMessage::s_pMessageCallback = NULL;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenMessage::CGuiScreenMessage
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMessage::CGuiScreenMessage
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_GENERIC_MESSAGE ),
+ m_pMenu( NULL ),
+ m_messageText( NULL ),
+ m_messageIcon( NULL ),
+ m_elapsedTime( 0 )
+{
+ m_originalStringBuffer[ 0 ] = '\0';
+
+MEMTRACK_PUSH_GROUP( "GUIScreenMessage" );
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Message" );
+ rAssert( pPage != NULL );
+
+ Scrooby::Layer* pLayer = pPage->GetLayer( "Foreground" );
+ rAssert( pLayer != NULL );
+
+ m_messageText = pLayer->GetText( "Message" );
+ rAssert( m_messageText );
+
+ // wrap text message
+ //
+ m_messageText->SetTextMode( Scrooby::TEXT_WRAP );
+ m_messageText->ResetTransformation();
+ m_messageText->ScaleAboutCenter(0.9f);
+
+ // Retrieve the Scrooby drawing elements (from MessageBox page).
+ //
+ pPage = m_pScroobyScreen->GetPage( "MessageBox" );
+ rAssert( pPage != NULL );
+
+ m_messageIcon = pPage->GetSprite( "ErrorIcon" );
+
+ this->AutoScaleFrame( pPage );
+
+ this->SetFadeTime( 0.0f );
+MEMTRACK_POP_GROUP( "GUIScreenMessage" );
+}
+
+
+//===========================================================================
+// CGuiScreenMessage::~CGuiScreenMessage
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMessage::~CGuiScreenMessage()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMessage::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMessage::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ m_elapsedTime += param1;
+
+ // pulse message icon
+ //
+ float scale = GuiSFX::Pulse( (float)m_elapsedTime,
+ 500.0f,
+ 1.0f * MESSAGE_ICON_CORRECTION_SCALE,
+ 0.1f * MESSAGE_ICON_CORRECTION_SCALE );
+
+ rAssert( m_messageIcon );
+ m_messageIcon->ResetTransformation();
+ m_messageIcon->ScaleAboutCenter( scale );
+
+ if( s_pMessageCallback != NULL )
+ {
+ s_pMessageCallback->HandleMessage( GUI_MSG_MESSAGE_UPDATE, param1 );
+ }
+
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ // ignore BACK inputs, thereby, not allowing users to back
+ // out of prompt
+ return;
+
+ break;
+ }
+/*
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ rAssert( s_pMessageCallback );
+ s_pMessageCallback->HandleMessage( GUI_MSG_MENU_MESSAGE_RESPONSE,
+ param1, param2 );
+
+ break;
+ }
+*/
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+ else if( m_state == GUI_WINDOW_STATE_OUTRO )
+ {
+ if( m_numTransitionsPending < 0 )
+ {
+ // restore original string buffer
+ //
+ if( m_originalStringBuffer[ 0 ] != '\0' )
+ {
+ rAssert( m_messageText != NULL );
+ UnicodeChar* stringBuffer = m_messageText->GetStringBuffer();
+ rAssert( stringBuffer != NULL );
+
+ p3d::UnicodeStrCpy( static_cast<P3D_UNICODE*>( m_originalStringBuffer ),
+ static_cast<P3D_UNICODE*>( stringBuffer ),
+ sizeof( m_originalStringBuffer ) );
+
+ m_originalStringBuffer[ 0 ] = '\0';
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+void
+CGuiScreenMessage::Display( int messageIndex, CGuiEntity* pCallback )
+{
+ s_messageIndex = messageIndex;
+ s_pMessageCallback = pCallback;
+}
+void
+CGuiScreenMessage::GetControllerDisconnectedMessage(int controller_id, char *str_buffer, int max_char)
+{
+ P3D_UNICODE* multitapString = NULL;
+
+ s_ControllerDisconnectedPort = controller_id;
+
+#ifdef RAD_GAMECUBE
+ P3D_UNICODE* uni_string = GetTextBibleString( "MSG_CONTROLLER_DISCONNECTED_(GC)" );
+#endif
+
+#ifdef RAD_XBOX
+ P3D_UNICODE* uni_string = GetTextBibleString( "MSG_CONTROLLER_DISCONNECTED_(XBOX)" );
+#endif
+
+#ifdef RAD_PS2
+ P3D_UNICODE* uni_string = GetTextBibleString( "MSG_CONTROLLER_DISCONNECTED_(PS2)" );
+ if (s_ControllerDisconnectedPort > 7)
+ uni_string = GetTextBibleString( "MSG_CONTROLLER_DISCONNECTED_WHEEL" ); // usb
+ int port = controller_id/4;
+ if ( controller_id < 8 &&
+ GetInputManager()->GetLastMultitapStatus( port ) != 0 &&
+ sceMtapGetConnection( port ) == 0 )
+ {
+ uni_string = GetTextBibleString( "MSG_CONTROLLER_DISCONNECTED_MULTITAP" ); // multitap
+
+ // convert the first controller port wildcard character to either 1 or 2
+ //
+ const UnicodeChar CONTROLLER_PORT_WILDCARD_CHARACTER = 0xa5;
+
+ HeapMgr()->PushHeap( GMA_TEMP );
+
+ multitapString = new P3D_UNICODE[ max_char + 1 ];
+ rAssert( multitapString != NULL );
+ p3d::UnicodeStrCpy( uni_string, multitapString, max_char );
+ for( int i = 0; multitapString[ i ] != '\0'; i++ )
+ {
+ if( multitapString[ i ] == CONTROLLER_PORT_WILDCARD_CHARACTER )
+ {
+ // found it!
+ //
+ multitapString[ i ] = '1' + port;
+ break;
+ }
+ }
+
+ uni_string = multitapString;
+
+ HeapMgr()->PopHeap( GMA_TEMP );
+ }
+#endif
+
+#ifdef RAD_WIN32
+ P3D_UNICODE* uni_string = GetTextBibleString( "MSG_CONTROLLER_DISCONNECTED_(XBOX)" );
+#endif
+
+ CGuiScreenMessage::ConvertUnicodeToChar(str_buffer, uni_string, max_char);
+
+ if( multitapString != NULL )
+ {
+ delete multitapString;
+ multitapString = NULL;
+ }
+}
+void
+CGuiScreenMessage::ConvertUnicodeToChar(char *str, P3D_UNICODE* uni_str, int max_char)
+{
+ const UnicodeChar CONTROLLER_PORT_WILDCARD_CHARACTER = 0xa5;// since > 0x7f, '¥' wont work;
+ const UnicodeChar NEWLINE_CHARACTER = 0x5c; //'\';
+ int i = 0;
+ while (*uni_str && i < max_char)
+ {
+ if (*uni_str==NEWLINE_CHARACTER)
+ *str = '\n';
+ else if (*uni_str==CONTROLLER_PORT_WILDCARD_CHARACTER)
+ {
+#ifdef RAD_PS2
+ int port_number = s_ControllerDisconnectedPort/4;
+ if (sceMtapGetConnection(port_number)==1
+ || GetInputManager()->GetLastMultitapStatus(port_number) == 1) { // is multitap
+
+ UnicodeString unicodeString; // splice the mu name inside
+ UnicodeString restofString;
+ UnicodeString deviceName;
+
+ *str++ = '1' + (s_ControllerDisconnectedPort/4);
+ i++;
+ if (i >= max_char) break;
+ *str++ = '-';
+ i++;
+ if (i >= max_char) break;
+ *str = 'A' + (s_ControllerDisconnectedPort%4);
+ }
+ else // no multitap
+ {
+ *str = '1' + (s_ControllerDisconnectedPort/4);
+ if (s_ControllerDisconnectedPort==8)
+ *str = '1';
+ else if (s_ControllerDisconnectedPort==9)
+ *str = '2';
+ }
+
+#else
+ *str = '1' + s_ControllerDisconnectedPort;
+#endif
+ }
+ else
+ *str = (char)*uni_str;
+
+
+ i++;
+ str++;
+ uni_str++;
+ }
+ *str++ = 0;
+}
+void
+CGuiScreenMessage::FormatMessage( Scrooby::Text* pText,
+ UnicodeChar* originalStringBuffer,
+ int stringBufferLength )
+{
+ const UnicodeChar SLOT_WILDCARD_CHARACTER = '$';
+ const UnicodeChar BLOCKS_WILDCARD_CHARACTER = '#';
+ const UnicodeChar CONTROLLER_PORT_WILDCARD_CHARACTER = 0xa5;// since > 0x7f, '¥' wont work;
+
+ rAssert( pText != NULL );
+ UnicodeChar* stringBuffer = pText->GetStringBuffer();
+ rAssert( stringBuffer != NULL );
+
+ // save copy of original string buffer
+ //
+ if( originalStringBuffer != NULL )
+ {
+ p3d::UnicodeStrCpy( static_cast<P3D_UNICODE*>( stringBuffer ),
+ static_cast<P3D_UNICODE*>( originalStringBuffer ),
+ stringBufferLength );
+ }
+
+ for( int i = 0; stringBuffer[ i ] != '\0'; i++ )
+ {
+ // search for slot wildcard character
+ //
+ if( stringBuffer[ i ] == CONTROLLER_PORT_WILDCARD_CHARACTER )
+ {
+#ifdef RAD_PS2
+ int port_number = s_ControllerDisconnectedPort/4;
+ if (sceMtapGetConnection(port_number)==1) { // is multitap
+ HeapMgr()->PushHeap( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ?
+ GMA_LEVEL_FE : GMA_LEVEL_HUD );
+
+ UnicodeString unicodeString; // splice the mu name inside
+ UnicodeString restofString;
+ UnicodeString deviceName;
+
+ deviceName.Append('1' + (s_ControllerDisconnectedPort/4));
+ deviceName.Append('-' );
+ deviceName.Append('A' + (s_ControllerDisconnectedPort%4));
+
+ unicodeString.ReadUnicode(stringBuffer, i);
+ restofString.ReadUnicode(&stringBuffer[i+1]);
+ unicodeString += deviceName;
+ unicodeString += restofString;
+ pText->SetString(pText->GetIndex(),unicodeString);
+
+ HeapMgr()->PopHeap(GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ?
+ GMA_LEVEL_FE : GMA_LEVEL_HUD);
+ }
+ else // no multitap
+ stringBuffer[ i ] = '1' + (s_ControllerDisconnectedPort/4);
+
+#else
+ stringBuffer[ i ] = '1' + s_ControllerDisconnectedPort;
+#endif
+ break;
+ }
+ }
+// update slot wild card character---------------------
+
+#ifdef RAD_GAMECUBE
+ for( int i = 0; stringBuffer[ i ] != '\0'; i++ )
+ {
+ // search for slot wildcard character
+ //
+ if( stringBuffer[ i ] == SLOT_WILDCARD_CHARACTER )
+ {
+ stringBuffer[ i ] = 'A' + CGuiScreenMemoryCard::s_currentMemoryCardSlot;
+
+ break;
+ }
+ }
+#endif // RAD_GAMECUBE
+
+#ifdef RAD_PS2
+ for( int i = 0; stringBuffer[ i ] != '\0'; i++ )
+ {
+ // search for slot wildcard character
+ //
+ if( stringBuffer[ i ] == SLOT_WILDCARD_CHARACTER )
+ {
+ int port_number = CGuiScreenMemoryCard::s_currentMemoryCardSlot/4;
+ if (sceMtapGetConnection(port_number)==1) { // is multitap
+
+ HeapMgr()->PushHeap( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ?
+ GMA_LEVEL_FE : GMA_LEVEL_HUD );
+
+ UnicodeString unicodeString; // splice the mu name inside
+ UnicodeString restofString;
+ UnicodeString deviceName;
+
+ deviceName.Append('1' + (CGuiScreenMemoryCard::s_currentMemoryCardSlot/4));
+ deviceName.Append('-' );
+ deviceName.Append('A' + (CGuiScreenMemoryCard::s_currentMemoryCardSlot%4));
+
+ unicodeString.ReadUnicode(stringBuffer, i);
+ restofString.ReadUnicode(&stringBuffer[i+1]);
+ unicodeString += deviceName;
+ unicodeString += restofString;
+ pText->SetString(pText->GetIndex(),unicodeString);
+
+ HeapMgr()->PopHeap(GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ?
+ GMA_LEVEL_FE : GMA_LEVEL_HUD);
+ }
+ else
+ {
+ stringBuffer[ i ] = '1' + CGuiScreenMemoryCard::s_currentMemoryCardSlot/4;
+ }
+ break;
+ }
+
+ }
+#endif // RAD_PS2
+
+#ifdef RAD_XBOX
+ for( int i = 0; stringBuffer[ i ] != '\0'; i++ )
+ {
+ // search for num blocks wildcard character
+ //
+ if( stringBuffer[ i ] == BLOCKS_WILDCARD_CHARACTER )
+ {
+ const IRadDrive::MediaInfo* mediaInfo = GetMemoryCardManager()->GetMediaInfo( static_cast<unsigned int>( CGuiScreenMemoryCard::s_currentMemoryCardSlot ) );
+ rAssert( mediaInfo != NULL );
+
+ unsigned int savedGameSize = GetMemoryCardManager()->GetSavedGameCreationSize( static_cast<unsigned int>( CGuiScreenMemoryCard::s_currentMemoryCardSlot ) );
+
+ unsigned int numBlocksRequired = (savedGameSize - mediaInfo->m_FreeSpace) / NUM_BYTES_PER_BLOCK;
+ rAssert( numBlocksRequired > 0 );
+ rWarningMsg( numBlocksRequired < 10, "WARNING: *** Number of free blocks required is more than one digit long!" );
+
+ stringBuffer[ i ] = '0' + numBlocksRequired;
+
+ break;
+ }
+ }
+ for( int i = 0; stringBuffer[ i ] != '\0'; i++ )
+ {
+ // search for slot wildcard character
+ //
+ if( stringBuffer[ i ] == SLOT_WILDCARD_CHARACTER )
+ {
+ HeapMgr()->PushHeap( GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ?
+ GMA_LEVEL_FE : GMA_LEVEL_HUD );
+ UnicodeString deviceName;
+
+ const IRadDrive::MediaInfo* mediaInfo =
+ GetMemoryCardManager()->GetMediaInfo( static_cast<unsigned int>(
+ CGuiScreenMemoryCard::s_currentMemoryCardSlot ) );
+ char textBibleEntry[ 32 ];
+ sprintf( textBibleEntry, "XBOX_%s",
+ GetMemoryCardManager()->GetDriveName( static_cast<unsigned int>(
+ CGuiScreenMemoryCard::s_currentMemoryCardSlot ) ) );
+ deviceName.ReadUnicode( GetTextBibleString( textBibleEntry ) );
+
+ if (mediaInfo->m_VolumeName[0]!=0) // append personalized name
+ {
+ UnicodeString muName;
+ if (p3d::UnicodeStrLen((P3D_UNICODE*)( mediaInfo->m_VolumeName) ) < MAX_MEM_CARD_NAME)
+ muName.ReadUnicode((P3D_UNICODE*) mediaInfo->m_VolumeName);
+ else
+ {
+ muName.ReadUnicode((P3D_UNICODE*) mediaInfo->m_VolumeName, MAX_MEM_CARD_NAME-1);
+ UnicodeString ellipsis;
+ ellipsis.ReadAscii("...");
+ muName += ellipsis;
+ }
+ deviceName.Append(' ');
+ deviceName.Append('(');
+ deviceName += muName;
+ deviceName.Append(')');
+ }
+ UnicodeString unicodeString; // splice the mu name inside
+ UnicodeString restofString;
+ unicodeString.ReadUnicode(stringBuffer, i);
+ restofString.ReadUnicode(&stringBuffer[i+1]);
+ unicodeString += deviceName;
+ unicodeString += restofString;
+
+ pText->SetString(pText->GetIndex(),unicodeString);
+
+ HeapMgr()->PopHeap(GetGameFlow()->GetCurrentContext() == CONTEXT_FRONTEND ?
+ GMA_LEVEL_FE : GMA_LEVEL_HUD);
+ }
+ }
+
+
+#endif // RAD_XBOX
+}
+
+//===========================================================================
+// CGuiScreenMessage::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMessage::InitIntro()
+{
+ rAssert( m_messageText );
+ rAssert( s_messageIndex >= 0 &&
+ s_messageIndex < m_messageText->GetNumOfStrings() );
+
+ // set message text
+ //
+ m_messageText->SetIndex( s_messageIndex );
+
+ CGuiScreenMessage::FormatMessage( m_messageText,
+ m_originalStringBuffer,
+ sizeof( m_originalStringBuffer ) );
+
+ rAssert( m_messageIcon );
+ m_messageIcon->ResetTransformation();
+
+ m_elapsedTime = 0;
+
+/*
+ // show/hide accept button depending on whether menu is visible or not
+ //
+ rAssert( s_menuGroup );
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, s_menuGroup->IsVisible() );
+*/
+}
+
+
+//===========================================================================
+// CGuiScreenMessage::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMessage::InitRunning()
+{
+ if( s_pMessageCallback != NULL )
+ {
+ s_pMessageCallback->HandleMessage( GUI_MSG_ON_DISPLAY_MESSAGE );
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMessage::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMessage::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/guiscreenmessage.h b/game/code/presentation/gui/guiscreenmessage.h
new file mode 100644
index 0000000..dec532d
--- /dev/null
+++ b/game/code/presentation/gui/guiscreenmessage.h
@@ -0,0 +1,114 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMessage
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/10/21 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMESSAGE_H
+#define GUISCREENMESSAGE_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+#include <strings/unicodestring.h>
+
+#ifdef RAD_WIN32
+const float MESSAGE_ICON_CORRECTION_SCALE = 0.875f;
+#else
+const float MESSAGE_ICON_CORRECTION_SCALE = 1.75f;
+#endif
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMessage : public CGuiScreen
+{
+public:
+ enum eMessageID
+ {
+ MSG_ID_CONTROLLER_DISCONNECTED_GC,
+ MSG_ID_CONTROLLER_DISCONNECTED_PS2,
+ MSG_ID_CONTROLLER_DISCONNECTED_XBOX,
+ MSG_ID_AUTO_LOADING_GAME_GC,
+ MSG_ID_AUTO_LOADING_GAME_PS2,
+ MSG_ID_AUTO_LOADING_GAME_XBOX,
+ MSG_ID_AUTO_LOADING_GAME_XBOX_HD,
+ MSG_ID_LOADING_GAME_GC,
+ MSG_ID_LOADING_GAME_PS2,
+ MSG_ID_LOADING_GAME_XBOX,
+ MSG_ID_LOADING_GAME_XBOX_HD,
+ MSG_ID_SAVING_GAME_GC,
+ MSG_ID_SAVING_GAME_PS2,
+ MSG_ID_SAVING_GAME_XBOX,
+ MSG_ID_SAVING_GAME_XBOX_HD,
+ MSG_ID_FORMATTING_GC,
+ MSG_ID_FORMATTING_PS2,
+ MSG_ID_FORMATTING_XBOX,
+ MSG_ID_DELETING_GC,
+ MSG_ID_DELETING_PS2,
+ MSG_ID_DELETING_XBOX,
+ MSG_ID_LOADING_MISSION,
+ MSG_ID_PROGRESSIVE_SCAN_TEST,
+#ifdef RAD_WIN32
+ MSG_ID_LOADING_GAME_PC,
+ MSG_ID_SAVING_GAME_PC,
+ MSG_ID_AUTO_LOADING_GAME_PC,
+#endif
+
+ NUM_MESSAGE_ID
+ };
+
+ CGuiScreenMessage( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenMessage();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+ static void Display( int messageIndex, CGuiEntity* pCallback = NULL );
+
+ static void FormatMessage( Scrooby::Text* pText,
+ UnicodeChar* originalStringBuffer = NULL,
+ int stringBufferLength = -1 );
+ static void GetControllerDisconnectedMessage(int controllerId, char *str, int max_char);
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ CGuiMenu* m_pMenu;
+
+ Scrooby::Text* m_messageText;
+ static int s_messageIndex;
+ static CGuiEntity* s_pMessageCallback;
+ static int s_ControllerDisconnectedPort;
+
+ Scrooby::Sprite* m_messageIcon;
+ unsigned int m_elapsedTime;
+
+ UnicodeChar m_originalStringBuffer[ 256 ];
+ static void ConvertUnicodeToChar(char *str, P3D_UNICODE* uni_str, int max_char);
+
+};
+
+#endif // GUISCREENMESSAGE_H
diff --git a/game/code/presentation/gui/guiscreenprompt.cpp b/game/code/presentation/gui/guiscreenprompt.cpp
new file mode 100644
index 0000000..a85329c
--- /dev/null
+++ b/game/code/presentation/gui/guiscreenprompt.cpp
@@ -0,0 +1,498 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPrompt
+//
+// Description: Implementation of the CGuiScreenPrompt class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/guiscreenprompt.h>
+#include <presentation/gui/guiscreenmessage.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guiscreenmemorycard.h>
+#include <presentation/gui/utility/specialfx.h>
+
+#include <memory/srrmemory.h>
+#include <mission/gameplaymanager.h>
+#include <mission/mission.h>
+#include <gameflow/gameflow.h>
+
+#include <p3d/unicode.hpp>
+#include <raddebug.hpp> // Foundation
+#include <layer.h>
+#include <page.h>
+#include <screen.h>
+#include <text.h>
+#include <sprite.h>
+#include <group.h>
+#include <pure3dobject.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+int CGuiScreenPrompt::s_messageIndex = 0;
+int CGuiScreenPrompt::s_numResponses = 0;
+CGuiMenuPrompt::ePromptResponse CGuiScreenPrompt::s_responses[ CGuiMenuPrompt::MAX_NUM_RESPONSES ];
+CGuiEntity* CGuiScreenPrompt::s_pPromptCallback = NULL;
+bool CGuiScreenPrompt::s_defaultToNo = true;
+
+const float ERROR_PROMPT_FADE_TIME = 100.0f;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenPrompt::CGuiScreenPrompt
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPrompt::CGuiScreenPrompt
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent,
+ eGuiWindowID windowID
+)
+: CGuiScreen( pScreen, pParent, windowID ),
+ m_pMenu( NULL ),
+ m_messageIcon( NULL ),
+ m_elapsedTime( 0 ),
+ m_xboxDashboardLabel( NULL ),
+ m_promptMessage( NULL ),
+ m_tvFrame( NULL )
+{
+MEMTRACK_PUSH_GROUP( "GUIScreenPrompt" );
+ if( m_screenCover != NULL )
+ {
+ m_screenCover->SetAlpha( 0.0f );
+ m_screenCover = NULL;
+ }
+
+ m_originalStringBuffer[ 0 ] = '\0';
+
+ // Create a menu.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Prompt" );
+ m_pMenu = new CGuiMenuPrompt( this, pPage );
+ rAssert( m_pMenu != NULL );
+
+ // TC: quick & dirty hack, no time to make this pretty!
+ //
+ m_pMenu->GetMenuItem( 0 )->m_defaultColour = tColour( 255, 255, 255 );
+
+ if( windowID == GUI_SCREEN_ID_ERROR_PROMPT )
+ {
+ pPage = m_pScroobyScreen->GetPage( "ErrorPrompt" );
+ rAssert( pPage != NULL );
+
+// m_messageIcon = pPage->GetSprite( "ErrorIcon" );
+// rAssert( m_messageIcon );
+
+ m_xboxDashboardLabel = pPage->GetGroup( "XboxDashboard" );
+ rAssert( m_xboxDashboardLabel != NULL );
+ m_xboxDashboardLabel->SetVisible( false );
+
+ this->SetFadeTime( ERROR_PROMPT_FADE_TIME );
+
+#ifdef RAD_XBOX
+ // wrap "Go to Xbox Dashboard" text
+ //
+ Scrooby::Group* xboxDashboard = pPage->GetGroup( "XboxDashboard" );
+ rAssert( xboxDashboard != NULL );
+
+ Scrooby::Text* pText = xboxDashboard->GetText( "GotoDashboard" );
+ if( pText != NULL )
+ {
+ pText->SetTextMode( Scrooby::TEXT_WRAP );
+ }
+#endif
+ }
+ else
+ {
+ this->SetSlidingEnabled( SCREEN_FX_SLIDE_Y, true );
+
+ pPage = m_pScroobyScreen->GetPage( "GenericPrompt" );
+ rAssert( pPage != NULL );
+ }
+
+ Scrooby::Page* messageBoxPage = m_pScroobyScreen->GetPage( "MessageBox" );
+ if( messageBoxPage != NULL )
+ {
+ this->AutoScaleFrame( messageBoxPage );
+
+ Scrooby::Sprite* messageIcon = messageBoxPage->GetSprite( "ErrorIcon" );
+ if( messageIcon != NULL )
+ {
+ messageIcon->ResetTransformation();
+ messageIcon->ScaleAboutCenter( MESSAGE_ICON_CORRECTION_SCALE );
+ }
+ }
+
+ m_promptMessage = pPage->GetText( "Message" );
+ rAssert( m_promptMessage );
+ m_promptMessage->SetTextMode( Scrooby::TEXT_WRAP );
+ m_promptMessage->ResetTransformation();
+ m_promptMessage->ScaleAboutCenter(0.9f);
+
+
+ pPage = m_pScroobyScreen->GetPage( "TVFrame" );
+ if( pPage != NULL )
+ {
+ m_tvFrame = pPage->GetLayer( "TVFrame" );
+ }
+MEMTRACK_POP_GROUP( "GUIScreenPrompt" );
+}
+
+
+//===========================================================================
+// CGuiScreenPrompt::~CGuiScreenPrompt
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPrompt::~CGuiScreenPrompt()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenPrompt::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPrompt::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+#ifdef RAD_PS2
+ case GUI_MSG_CONTROLLER_START:
+ {
+ if ( GetGameFlow()->GetCurrentContext() == CONTEXT_PAUSE )
+ if ( s_pPromptCallback )
+ s_pPromptCallback->HandleMessage( GUI_MSG_PROMPT_START_RESPONSE );
+
+ break;
+ }
+#endif
+ case GUI_MSG_UPDATE:
+ {
+ m_elapsedTime += param1;
+
+ // pulse message icon
+ //
+ float scale = GuiSFX::Pulse( (float)m_elapsedTime,
+ 500.0f,
+ 1.0f,
+ 0.1f );
+
+ if( m_messageIcon != NULL )
+ {
+ m_messageIcon->ResetTransformation();
+ m_messageIcon->ScaleAboutCenter( scale );
+ }
+
+ if (!m_pMenu->HasSelectionBeenMade())
+ {
+ rAssert( s_pPromptCallback );
+ s_pPromptCallback->HandleMessage( GUI_MSG_PROMPT_UPDATE, param1, param2);
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+#ifdef RAD_XBOX
+ if( m_ID == GUI_SCREEN_ID_ERROR_PROMPT )
+ {
+ // special case for going to xbox dashboard on the
+ // "full xbox hard disk" error message
+ //
+ rAssert( s_pPromptCallback );
+ rAssert( m_promptMessage );
+ s_pPromptCallback->HandleMessage( GUI_MSG_MENU_PROMPT_RESPONSE,
+ m_promptMessage->GetIndex(),
+ CGuiMenuPrompt::RESPONSE_MANAGE_MEMCARDS );
+ }
+#endif
+ // ignore BACK inputs, thereby, not allowing users to back
+ // out of prompt
+ return;
+
+ break;
+ }
+
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ rAssert( m_pMenu );
+ CGuiMenuPrompt::ePromptResponse response = m_pMenu->GetResponse( param1 );
+
+ rAssert( s_pPromptCallback );
+ rAssert( m_promptMessage );
+ enum eGuiMessage message;
+ if (m_ID==GUI_SCREEN_ID_GENERIC_PROMPT)
+ message = GUI_MSG_MENU_PROMPT_RESPONSE;
+ else if (m_ID==GUI_SCREEN_ID_ERROR_PROMPT)
+ message = GUI_MSG_ERROR_PROMPT_RESPONSE;
+ else
+ {
+ message = GUI_MSG_MENU_PROMPT_RESPONSE;
+ rTuneAssert(!"not reached");
+ }
+ s_pPromptCallback->HandleMessage( message,
+ m_promptMessage->GetIndex(),
+ response );
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+ else if( m_state == GUI_WINDOW_STATE_OUTRO )
+ {
+ // TC: This is a nasty hack! GOD, please forgive me, as this is the
+ // easiest thing for me to do w/ just a few days left before beta.
+ //
+ if( m_ID == GUI_SCREEN_ID_GENERIC_PROMPT && s_messageIndex == PROMPT_CONFIRM_NEW_GAME )
+ {
+ rAssert( m_p3dObject != NULL );
+
+ tMultiController* multiController = m_p3dObject->GetMultiController();
+ if( multiController != NULL )
+ {
+ const float NUM_FADE_OUT_FRAMES = 15.0f;
+ float currentFrame = multiController->GetFrame();
+ float numRemainingFrames = multiController->GetNumFrames() - currentFrame;
+
+ if( numRemainingFrames < NUM_FADE_OUT_FRAMES )
+ {
+ // fade out TV frame
+ //
+ if( m_tvFrame != NULL )
+ {
+ float alpha = numRemainingFrames / NUM_FADE_OUT_FRAMES;
+
+ // decrease fade rate for low alpha values
+ alpha *= alpha;
+
+ if( alpha > 0.0f && alpha < 1.0f )
+ {
+ m_tvFrame->SetAlpha( alpha );
+ }
+ else
+ {
+ m_tvFrame->SetAlpha( 0.0f );
+ }
+ }
+
+ // TC [HACK]: To prevent any clipping in homer's mouth
+ // in the last few frames.
+ //
+ if( numRemainingFrames < 1.0f )
+ {
+ this->RestoreScreenCover();
+ }
+ }
+ }
+ }
+
+ if( m_numTransitionsPending < 0 )
+ {
+ // restore original string buffer
+ //
+ if( m_originalStringBuffer[ 0 ] != '\0' )
+ {
+ rAssert( m_promptMessage != NULL );
+ UnicodeChar* stringBuffer = m_promptMessage->GetStringBuffer();
+ rAssert( stringBuffer != NULL );
+
+ p3d::UnicodeStrCpy( static_cast<P3D_UNICODE*>( m_originalStringBuffer ),
+ static_cast<P3D_UNICODE*>( stringBuffer ),
+ sizeof( m_originalStringBuffer ) );
+
+ m_originalStringBuffer[ 0 ] = '\0';
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenPrompt::Display
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPrompt::Display( int messageIndex,
+ CGuiEntity* pCallback,
+ int numResponses,
+ CGuiMenuPrompt::ePromptResponse* responses )
+{
+ s_messageIndex = messageIndex;
+ s_pPromptCallback = pCallback;
+ s_numResponses = numResponses;
+
+ for( int i = 0; i < numResponses; i++ )
+ {
+ s_responses[ i ] = responses[ i ];
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenPrompt::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPrompt::InitIntro()
+{
+ rAssert( m_promptMessage );
+ rAssert( s_messageIndex >= 0 &&
+ s_messageIndex < m_promptMessage->GetNumOfStrings() );
+
+#ifdef RAD_XBOX
+ if( m_ID == GUI_SCREEN_ID_ERROR_PROMPT )
+ {
+ // special case for "full xbox hard disk" error message
+ //
+ bool showLabel = (s_messageIndex == GetErrorMessageIndex( NoFreeSpace, ERROR_DURING_CHECKING ));
+ rAssert( m_xboxDashboardLabel != NULL );
+ m_xboxDashboardLabel->SetVisible( showLabel );
+ }
+#endif
+
+ m_promptMessage->SetIndex( s_messageIndex );
+
+ CGuiScreenMessage::FormatMessage( m_promptMessage,
+ m_originalStringBuffer,
+ sizeof( m_originalStringBuffer ) );
+
+// rAssert( m_messageIcon );
+// m_messageIcon->ResetTransformation();
+
+ rAssert( m_pMenu );
+ m_pMenu->SetNumResponses( s_numResponses );
+ m_pMenu->Reset();
+
+ for( int i = 0; i < s_numResponses; i++ )
+ {
+ m_pMenu->SetResponse( i, s_responses[ i ] );
+
+ if( s_defaultToNo && s_responses[ i ] == CGuiMenuPrompt::RESPONSE_NO )
+ {
+ // set NO as default response
+ //
+ m_pMenu->Reset( i );
+ }
+ }
+
+ m_elapsedTime = 0;
+}
+
+
+//===========================================================================
+// CGuiScreenPrompt::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPrompt::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenPrompt::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPrompt::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/guiscreenprompt.h b/game/code/presentation/gui/guiscreenprompt.h
new file mode 100644
index 0000000..b39e485
--- /dev/null
+++ b/game/code/presentation/gui/guiscreenprompt.h
@@ -0,0 +1,166 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPrompt
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENPROMPT_H
+#define GUISCREENPROMPT_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <presentation/gui/guimenu.h>
+
+#include <strings/unicodestring.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class Group;
+}
+
+enum ePromptQuestion
+{
+ PROMPT_CONFIRM_QUIT,
+ PROMPT_CONFIRM_SAVE_BEFORE_QUIT,
+ PROMPT_CONFIRM_RESTART,
+ PROMPT_CONFIRM_ABORT,
+ PROMPT_CONFIRM_RACE_AGAIN,
+ PROMPT_CONFIRM_NEW_GAME,
+ PROMPT_CONFIRM_START_MISSION,
+ PROMPT_LOAD_CONFIRM_GC,
+ PROMPT_LOAD_CONFIRM_PS2,
+ PROMPT_LOAD_CONFIRM_XBOX,
+
+ PROMPT_SAVE_CONFIRM_GC,
+ PROMPT_SAVE_CONFIRM_PS2,
+ PROMPT_SAVE_CONFIRM_XBOX,
+ PROMPT_SAVE_CONFIRM_OVERWRITE_GC,
+ PROMPT_SAVE_CONFIRM_OVERWRITE_PS2,
+ PROMPT_SAVE_CONFIRM_OVERWRITE_XBOX,
+
+ PROMPT_LOAD_SUCCESSFUL,
+ PROMPT_SAVE_SUCCESSFUL,
+
+ PROMPT_FORMAT_CONFIRM_GC,
+ PROMPT_FORMAT_CONFIRM_PS2,
+ PROMPT_FORMAT_CONFIRM_XBOX,
+
+ PROMPT_FORMAT_CONFIRM2_GC,
+ PROMPT_FORMAT_CONFIRM2_PS2,
+ PROMPT_FORMAT_CONFIRM2_XBOX,
+
+ PROMPT_FORMAT_SUCCESS_GC,
+ PROMPT_FORMAT_SUCCESS_PS2,
+ PROMPT_FORMAT_SUCCESS_XBOX,
+
+ PROMPT_FORMAT_FAIL_GC,
+ PROMPT_FORMAT_FAIL_PS2,
+ PROMPT_FORMAT_FAIL_XBOX,
+
+ PROMPT_DELETE_CORRUPT_SUCCESS_GC,
+ PROMPT_DELETE_CORRUPT_SUCCESS_PS2,
+ PROMPT_DELETE_CORRUPT_SUCCESS_XBOX,
+
+ PROMPT_DELETE_CORRUPT_FAIL_GC,
+ PROMPT_DELETE_CORRUPT_FAIL_PS2,
+ PROMPT_DELETE_CORRUPT_FAIL_XBOX,
+
+ PROMPT_LOAD_CARD_EMPTY_GC,
+ PROMPT_LOAD_CARD_EMPTY_PS2,
+ PROMPT_LOAD_CARD_EMPTY_XBOX,
+ PROMPT_LOAD_CARD_EMPTY_XBOX_HD,
+#ifdef RAD_WIN32
+ PROMPT_LOAD_CARD_EMPTY_PC,
+#endif
+
+ PROMPT_DISPLAY_PROGRESSIVE_SCAN,
+ PROMPT_DISPLAY_PROGRESSIVE_SCAN_PS2,
+ PROMPT_DISPLAY_PROGRESSIVE_SCAN_CONFIRM,
+ PROMPT_DISPLAY_PROGRESSIVE_SCAN_TEST,
+
+ PROMPT_LOAD_DELETE_CORRUPT_GC,
+ PROMPT_LOAD_DELETE_CORRUPT_PS2,
+ PROMPT_LOAD_DELETE_CORRUPT_XBOX,
+ PROMPT_LOAD_DELETE_CORRUPT_XBOX_HD,
+
+ PROMPT_HD_FULL_XBOX,
+#ifdef RAD_WIN32
+ PROMPT_CONFIRM_RESTOREALLDEFAULTS,
+ PROMPT_CONFIRM_QUIT_TO_SYSTEM,
+ PROMPT_CONFIRM_SAVE_BEFORE_QUITTOSYSTEM,
+#endif
+ NUM_PROMPT_QUESTIONS
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenPrompt : public CGuiScreen
+{
+public:
+ CGuiScreenPrompt( Scrooby::Screen* pScreen,
+ CGuiEntity* pParent,
+ eGuiWindowID windowID = GUI_SCREEN_ID_GENERIC_PROMPT );
+
+ virtual ~CGuiScreenPrompt();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+ static void Display( int messageIndex,
+ CGuiEntity* pCallback,
+ int numResponses,
+ CGuiMenuPrompt::ePromptResponse* responses );
+
+ static void EnableDefaultToNo( bool enable );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ CGuiMenuPrompt* m_pMenu;
+
+ Scrooby::Sprite* m_messageIcon;
+ unsigned int m_elapsedTime;
+
+ Scrooby::Group* m_xboxDashboardLabel;
+
+ Scrooby::Text* m_promptMessage;
+ static int s_messageIndex;
+ static int s_numResponses;
+ static CGuiMenuPrompt::ePromptResponse s_responses[ CGuiMenuPrompt::MAX_NUM_RESPONSES ];
+ static CGuiEntity* s_pPromptCallback;
+ static bool s_defaultToNo;
+
+ UnicodeChar m_originalStringBuffer[ 256 ];
+
+ Scrooby::Layer* m_tvFrame;
+
+};
+
+inline void CGuiScreenPrompt::EnableDefaultToNo( bool enable )
+{
+ s_defaultToNo = enable;
+}
+
+#endif // GUISCREENPROMPT_H
diff --git a/game/code/presentation/gui/guisystem.cpp b/game/code/presentation/gui/guisystem.cpp
new file mode 100644
index 0000000..f7523e6
--- /dev/null
+++ b/game/code/presentation/gui/guisystem.cpp
@@ -0,0 +1,1845 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiSystem
+//
+// Description: Implementation of the CGuiSystem class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/09/21 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/gui/bootup/guimanagerlanguage.h>
+#include <presentation/gui/bootup/guimanagerbootup.h>
+#include <presentation/gui/bootup/guiscreenlanguage.h>
+#include <presentation/gui/backend/guimanagerbackend.h>
+#include <presentation/gui/frontend/guimanagerfrontend.h>
+#include <presentation/gui/minigame/guimanagerminigame.h>
+#include <presentation/gui/ingame/guimanageringame.h>
+#include <presentation/gui/guiuserinputhandler.h>
+#include <presentation/tutorialmode.h>
+
+#include <data/gamedatamanager.h>
+#include <main/game.h>
+#include <main/platform.h>
+#include <main/commandlineoptions.h>
+#include <memory/srrmemory.h>
+#include <mission/gameplaymanager.h>
+#include <mission/missionscriptloader.h>
+#include <input/inputmanager.h>
+#include <gameflow/gameflow.h>
+#include <render/rendermanager/rendermanager.h>
+#include <render/rendermanager/renderlayer.h>
+
+#include <p3d/view.hpp>
+#include <raddebug.hpp> // Foundation
+#include <raddebugwatch.hpp>
+#include <page.h>
+#include <polygon.h>
+#include <resourcemanager.h>
+#include <screen.h>
+#include <sprite.h>
+#include <text.h>
+#include <feloaders.h>
+
+// Static pointer to instance of singleton.
+CGuiSystem* CGuiSystem::spInstance = NULL;
+
+// Scrooby simulation time, needed for DrawFrame() render loop
+//
+unsigned int g_scroobySimulationTime = 0;
+
+//===========================================================================
+// Local Constants
+//===========================================================================
+
+#define LOAD_LEVEL_SPECIFIC_PROJECT
+
+/*
+#ifdef RAD_GAMECUBE
+ float g_gcnScreenScaleX = 1.1f;
+ float g_gcnScreenScaleY = 1.0f;
+#endif
+
+#ifdef RAD_PS2
+ float g_ps2screenScale = 1.096f;
+#endif
+*/
+
+#ifdef DEBUGWATCH
+ const char* GUI_WATCHER_NAMESPACE = "GUI System";
+ float g_wGuiSimulationTimeFactor = 1.0f;
+ int g_wGuiMessage = 0;
+ int g_wGuiMessageParam1 = 0;
+ int g_wGuiMessageParam2 = 0;
+
+ static void SendMsgToGuiSystem()
+ {
+ GetGuiSystem()->HandleMessage( static_cast<eGuiMessage>( g_wGuiMessage ),
+ g_wGuiMessageParam1,
+ g_wGuiMessageParam2 );
+ }
+
+ namespace Scrooby
+ {
+ extern float g_CameraNearPlane;
+ extern float g_CameraFarPlane;
+ }
+
+/*
+#ifdef RAD_PS2
+ static void UpdatePS2ScreenScale()
+ {
+ Scrooby::App::GetInstance()->EnableScreenScaling( true,
+ g_ps2screenScale,
+ g_ps2screenScale );
+ }
+#endif
+*/
+
+ // for Formatting Scrooby Drawables in Run-time
+ //
+ static const char* WATCHER_NAMESPACE_SCROOBY = "GUI System - Scrooby";
+
+ static Scrooby::Page* g_wCurrentScroobyPage = NULL;
+ static char g_wScroobyPageName[ 32 ];
+ static void SetCurrentScroobyPage()
+ {
+ Scrooby::Project* currentProject = Scrooby::App::GetInstance()->GetProject();
+ rAssert( currentProject );
+
+ Scrooby::Screen* currentScreen = currentProject->GetCurrentScreen();
+ rAssert( currentScreen );
+
+ g_wCurrentScroobyPage = currentScreen->GetPage( g_wScroobyPageName );
+ rWarning( g_wCurrentScroobyPage );
+ }
+
+ static Scrooby::Drawable* g_wCurrentScroobyDrawable = NULL;
+
+ static int g_wScroobyPosX = 0;
+ static int g_wScroobyPosY = 0;
+ static void SetScroobyDrawablePosition()
+ {
+ if( g_wCurrentScroobyDrawable != NULL )
+ {
+ g_wCurrentScroobyDrawable->SetPosition( g_wScroobyPosX, g_wScroobyPosY );
+ }
+ }
+
+ static float g_wScroobyAlpha = 0.0f;
+ static void SetScroobyDrawableAlpha()
+ {
+ if( g_wCurrentScroobyDrawable != NULL )
+ {
+ g_wCurrentScroobyDrawable->SetAlpha( g_wScroobyAlpha );
+ }
+ }
+
+ static void UpdateScroobyDrawableAttributes()
+ {
+ if( g_wCurrentScroobyDrawable != NULL )
+ {
+ g_wCurrentScroobyDrawable->GetOriginPosition( g_wScroobyPosX,
+ g_wScroobyPosY );
+ g_wScroobyAlpha = g_wCurrentScroobyDrawable->GetAlpha();
+ }
+ }
+
+ static char g_wScroobyTextName[ 32 ];
+ static void SetCurrentScroobyDrawableAsText()
+ {
+ if( g_wCurrentScroobyPage != NULL )
+ {
+ g_wCurrentScroobyDrawable = g_wCurrentScroobyPage->GetText( g_wScroobyTextName );
+ UpdateScroobyDrawableAttributes();
+ }
+
+ rWarning( g_wCurrentScroobyDrawable );
+ }
+
+ static char g_wScroobySpriteName[ 32 ];
+ static void SetCurrentScroobyDrawableAsSprite()
+ {
+ if( g_wCurrentScroobyPage != NULL )
+ {
+ g_wCurrentScroobyDrawable = g_wCurrentScroobyPage->GetSprite( g_wScroobySpriteName );
+ UpdateScroobyDrawableAttributes();
+ }
+
+ rWarning( g_wCurrentScroobyDrawable );
+ }
+
+ static char g_wScroobyPolygonName[ 32 ];
+ static void SetCurrentScroobyDrawableAsPolygon()
+ {
+ if( g_wCurrentScroobyPage != NULL )
+ {
+ g_wCurrentScroobyDrawable = g_wCurrentScroobyPage->GetPolygon( g_wScroobyPolygonName );
+ UpdateScroobyDrawableAttributes();
+ }
+
+ rWarning( g_wCurrentScroobyDrawable );
+ }
+
+ int g_currentLanguage = 0;
+
+ static void ToggleNextLanguage()
+ {
+ g_currentLanguage = (g_currentLanguage + 1) % NUM_SRR2_LANGUAGES;
+ CGuiTextBible::SetCurrentLanguage( SRR2_LANGUAGE[ g_currentLanguage ] );
+ }
+
+#endif // DEBUGWATCH
+
+const char* PROJECT_FILE_LANGUAGE = "art\\frontend\\scrooby\\language.p3d";
+const char* PROJECT_FILE_BOOTUP = "art\\frontend\\scrooby\\bootup.p3d";
+const char* PROJECT_FILE_BACKEND = "art\\frontend\\scrooby\\backend.p3d";
+const char* PROJECT_FILE_FRONTEND = "art\\frontend\\scrooby\\frontend.p3d";
+const char* PROJECT_FILE_MINIGAME = "art\\frontend\\scrooby\\minigame.p3d";
+const char* PROJECT_FILE_INGAME = "art\\frontend\\scrooby\\ingame.p3d";
+
+const char* LICENSE_SCREEN_IMAGE_DIR = "art\\frontend\\dynaload\\images\\license\\";
+#ifdef RAD_WIN32
+const char* MOUSE_CURSOR_DIR = "art\\frontend\\dynaload\\images\\";
+#endif
+
+const char* INGAME_LEVEL_PROJECT_FILES[] =
+{
+ "art\\frontend\\scrooby\\ingamel1.p3d",
+ "art\\frontend\\scrooby\\ingamel2.p3d",
+ "art\\frontend\\scrooby\\ingamel3.p3d",
+ "art\\frontend\\scrooby\\ingamel4.p3d",
+ "art\\frontend\\scrooby\\ingamel5.p3d",
+ "art\\frontend\\scrooby\\ingamel6.p3d",
+ "art\\frontend\\scrooby\\ingamel7.p3d"
+};
+
+const char* TEXT_BIBLE_NAME = "srr2";
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//==============================================================================
+// CGuiSystem::CreateInstance
+//==============================================================================
+//
+// Description: - Creates the CGuiSystem.
+//
+// Parameters: None.
+//
+// Return: Pointer to the CGuiSystem.
+//
+// Constraints: This is a singleton so only one instance is allowed.
+//
+//==============================================================================
+CGuiSystem* CGuiSystem::CreateInstance()
+{
+MEMTRACK_PUSH_GROUP( "CGUISystem" );
+ spInstance = new CGuiSystem;
+ rAssert( spInstance != NULL );
+MEMTRACK_POP_GROUP( "CGUISystem" );
+
+ return spInstance;
+}
+
+//==============================================================================
+// CGuiSystem::DestroyInstance
+//==============================================================================
+//
+// Description: Destroy the GUI system.
+//
+// Parameters: None.
+//
+// Return: None.
+//
+//==============================================================================
+void CGuiSystem::DestroyInstance()
+{
+ rAssert( spInstance != NULL );
+
+ delete spInstance;
+ spInstance = NULL;
+}
+
+//==============================================================================
+// CGuiSystem::GetInstance
+//==============================================================================
+//
+// Description: - Access point for the CGuiSystem singleton.
+// - Creates the CGuiSystem if needed.
+//
+// Parameters: None.
+//
+// Return: Pointer to the CGuiSystem.
+//
+// Constraints: This is a singleton so only one instance is allowed.
+//
+//==============================================================================
+CGuiSystem* CGuiSystem::GetInstance()
+{
+ rAssert( spInstance != NULL );
+
+ return spInstance;
+}
+
+//===========================================================================
+// CGuiSystem::CGuiSystem
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+CGuiSystem::CGuiSystem()
+: CGuiEntity( NULL ),
+ m_state( GUI_UNINITIALIZED ),
+ m_pTextBible( NULL ),
+ m_pManagerLanguage( NULL ),
+ m_pManagerBootUp( NULL ),
+ m_pManagerBackEnd( NULL ),
+ m_pManagerFrontEnd( NULL ),
+ m_pManagerMiniGame( NULL ),
+ m_pManagerInGame( NULL ),
+ m_pUserInputHandlers( NULL ),
+ m_numUserInputHandlers( 0 ),
+ m_registeredUserInputHandlers( 0 ),
+ m_primaryController(-1),
+ m_pApp( NULL ),
+ m_pProject( NULL ),
+ m_pLevelProject( NULL ),
+ m_pBackendProject( NULL ),
+ m_pLoadingCallback( NULL ),
+ m_isSplashScreenFinished( false ),
+ m_isRadarEnabled( true ),
+ m_isShowCreditsUponReturnToFE( false )
+{
+ m_pTextBible = new CGuiTextBible;
+ rAssert( m_pTextBible != NULL );
+}
+
+//===========================================================================
+// CGuiSystem::~CGuiSystem
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+CGuiSystem::~CGuiSystem()
+{
+ // unload backend Scrooby project
+ //
+ if( m_pBackendProject != NULL )
+ {
+ m_pApp->UnloadProject( m_pBackendProject );
+ m_pBackendProject = NULL;
+ }
+
+ // delete text bible
+ //
+ if( m_pTextBible != NULL )
+ {
+ delete m_pTextBible;
+ m_pTextBible = NULL;
+ }
+
+ // delete all GUI managers (if not already deleted)
+ //
+ if( m_pManagerFrontEnd != NULL )
+ {
+ delete m_pManagerFrontEnd;
+ m_pManagerFrontEnd = NULL;
+ }
+
+ if( m_pManagerMiniGame != NULL )
+ {
+ delete m_pManagerMiniGame;
+ m_pManagerMiniGame = NULL;
+ }
+
+ if( m_pManagerInGame != NULL )
+ {
+ delete m_pManagerInGame;
+ m_pManagerInGame = NULL;
+ }
+
+ if( m_pManagerBackEnd != NULL )
+ {
+ delete m_pManagerBackEnd;
+ m_pManagerBackEnd = NULL;
+ }
+
+ if( m_pManagerBootUp != NULL )
+ {
+ delete m_pManagerBootUp;
+ m_pManagerBootUp = NULL;
+ }
+
+ if( m_pManagerLanguage != NULL )
+ {
+ delete m_pManagerLanguage;
+ m_pManagerLanguage = NULL;
+ }
+
+ // delete all GUI user input handlers
+ //
+ if(m_pUserInputHandlers != NULL )
+ {
+ for( int i = 0; i < m_numUserInputHandlers; i++ )
+ {
+ if( m_pUserInputHandlers[ i ] != NULL )
+ {
+ m_pUserInputHandlers[ i ]->Release();
+ m_pUserInputHandlers[ i ] = NULL;
+ }
+ }
+
+ delete [] m_pUserInputHandlers;
+ m_pUserInputHandlers = NULL;
+ }
+
+ // delete Scrooby App singleton
+ //
+ if( m_pApp != NULL )
+ {
+ Scrooby::App::DeleteInstance();
+ m_pApp = NULL;
+ }
+}
+
+//===========================================================================
+// CGuiSystem::Init
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiSystem::Init()
+{
+MEMTRACK_PUSH_GROUP( "CGUISystem" );
+ rAssert( m_state == GUI_UNINITIALIZED );
+
+ m_pApp = Scrooby::App::GetInstance();
+ rAssert( m_pApp != NULL );
+
+ // set Scrooby to use full image names depending on whether or not
+ // resource files are joined together into single P3D project file
+ //
+ m_pApp->SetFullImageNames( CommandLineOptions::Get( CLO_FE_UNJOINED ) );
+
+ // set FE text bible loader to only load one string table for the
+ // current language
+ //
+ FeTextBibleLoader::SetOnlyLoadCurrentLanguage( true );
+
+#if defined( PAL ) && defined( RAD_XBOX ) && !defined( RAD_RELEASE )
+ // TC: disable this for Xbox non-release PAL builds so that I can
+ // change languages on-the-fly w/ the Watcher
+ //
+ FeTextBibleLoader::SetOnlyLoadCurrentLanguage( false );
+#endif
+
+ // setup the GUI render layer
+ //
+ GetRenderManager()->mpLayer(RenderEnums::GUI)->AddGuts( m_pApp );
+ GetRenderManager()->mpLayer(RenderEnums::GUI)->FreezeCorpse();
+ GetRenderManager()->mpLayer(RenderEnums::GUI)->pView( 0 )->SetClearColour( tColour( 0, 0, 0 ) );
+
+ HeapMgr()->PushHeap( GMA_PERSISTENT );
+
+ // create array of user input handlers
+ //
+ m_numUserInputHandlers = GetInputManager()->GetMaxControllers();
+ m_pUserInputHandlers = new CGuiUserInputHandler*[ m_numUserInputHandlers ];
+ rAssert( m_pUserInputHandlers != NULL );
+
+ // create each user input handler
+ //
+ for( int i = 0; i < m_numUserInputHandlers; i++ )
+ {
+ m_pUserInputHandlers[ i ] = new CGuiUserInputHandler;
+ rAssert( m_pUserInputHandlers[ i ] != NULL );
+ m_pUserInputHandlers[ i ]->AddRef();
+ }
+
+ HeapMgr()->PopHeap( GMA_PERSISTENT );
+
+ // register GUI as game data handler
+ //
+ GetGameDataManager()->RegisterGameData( this, 1, "GUI System" );
+
+#if defined( PAL ) && !defined( RAD_DEMO )
+/*
+ #ifdef RAD_GAMECUBE
+ // GC ONLY: load language configuration file
+ //
+ HeapMgr()->PushHeap( GMA_TEMP );
+ GetMissionScriptLoader()->LoadScriptAsync( "language.ini" );
+ HeapMgr()->PopHeap( GMA_TEMP );
+ #endif
+*/
+ // load language Scrooby project (into FE heap)
+ //
+ GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY,
+ PROJECT_FILE_LANGUAGE,
+ GMA_LEVEL_FE,
+ SCROOBY_INVENTORY_LANGUAGE,
+ SCROOBY_INVENTORY_LANGUAGE );
+
+ m_state = LANGUAGE_LOADING;
+#else
+ this->OnInitBootUp();
+#endif // PAL
+
+#ifdef DEBUGWATCH
+ this->RegisterWatcherStuff();
+#endif
+ MEMTRACK_POP_GROUP( "CGUISystem" );
+}
+
+//===========================================================================
+// CGuiSystem::Update
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiSystem::Update( unsigned int elapsedTime )
+{
+#ifdef RAD_RELEASE
+ // TC [HACK]: To avoid any choppiness in FE animations
+ //
+ const unsigned int MAX_ELAPSED_TIME = 100; // in msec
+ if( elapsedTime > MAX_ELAPSED_TIME )
+ {
+ rTunePrintf( "*** WARNING: GUI System elapsed time (%d ms) exceeded MAX_ELAPSED_TIME (%d ms)!\n",
+ elapsedTime, MAX_ELAPSED_TIME );
+
+ elapsedTime = 20;
+ }
+#endif
+
+#ifdef DEBUGWATCH
+ elapsedTime = static_cast<unsigned int>( g_wGuiSimulationTimeFactor *
+ elapsedTime );
+#endif
+
+ // check for repeated inputs
+ for( int i = 0; i < m_numUserInputHandlers; i++ )
+ {
+ m_pUserInputHandlers[ i ]->Update( elapsedTime, i );
+ }
+
+ // set scrooby simulation time for use in the rendering loop
+ //
+ g_scroobySimulationTime = elapsedTime;
+
+ // send update message to current GUI manager
+ //
+ CGuiManager* currentManager = this->GetCurrentManager();
+ if( currentManager != NULL )
+ {
+ currentManager->HandleMessage( GUI_MSG_UPDATE, elapsedTime );
+ }
+
+ if( m_state == DEMO_ACTIVE )
+ {
+ if( m_pManagerInGame != NULL )
+ {
+ m_pManagerInGame->HandleMessage( GUI_MSG_UPDATE, elapsedTime );
+ }
+ }
+}
+
+//===========================================================================
+// CGuiSystem::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters:
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiSystem::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ rAssertMsg( 0, "*** Call GuiSystem::Update() instead! ***" );
+
+ break;
+ }
+
+ case GUI_MSG_INIT_FRONTEND:
+ {
+ this->OnInitFrontEnd();
+
+ break;
+ }
+ case GUI_MSG_RELEASE_FRONTEND:
+ {
+ this->OnReleaseFrontEnd();
+
+ break;
+ }
+ case GUI_MSG_RUN_FRONTEND:
+ {
+ // thaw frontend render layer
+ GetRenderManager()->mpLayer(RenderEnums::GUI)->Thaw();
+
+ m_pApp->SetProject( m_pProject );
+
+ m_state = FRONTEND_ACTIVE;
+
+ // start the frontend manager
+ rAssert( m_pManagerFrontEnd );
+ if( param1 != 0 )
+ {
+ m_pManagerFrontEnd->Start( static_cast<CGuiWindow::eGuiWindowID>( param1 ) );
+ }
+ else
+ {
+ m_pManagerFrontEnd->Start();
+ }
+
+/*
+#ifdef RAD_GAMECUBE
+ // enable screen scaling (for GameCube)
+ m_pApp->EnableScreenScaling( true, g_gcnScreenScaleX, g_gcnScreenScaleY );
+#endif
+
+#ifdef RAD_PS2
+ // enable screen scaling (for PS2)
+ m_pApp->EnableScreenScaling( true, g_ps2screenScale, g_ps2screenScale );
+#endif
+*/
+
+ break;
+ }
+
+ case GUI_MSG_INIT_MINIGAME:
+ {
+ this->OnInitMiniGame();
+
+ break;
+ }
+ case GUI_MSG_RELEASE_MINIGAME:
+ {
+ this->OnReleaseMiniGame();
+
+ break;
+ }
+ case GUI_MSG_RUN_MINIGAME:
+ {
+ m_pApp->SetProject( m_pProject );
+
+ m_state = MINIGAME_ACTIVE;
+
+ // start the minigame manager
+ //
+ rAssert( m_pManagerMiniGame != NULL );
+ if( param1 != 0 )
+ {
+ m_pManagerMiniGame->Start( static_cast<CGuiWindow::eGuiWindowID>( param1 ) );
+ }
+ else
+ {
+ m_pManagerMiniGame->Start();
+ }
+
+ break;
+ }
+
+ case GUI_MSG_INIT_INGAME:
+ {
+ this->OnInitInGame();
+
+ break;
+ }
+ case GUI_MSG_RELEASE_INGAME:
+ {
+ this->OnReleaseInGame();
+
+ break;
+ }
+ case GUI_MSG_RUN_INGAME:
+ {
+ m_pApp->SetProject( m_pProject );
+
+ m_state = INGAME_ACTIVE;
+
+ // start the in-game manager
+ rAssert( m_pManagerInGame );
+ m_pManagerInGame->Start();
+
+ break;
+ }
+
+ case GUI_MSG_INIT_BOOTUP:
+ {
+ this->OnInitBootUp();
+
+ break;
+ }
+ case GUI_MSG_RELEASE_BOOTUP:
+ {
+ this->OnReleaseBootUp();
+
+ break;
+ }
+
+ case GUI_MSG_RUN_BACKEND:
+ {
+ m_pApp->SetProject( m_pBackendProject );
+
+ m_state = GUI_IDLE;
+
+ rAssert( m_pManagerBackEnd );
+ m_pManagerBackEnd->HandleMessage( message, param1, param2 );
+
+ break;
+ }
+ case GUI_MSG_RUN_DEMO:
+ {
+ m_state = DEMO_ACTIVE;
+
+ rAssert( m_pManagerBackEnd );
+ m_pManagerBackEnd->HandleMessage( message, param1, param2 );
+
+ break;
+ }
+ case GUI_MSG_PROJECT_LOAD_COMPLETE:
+ {
+ this->OnProjectLoadComplete( (Scrooby::Project*)param1 );
+
+ break;
+ }
+ default:
+ {
+ // relay message to current GUI manager
+ //
+ CGuiManager* currentManager = this->GetCurrentManager();
+ if( currentManager != NULL )
+ {
+ currentManager->HandleMessage( message, param1, param2 );
+ }
+
+ break;
+ }
+ }
+}
+
+//===========================================================================
+// CGuiSystem::OnProjectLoadComplete
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiSystem::OnProjectLoadComplete( Scrooby::Project* pProject )
+{
+MEMTRACK_PUSH_GROUP( "CGUISystem" );
+ rAssert( pProject != NULL );
+ m_pProject = pProject;
+
+ // update reference to text bible
+ //
+ rAssert( m_pTextBible != NULL );
+ m_pTextBible->SetTextBible( TEXT_BIBLE_NAME );
+
+ switch( m_state )
+ {
+ case LANGUAGE_LOADING:
+ {
+ HeapMgr()->PushHeap( GMA_LEVEL_FE );
+
+ m_pManagerLanguage = new CGuiManagerLanguage( m_pProject, this );
+ rAssert( m_pManagerLanguage != NULL );
+
+ // Populate screens
+ //
+ m_pManagerLanguage->Populate();
+
+ HeapMgr()->PopHeap( GMA_LEVEL_FE );
+
+ m_state = LANGUAGE_ACTIVE;
+
+ // Start it up!
+ //
+ m_pManagerLanguage->Start();
+
+ break;
+ }
+ case BOOTUP_LOADING:
+ {
+ HeapMgr()->PushHeap( GMA_LEVEL_FE );
+
+ // Create bootup manager (for license screen, etc.)
+ //
+ m_pManagerBootUp = new CGuiManagerBootUp( m_pProject, this );
+ rAssert( m_pManagerBootUp );
+
+ // Populate screens
+ //
+ m_pManagerBootUp->Populate();
+
+ // Start it up!
+ //
+ m_pManagerBootUp->Start();
+
+ m_pApp->SetProject( m_pProject );
+
+ // thaw frontend render layer
+ GetRenderManager()->mpLayer(RenderEnums::GUI)->Thaw();
+
+ m_state = BACKEND_LOADING;
+
+ HeapMgr()->PopHeap( GMA_LEVEL_FE );
+
+ break;
+ }
+ case BACKEND_LOADING:
+ {
+ HeapMgr()->PushHeap( GMA_PERSISTENT );
+
+ // now that the text bible loaded from the backend project is residing
+ // in the persistend heap, there is no need to load any more instances
+ // of the text bible from subsequent scrooby project loads
+ //
+ FeTextBibleLoader::SetUseLastLoadedTextBible( true );
+
+ m_pBackendProject = pProject;
+
+ // Create backend manager (for loading screens)
+ //
+ m_pManagerBackEnd = new CGuiManagerBackEnd( m_pProject, this );
+ rAssert( m_pManagerBackEnd );
+
+ // Populate screens
+ //
+ m_pManagerBackEnd->Populate();
+
+ m_pManagerBackEnd->Start();
+
+ if( !CommandLineOptions::Get( CLO_SKIP_FE ) )
+ {
+ m_state = FRONTEND_LOADING_DURING_BOOTUP;
+ }
+ else
+ {
+ m_state = BOOTUP_ACTIVE;
+ }
+
+ HeapMgr()->PopHeap(GMA_PERSISTENT);
+
+ break;
+ }
+ case FRONTEND_LOADING_DURING_BOOTUP:
+ {
+ m_state = BOOTUP_ACTIVE;
+
+ // follow-through
+ }
+ case FRONTEND_LOADING:
+ {
+ HeapMgr()->PushHeap( GMA_LEVEL_FE );
+
+ // Create FE screen manager
+ //
+ m_pManagerFrontEnd = new CGuiManagerFrontEnd( m_pProject, this );
+ rAssert( m_pManagerFrontEnd );
+
+ // Populate screens
+ //
+ m_pManagerFrontEnd->Populate();
+
+ // notify callback
+ //
+ if( m_pLoadingCallback != NULL )
+ {
+ m_pLoadingCallback->OnGuiLoadComplete( IGuiLoadingCallback::GUI_LOADED_FRONT_END );
+ }
+
+ HeapMgr()->PopHeap(GMA_LEVEL_FE);
+
+ break;
+ }
+ case MINIGAME_LOADING:
+ {
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ // create mini-game manager
+ //
+ m_pManagerMiniGame = new CGuiManagerMiniGame( m_pProject, this );
+ rAssert( m_pManagerMiniGame != NULL );
+
+ // Populate screens
+ //
+ m_pManagerMiniGame->Populate();
+
+ // notify callback
+ //
+ if( m_pLoadingCallback != NULL )
+ {
+ m_pLoadingCallback->OnGuiLoadComplete( IGuiLoadingCallback::GUI_LOADED_MINI_GAME );
+ }
+
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+
+ break;
+ }
+ case INGAME_LOADING:
+ {
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ // Create InGame manager
+ //
+#ifdef LOAD_LEVEL_SPECIFIC_PROJECT
+ if( m_pLevelProject == NULL )
+ {
+ m_pLevelProject = m_pProject;
+ }
+ else
+#endif // LOAD_LEVEL_SPECIFIC_PROJECT
+ {
+ m_pManagerInGame = new CGuiManagerInGame( m_pProject, this );
+ rAssert( m_pManagerInGame );
+
+ // Populate screens
+ //
+ m_pManagerInGame->Populate();
+
+ // notify callback
+ //
+ if( m_pLoadingCallback != NULL )
+ {
+ m_pLoadingCallback->OnGuiLoadComplete( IGuiLoadingCallback::GUI_LOADED_IN_GAME );
+ }
+ }
+
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Invalid state!" );
+
+ break;
+ }
+ }
+MEMTRACK_POP_GROUP("CGUISystem");
+}
+
+//===========================================================================
+// CGuiSystem::GotoScreen
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiSystem::GotoScreen( unsigned int screenID,
+ unsigned int param1,
+ unsigned int param2,
+ unsigned int windowOptions )
+{
+ CGuiManager* currentManager = this->GetCurrentManager();
+ rAssert( currentManager != NULL );
+
+ if( param1 != 0 || param2 != 0 )
+ {
+ currentManager->HandleMessage( GUI_MSG_SET_GOTO_SCREEN_PARAMETERS,
+ param1, param2 );
+ }
+
+ currentManager->HandleMessage( GUI_MSG_GOTO_SCREEN, screenID, windowOptions );
+}
+
+//===========================================================================
+// CGuiSystem::GetCurrentManager
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+CGuiManager* CGuiSystem::GetCurrentManager() const
+{
+ CGuiManager* currentManager = NULL;
+
+ switch( m_state )
+ {
+ case FRONTEND_ACTIVE:
+ {
+ currentManager = m_pManagerFrontEnd;
+
+ break;
+ }
+ case MINIGAME_ACTIVE:
+ {
+ currentManager = m_pManagerMiniGame;
+
+ break;
+ }
+ case INGAME_ACTIVE:
+ {
+ currentManager = m_pManagerInGame;
+
+ break;
+ }
+ case BOOTUP_ACTIVE:
+ case BACKEND_LOADING:
+ case FRONTEND_LOADING_DURING_BOOTUP:
+ {
+ currentManager = m_pManagerBootUp;
+
+ break;
+ }
+ case LANGUAGE_ACTIVE:
+ {
+ currentManager = m_pManagerLanguage;
+
+ break;
+ }
+ case GUI_IDLE:
+ case DEMO_ACTIVE:
+ case FRONTEND_LOADING:
+ case MINIGAME_LOADING:
+ case INGAME_LOADING:
+ {
+ currentManager = m_pManagerBackEnd;
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ return currentManager;
+}
+
+//===========================================================================
+// CGuiSystem::RegisterUserInputHandlers
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiSystem::RegisterUserInputHandlers( int controllerIDs )
+{
+ for( int i = 0; i < m_numUserInputHandlers; i++ )
+ {
+ if( (controllerIDs & (1 << i)) > 0 )
+ {
+ GetInputManager()->RegisterMappable( i, m_pUserInputHandlers[ i ] );
+
+ m_registeredUserInputHandlers |= (1 << i);
+ }
+ }
+}
+
+//===========================================================================
+// CGuiSystem::UnregisterUserInputHandlers
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiSystem::UnregisterUserInputHandlers( int controllerIDs )
+{
+ for( int i = 0; i < m_numUserInputHandlers; i++ )
+ {
+ if( (controllerIDs & (1 << i)) > 0 )
+ {
+ GetInputManager()->UnregisterMappable( i, m_pUserInputHandlers[ i ] );
+
+ m_registeredUserInputHandlers &= ~(1 << i);
+ }
+ }
+
+ rAssertMsg( m_registeredUserInputHandlers == 0,
+ "*** WARNING: Not all GUI user input handlers were un-registered!" );
+}
+
+//===========================================================================
+// CGuiSystem::GetUserInputHandler
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+CGuiUserInputHandler*
+CGuiSystem::GetUserInputHandler( int controllerId ) const
+{
+ rAssert( controllerId >= 0 && controllerId < m_numUserInputHandlers );
+ rAssert( m_pUserInputHandlers != NULL );
+
+ if( (m_registeredUserInputHandlers & (1 << controllerId)) > 0 )
+ {
+ return m_pUserInputHandlers[ controllerId ];
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+//===========================================================================
+// CGuiSystem::LoadData
+//===========================================================================
+// Description: Load GUI data from memory card.
+//
+//===========================================================================
+void
+CGuiSystem::LoadData( const GameDataByte* dataBuffer, unsigned int numBytes )
+{
+ rAssert( dataBuffer != NULL && numBytes == 1 );
+ m_isRadarEnabled = ( dataBuffer[ 0 ] != 0 );
+}
+
+//===========================================================================
+// CGuiSystem::SaveData
+//===========================================================================
+// Description: Save GUI data to memory card.
+//
+//===========================================================================
+void
+CGuiSystem::SaveData( GameDataByte* dataBuffer, unsigned int numBytes )
+{
+ rAssert( dataBuffer != NULL && numBytes == 1 );
+ dataBuffer[ 0 ] = m_isRadarEnabled ? 1 : 0;
+}
+
+//===========================================================================
+// CGuiSystem::ResetData
+//===========================================================================
+// Description: Reset GUI data to defaults.
+//
+//===========================================================================
+void
+CGuiSystem::ResetData()
+{
+ m_isRadarEnabled = true;
+}
+
+//===========================================================================
+// Private Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiSystem::OnInitBootUp
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiSystem::OnInitBootUp()
+{
+ char languageDir[ 16 ];
+ languageDir[ 0 ] = '\0';
+
+#ifdef PAL
+ switch( CGuiTextBible::GetCurrentLanguage() )
+ {
+ case Scrooby::XL_FRENCH:
+ {
+ strcpy( languageDir, "french\\" );
+
+ break;
+ }
+ case Scrooby::XL_GERMAN:
+ {
+ strcpy( languageDir, "german\\" );
+
+ break;
+ }
+ case Scrooby::XL_SPANISH:
+ {
+ strcpy( languageDir, "spanish\\" );
+
+ break;
+ }
+ default:
+ {
+ rAssert( CGuiTextBible::GetCurrentLanguage() == Scrooby::XL_ENGLISH );
+
+ break;
+ }
+ }
+#endif // PAL
+
+ char licenseImageFile[ 256 ];
+ sprintf( licenseImageFile,
+#ifdef RAD_GAMECUBE
+ "%s%slicenseG.p3d",
+#endif
+#ifdef RAD_PS2
+ "%s%slicenseP.p3d",
+#endif
+#ifdef RAD_XBOX
+ "%s%slicenseX.p3d",
+#endif
+#ifdef RAD_WIN32
+ "%s%slicensePC.p3d",
+#endif
+ LICENSE_SCREEN_IMAGE_DIR,
+ languageDir );
+
+ //Load the mouse cursor
+#ifdef RAD_WIN32
+ char cursorImageFile[256];
+ sprintf( cursorImageFile, "%smouse_cursor.p3d", MOUSE_CURSOR_DIR );
+
+ GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D,
+ cursorImageFile,
+ GMA_PERSISTENT,
+ "Default",
+ "Default" );
+#endif
+
+ GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D,
+ licenseImageFile,
+ GMA_LEVEL_FE,
+ SCROOBY_INVENTORY_BOOTUP,
+ SCROOBY_INVENTORY_BOOTUP );
+
+ // load bootup Scrooby project (into FE heap)
+ //
+ GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY,
+ PROJECT_FILE_BOOTUP,
+ GMA_LEVEL_FE,
+ SCROOBY_INVENTORY_BOOTUP,
+ SCROOBY_INVENTORY_BOOTUP );
+
+ // load backend Scrooby project (into PERSISTENT heap)
+ //
+ GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY,
+ PROJECT_FILE_BACKEND,
+ GMA_PERSISTENT, // This is because the loading screen always stays around
+ SCROOBY_INVENTORY_BACKEND,
+ SCROOBY_INVENTORY_BACKEND );
+
+ if( !CommandLineOptions::Get( CLO_SKIP_FE ) )
+ {
+ // load frontend Scrooby project (into FE heap)
+ //
+ GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY,
+ PROJECT_FILE_FRONTEND,
+ GMA_LEVEL_FE,
+ SCROOBY_INVENTORY_FRONTEND,
+ SCROOBY_INVENTORY_FRONTEND );
+ }
+
+ m_state = BOOTUP_LOADING;
+}
+
+//===========================================================================
+// CGuiSystem::OnReleaseBootUp
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiSystem::OnReleaseBootUp()
+{
+ HeapMgr()->PushHeap( GMA_LEVEL_FE );
+
+ Scrooby::Project* pScroobyProject = NULL;
+
+ if( m_pManagerLanguage != NULL )
+ {
+ pScroobyProject = m_pManagerLanguage->GetScroobyProject();
+
+ // destroy language manager
+ //
+ delete m_pManagerLanguage;
+ m_pManagerLanguage = NULL;
+
+ if( pScroobyProject != NULL )
+ {
+ m_pApp->UnloadProject( pScroobyProject );
+ }
+ }
+
+ if( m_pManagerBootUp != NULL )
+ {
+ pScroobyProject = m_pManagerBootUp->GetScroobyProject();
+
+ // destroy bootup manager
+ delete m_pManagerBootUp;
+ m_pManagerBootUp = NULL;
+
+ if( pScroobyProject != NULL )
+ {
+ m_pApp->UnloadProject( pScroobyProject );
+ }
+ }
+
+ // update reference to text bible
+ //
+ rAssert( m_pTextBible != NULL );
+ m_pTextBible->SetTextBible( TEXT_BIBLE_NAME );
+
+ HeapMgr()->PopHeap(GMA_LEVEL_FE);
+
+#ifdef PAL
+ this->FormatTutorialTextWithLineBreaks();
+#endif
+
+ m_state = GUI_IDLE;
+}
+
+//===========================================================================
+// CGuiSystem::OnInitFrontEnd
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiSystem::OnInitFrontEnd()
+{
+ // load frontend Scrooby project (into FE heap)
+ GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY,
+ PROJECT_FILE_FRONTEND,
+ GMA_LEVEL_FE,
+ SCROOBY_INVENTORY_FRONTEND,
+ SCROOBY_INVENTORY_FRONTEND );
+
+ m_state = FRONTEND_LOADING;
+}
+
+//===========================================================================
+// CGuiSystem::OnReleaseFrontEnd
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiSystem::OnReleaseFrontEnd()
+{
+ HeapMgr()->PushHeap( GMA_LEVEL_FE );
+
+ if( m_pManagerFrontEnd != NULL )
+ {
+ // destroy frontend manager
+ delete m_pManagerFrontEnd;
+ m_pManagerFrontEnd = NULL;
+ }
+
+ // unload frontend project resources
+ if( m_pProject != NULL )
+ {
+ m_pApp->UnloadProject( m_pProject );
+ m_pProject = NULL;
+ }
+
+/*
+#ifdef RAD_GAMECUBE
+ // disable screen scaling (for GameCube)
+ m_pApp->EnableScreenScaling( false );
+#endif
+
+#ifdef RAD_PS2
+ // disable screen scaling (for PS2)
+ m_pApp->EnableScreenScaling( false );
+#endif
+*/
+
+ HeapMgr()->PopHeap(GMA_LEVEL_FE);
+
+ m_state = GUI_IDLE;
+}
+
+//===========================================================================
+// CGuiSystem::OnInitMiniGame
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiSystem::OnInitMiniGame()
+{
+ // load mini-game Scrooby project
+ //
+ GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY,
+ PROJECT_FILE_MINIGAME,
+ GMA_LEVEL_HUD,
+ SCROOBY_INVENTORY_MINIGAME,
+ SCROOBY_INVENTORY_MINIGAME );
+
+ // load 3D characters
+ //
+// CGuiManagerMiniGame::LoadCharacters();
+
+ m_state = MINIGAME_LOADING;
+}
+
+//===========================================================================
+// CGuiSystem::OnReleaseMiniGame
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiSystem::OnReleaseMiniGame()
+{
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ // unload 3D characters
+ //
+// CGuiManagerMiniGame::UnloadCharacters();
+
+ // destroy MiniGame manager
+ //
+ if( m_pManagerMiniGame != NULL )
+ {
+ delete m_pManagerMiniGame;
+ m_pManagerMiniGame = NULL;
+ }
+
+ // unload mini-game project resources
+ //
+ if( m_pProject != NULL )
+ {
+ m_pApp->UnloadProject( m_pProject );
+ m_pProject = NULL;
+ }
+
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+
+ m_state = GUI_IDLE;
+}
+
+//===========================================================================
+// CGuiSystem::OnInitInGame
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiSystem::OnInitInGame()
+{
+ int currentLevel = GetGameplayManager()->GetCurrentLevelIndex();
+ rAssert( currentLevel >= 0 );
+
+ // substitute levels > 7 with level 1
+ //
+ if( static_cast<unsigned int>( currentLevel ) >= sizeof( INGAME_LEVEL_PROJECT_FILES ) /
+ sizeof( INGAME_LEVEL_PROJECT_FILES[ 0 ] ) )
+ {
+ currentLevel = 0;
+ }
+
+#ifdef LOAD_LEVEL_SPECIFIC_PROJECT
+ // load level-specific ingame Scrooby project (into HUD heap)
+ GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY,
+ INGAME_LEVEL_PROJECT_FILES[ currentLevel ],
+ GMA_LEVEL_HUD,
+ SCROOBY_INVENTORY_INGAME_LEVEL,
+ SCROOBY_INVENTORY_INGAME_LEVEL );
+#endif // LOAD_LEVEL_SPECIFIC_PROJECT
+
+ // load ingame Scrooby project (into HUD heap)
+ GetLoadingManager()->AddRequest( FILEHANDLER_SCROOBY,
+ PROJECT_FILE_INGAME,
+ GMA_LEVEL_HUD,
+ SCROOBY_INVENTORY_INGAME,
+ SCROOBY_INVENTORY_INGAME );
+
+ rAssert( m_pApp );
+ m_pApp->GetResourceManager().SetSecondaryInventorySection( SCROOBY_INVENTORY_INGAME_LEVEL );
+
+ m_state = INGAME_LOADING;
+}
+
+
+//===========================================================================
+// CGuiSystem::OnReleaseInGame
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiSystem::OnReleaseInGame()
+{
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ if( m_pManagerInGame != NULL )
+ {
+ // destroy ingame manager
+ delete m_pManagerInGame;
+ m_pManagerInGame = NULL;
+ }
+
+ // unload ingame project resources
+ if( m_pProject != NULL )
+ {
+ m_pApp->UnloadProject( m_pProject );
+ m_pProject = NULL;
+ }
+
+ // as well as level-specific ingame resources
+ if( m_pLevelProject != NULL )
+ {
+ m_pApp->UnloadProject( m_pLevelProject );
+ m_pLevelProject = NULL;
+ }
+
+ // update reference to text bible
+ //
+ rAssert( m_pTextBible != NULL );
+ m_pTextBible->SetTextBible( TEXT_BIBLE_NAME );
+
+ rAssert( m_pApp );
+ m_pApp->GetResourceManager().SetSecondaryInventorySection( NULL );
+
+ HeapMgr()->PopHeap(GMA_LEVEL_HUD);
+
+ m_state = GUI_IDLE;
+}
+
+
+//===========================================================================
+// CGuiSystem::FormatTutorialTextWithLineBreaks
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiSystem::FormatTutorialTextWithLineBreaks()
+{
+#ifdef PAL
+ const int MAX_NUM_CHARS_PER_LINE = 35;
+ const P3D_UNICODE TEXT_LINE_BREAK = '\\';
+
+ for( int tutorialID = 0; tutorialID < TUTORIAL_MAX; tutorialID++ )
+ {
+ char textBibleID[ 32 ];
+ sprintf( textBibleID, "TUTORIAL_%03d", tutorialID );
+ P3D_UNICODE* tutorialText = GetTextBibleString( textBibleID );
+
+ // check for platform-specific text; if found, override default text
+ //
+ P3D_UNICODE* platformText = NULL;
+
+#ifdef RAD_GAMECUBE
+ strcat( textBibleID, "_(GC)" );
+ platformText = GetTextBibleString( textBibleID );
+#endif
+#ifdef RAD_PS2
+ strcat( textBibleID, "_(PS2)" );
+ platformText = GetTextBibleString( textBibleID );
+#endif
+#ifdef RAD_XBOX
+ strcat( textBibleID, "_(XBOX)" );
+ platformText = GetTextBibleString( textBibleID );
+#endif
+ if( platformText != NULL )
+ {
+ tutorialText = platformText;
+ }
+
+ // wrap tutorial text by inserting line breaks into text
+ //
+ int numCharsInCurrentLine = 0;
+ int lastSpaceCharIndex = -1;
+
+#ifdef RAD_DEBUG
+ const int MAX_NUM_LINES_PER_MESSAGE = 5;
+ int numLineBreaks = 0;
+#endif
+
+ int tutorialTextLength = p3d::UnicodeStrLen( tutorialText );
+ for( int i = 0; i < tutorialTextLength; i++ )
+ {
+ if( tutorialText[ i ] == TEXT_LINE_BREAK ) // line break character
+ {
+#ifdef RAD_DEBUG
+ numLineBreaks++;
+ rAssert( numLineBreaks < MAX_NUM_LINES_PER_MESSAGE );
+#endif
+ numCharsInCurrentLine = 0;
+
+ continue;
+ }
+
+ if( tutorialText[ i ] == ' ' ) // space character
+ {
+ lastSpaceCharIndex = i;
+ }
+
+ numCharsInCurrentLine++;
+
+ if( numCharsInCurrentLine > MAX_NUM_CHARS_PER_LINE )
+ {
+ rAssertMsg( lastSpaceCharIndex != -1, "We might encounter this w/ Japanese text!" );
+
+ // replace last space character w/ line break
+ //
+ tutorialText[ lastSpaceCharIndex ] = TEXT_LINE_BREAK;
+ numCharsInCurrentLine = i - lastSpaceCharIndex;
+
+#ifdef RAD_DEBUG
+ numLineBreaks++;
+ rAssertMsg( numLineBreaks < MAX_NUM_LINES_PER_MESSAGE, "Too many lines in tutorial message! Tell Tony." );
+#endif
+
+ rAssertMsg( numCharsInCurrentLine <= MAX_NUM_CHARS_PER_LINE, "We might encounter this w/ Japanese text!" );
+ }
+ }
+ }
+#endif // PAL
+}
+
+
+int CGuiSystem::GetPrimaryController() const
+{
+ return m_primaryController;
+}
+
+void CGuiSystem::SetPrimaryController(int id)
+{
+ m_primaryController = id;
+}
+
+
+#ifdef DEBUGWATCH
+
+void CGuiSystem::RegisterWatcherStuff()
+{
+ static bool s_watcherRegistered = false;
+
+ if( s_watcherRegistered )
+ {
+ // delete previously registered stuff
+ //
+ radDbgWatchDelete( &g_wGuiSimulationTimeFactor );
+ radDbgWatchDelete( &g_wGuiMessage );
+ radDbgWatchDelete( &g_wGuiMessageParam1 );
+ radDbgWatchDelete( &g_wGuiMessageParam2 );
+ radDbgWatchDelete( &(Scrooby::g_CameraNearPlane) );
+ radDbgWatchDelete( &(Scrooby::g_CameraFarPlane) );
+/*
+#ifdef RAD_PS2
+ radDbgWatchDelete( &g_ps2screenScale );
+#endif
+*/
+ radDbgWatchDelete( &g_wScroobyPageName );
+ radDbgWatchDelete( &g_wScroobyPosX );
+ radDbgWatchDelete( &g_wScroobyPosY );
+ radDbgWatchDelete( &g_wScroobyAlpha );
+ radDbgWatchDelete( &g_wScroobyTextName );
+ radDbgWatchDelete( &g_wScroobySpriteName );
+ radDbgWatchDelete( &g_wScroobyPolygonName );
+ }
+
+ // and re-register again
+ //
+ radDbgWatchAddFloat( &g_wGuiSimulationTimeFactor,
+ "GUI Simulation Time Factor",
+ GUI_WATCHER_NAMESPACE,
+ NULL,
+ NULL,
+ 0.0f,
+ 2.0f );
+
+ radDbgWatchAddInt( &g_wGuiMessage,
+ "GUI Message",
+ GUI_WATCHER_NAMESPACE,
+ (RADDEBUGWATCH_CALLBACK)SendMsgToGuiSystem );
+
+ radDbgWatchAddInt( &g_wGuiMessageParam1,
+ "GUI Message Param1",
+ GUI_WATCHER_NAMESPACE );
+
+ radDbgWatchAddInt( &g_wGuiMessageParam2,
+ "GUI Message Param2",
+ GUI_WATCHER_NAMESPACE );
+
+ radDbgWatchAddFloat( &(Scrooby::g_CameraNearPlane),
+ "Override Camera Near Plane",
+ GUI_WATCHER_NAMESPACE,
+ NULL, NULL, 0.01f, 1.0f );
+
+ radDbgWatchAddFloat( &(Scrooby::g_CameraFarPlane),
+ "Override Camera Far Plane",
+ GUI_WATCHER_NAMESPACE,
+ NULL, NULL, 10.0f, 1000.0f );
+
+ radDbgWatchAddFunction( "Toggle Next Language",
+ (RADDEBUGWATCH_CALLBACK)ToggleNextLanguage,
+ NULL,
+ GUI_WATCHER_NAMESPACE );
+/*
+#ifdef RAD_PS2
+ radDbgWatchAddFloat( &g_ps2screenScale,
+ "PS2 Screen Scale",
+ GUI_WATCHER_NAMESPACE,
+ (RADDEBUGWATCH_CALLBACK)UpdatePS2ScreenScale,
+ NULL, 0.5f, 1.5f );
+#endif
+*/
+ radDbgWatchAddString( g_wScroobyPageName,
+ sizeof( g_wScroobyPageName ),
+ "Scrooby Page",
+ WATCHER_NAMESPACE_SCROOBY,
+ (RADDEBUGWATCH_CALLBACK)SetCurrentScroobyPage );
+
+ radDbgWatchAddInt( &g_wScroobyPosX,
+ "X-Position",
+ WATCHER_NAMESPACE_SCROOBY,
+ (RADDEBUGWATCH_CALLBACK)SetScroobyDrawablePosition,
+ NULL,
+ 0,
+ (int)Scrooby::App::GetInstance()->GetScreenWidth() );
+
+ radDbgWatchAddInt( &g_wScroobyPosY,
+ "Y-Position",
+ WATCHER_NAMESPACE_SCROOBY,
+ (RADDEBUGWATCH_CALLBACK)SetScroobyDrawablePosition,
+ NULL,
+ 0,
+ (int)Scrooby::App::GetInstance()->GetScreenHeight() );
+
+ radDbgWatchAddFloat( &g_wScroobyAlpha,
+ "Alpha",
+ WATCHER_NAMESPACE_SCROOBY,
+ (RADDEBUGWATCH_CALLBACK)SetScroobyDrawableAlpha );
+
+ radDbgWatchAddString( g_wScroobyTextName,
+ sizeof( g_wScroobyTextName ),
+ "Scrooby Text",
+ WATCHER_NAMESPACE_SCROOBY,
+ (RADDEBUGWATCH_CALLBACK)SetCurrentScroobyDrawableAsText );
+
+ radDbgWatchAddString( g_wScroobySpriteName,
+ sizeof( g_wScroobySpriteName ),
+ "Scrooby Sprite",
+ WATCHER_NAMESPACE_SCROOBY,
+ (RADDEBUGWATCH_CALLBACK)SetCurrentScroobyDrawableAsSprite );
+
+ radDbgWatchAddString( g_wScroobyPolygonName,
+ sizeof( g_wScroobyPolygonName ),
+ "Scrooby Polygon",
+ WATCHER_NAMESPACE_SCROOBY,
+ (RADDEBUGWATCH_CALLBACK)SetCurrentScroobyDrawableAsPolygon );
+
+ s_watcherRegistered = true;
+}
+
+#endif // DEBUGWATCH
diff --git a/game/code/presentation/gui/guisystem.h b/game/code/presentation/gui/guisystem.h
new file mode 100644
index 0000000..c56e4bc
--- /dev/null
+++ b/game/code/presentation/gui/guisystem.h
@@ -0,0 +1,320 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiSystem
+//
+// Description: Interface for the CGuiSystem class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/09/20 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef GUISYSTEM_H
+#define GUISYSTEM_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guientity.h>
+#include <data/gamedata.h>
+#include <app.h>
+
+//===========================================================================
+// External Constants
+//===========================================================================
+
+extern unsigned int g_scroobySimulationTime;
+
+static const char* SCROOBY_INVENTORY_LANGUAGE = "ScroobyLanguage";
+static const char* SCROOBY_INVENTORY_BOOTUP = "ScroobyBootup";
+static const char* SCROOBY_INVENTORY_BACKEND = "ScroobyBackend";
+static const char* SCROOBY_INVENTORY_FRONTEND = "ScroobyFrontend";
+static const char* SCROOBY_INVENTORY_MINIGAME = "ScroobyMiniGame";
+static const char* SCROOBY_INVENTORY_INGAME = "ScroobyIngame";
+static const char* SCROOBY_INVENTORY_INGAME_LEVEL = "ScroobyIngameLevel";
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class CGuiTextBible;
+class CGuiManager;
+class CGuiManagerLanguage;
+class CGuiManagerBootUp;
+class CGuiManagerBackEnd;
+class CGuiManagerFrontEnd;
+class CGuiManagerMiniGame;
+class CGuiManagerInGame;
+class CGuiUserInputHandler;
+class CGuiScreenMultiHud;
+
+// Implement this interface to be called back when the
+// async loading of the GUI system is complete.
+//
+struct IGuiLoadingCallback
+{
+ enum eGameMode
+ {
+ GUI_LOADED_FRONT_END,
+ GUI_LOADED_IN_GAME,
+ GUI_LOADED_MINI_GAME,
+
+ NUM_GAME_MODES
+ };
+
+ virtual void OnGuiLoadComplete( eGameMode mode ) = 0;
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+class CGuiSystem : public CGuiEntity,
+ public Scrooby::LoadProjectCallback,
+ public GameDataHandler
+{
+public:
+ // Static Methods for accessing this singleton.
+ static CGuiSystem* CreateInstance();
+ static void DestroyInstance();
+ static CGuiSystem* GetInstance();
+
+ void Init();
+ void Update( unsigned int elapsedTime );
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ // Implements Scrooby::LoadProjectCallback interface.
+ //
+ virtual void OnProjectLoadComplete( Scrooby::Project* pProject );
+
+ void GotoScreen( unsigned int screenID,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0,
+ unsigned int windowOptions = 0 );
+
+ Scrooby::Project* GetCurrentScroobyProject() const { return m_pProject; }
+ void SetCurrentScroobyProject( Scrooby::Project* pProject ) { m_pProject = pProject; }
+ Scrooby::Project* GetScroobyLevelProject() const { return m_pLevelProject; }
+
+ void SwitchToCurrentProject();
+ void SwitchToLevelProject();
+ void SwitchToBackendProject();
+
+ // Registration of Client Loading Callback Routine
+ //
+ void RegisterLoadingCallback( IGuiLoadingCallback* pCallback );
+ void UnregisterLoadingCallback();
+
+ // Accessors to GUI System Managers
+ //
+ CGuiManager* GetCurrentManager() const;
+
+ inline CGuiManagerBootUp* GetBootupManager() const { return m_pManagerBootUp; }
+ inline CGuiManagerBackEnd* GetBackendManager() const { return m_pManagerBackEnd; }
+ inline CGuiManagerFrontEnd* GetFrontEndManager() const { return m_pManagerFrontEnd; }
+ inline CGuiManagerInGame* GetInGameManager() const { return m_pManagerInGame; }
+ inline CGuiManagerMiniGame* GetMiniGameManager() const { return m_pManagerMiniGame; }
+
+ // Registration of GUI User Input Handlers
+ //
+ void RegisterUserInputHandlers( int controllerIDs = ~0 );
+ void UnregisterUserInputHandlers( int controllerIDs = ~0 );
+
+ // Accessor to GUI User Input Handlers
+ //
+ CGuiUserInputHandler* GetUserInputHandler( int controllerId ) const;
+ int GetNumUserInputHandlers() const { return m_numUserInputHandlers; }
+
+ // Splash Screen
+ //
+ inline void SetSplashScreenFinished() { m_isSplashScreenFinished = true; }
+ inline bool IsSplashScreenFinished() const { return m_isSplashScreenFinished; }
+
+ // Credits Screen
+ //
+ void ShowCreditsUponReturnToFE( bool enable );
+ bool IsShowCreditsUponReturnToFE() const;
+
+ // Enabling/Disabling HUD Radar
+ //
+ void SetRadarEnabled( bool isEnabled );
+ bool IsRadarEnabled() const;
+
+ // Implements GameDataHandler
+ //
+ virtual void LoadData( const GameDataByte* dataBuffer, unsigned int numBytes );
+ virtual void SaveData( GameDataByte* dataBuffer, unsigned int numBytes );
+ virtual void ResetData();
+
+ int GetPrimaryController() const;
+ void SetPrimaryController(int id);
+
+ enum eGuiSystemState
+ {
+ GUI_UNINITIALIZED,
+ GUI_IDLE,
+
+ LANGUAGE_LOADING,
+ LANGUAGE_ACTIVE,
+
+ BOOTUP_LOADING,
+ BOOTUP_ACTIVE,
+
+ BACKEND_LOADING,
+ FRONTEND_LOADING_DURING_BOOTUP,
+
+ FRONTEND_LOADING,
+ FRONTEND_ACTIVE,
+
+ MINIGAME_LOADING,
+ MINIGAME_ACTIVE,
+
+ INGAME_LOADING,
+ INGAME_ACTIVE,
+
+ DEMO_ACTIVE,
+
+ NUM_GUI_STATES
+ };
+
+ eGuiSystemState GetCurrentState() const { return m_state; }
+
+private:
+ //---------------------------------------------------------------------
+ // Private Functions
+ //---------------------------------------------------------------------
+
+ // No public access; use singleton interface.
+ //
+ CGuiSystem();
+ virtual ~CGuiSystem();
+
+ // No copying or assignment. Declare but don't define.
+ //
+ CGuiSystem( const CGuiSystem& );
+ CGuiSystem& operator= ( const CGuiSystem& );
+
+ void OnInitBootUp();
+ void OnReleaseBootUp();
+
+ void OnInitFrontEnd();
+ void OnReleaseFrontEnd();
+
+ void OnInitMiniGame();
+ void OnReleaseMiniGame();
+
+ void OnInitInGame();
+ void OnReleaseInGame();
+
+ void FormatTutorialTextWithLineBreaks();
+
+#ifdef DEBUGWATCH
+ void RegisterWatcherStuff();
+#endif
+
+ //---------------------------------------------------------------------
+ // Private Data
+ //---------------------------------------------------------------------
+
+ // Pointer to the one and only instance of this singleton.
+ static CGuiSystem* spInstance;
+
+ eGuiSystemState m_state;
+
+ CGuiTextBible* m_pTextBible;
+
+ CGuiManagerLanguage* m_pManagerLanguage;
+ CGuiManagerBootUp* m_pManagerBootUp;
+ CGuiManagerBackEnd* m_pManagerBackEnd;
+ CGuiManagerFrontEnd* m_pManagerFrontEnd;
+ CGuiManagerMiniGame* m_pManagerMiniGame;
+ CGuiManagerInGame* m_pManagerInGame;
+
+ CGuiUserInputHandler** m_pUserInputHandlers;
+ int m_numUserInputHandlers;
+ int m_registeredUserInputHandlers;
+ int m_primaryController;
+
+ Scrooby::App* m_pApp;
+ Scrooby::Project* m_pProject;
+ Scrooby::Project* m_pLevelProject;
+ Scrooby::Project* m_pBackendProject;
+
+ IGuiLoadingCallback* m_pLoadingCallback;
+
+ bool m_isSplashScreenFinished : 1;
+ bool m_isRadarEnabled : 1;
+ bool m_isShowCreditsUponReturnToFE : 1;
+
+};
+
+//===========================================================================
+// Inline Methods
+//===========================================================================
+
+// A little syntactic sugar for getting at this singleton.
+//
+inline CGuiSystem* GetGuiSystem() { return( CGuiSystem::GetInstance() ); }
+
+inline void CGuiSystem::SwitchToCurrentProject()
+{
+ rAssert( m_pProject != NULL );
+ rAssert( m_pApp != NULL );
+ m_pApp->SetProject( m_pProject );
+}
+
+inline void CGuiSystem::SwitchToLevelProject()
+{
+ if( m_pLevelProject != NULL )
+ {
+ rAssert( m_pApp != NULL );
+ m_pApp->SetProject( m_pLevelProject );
+ }
+}
+
+inline void CGuiSystem::SwitchToBackendProject()
+{
+ rAssert( m_pBackendProject != NULL );
+ rAssert( m_pApp != NULL );
+ m_pApp->SetProject( m_pBackendProject );
+}
+
+inline void CGuiSystem::RegisterLoadingCallback( IGuiLoadingCallback* pCallback )
+{
+ m_pLoadingCallback = pCallback;
+}
+
+inline void CGuiSystem::UnregisterLoadingCallback()
+{
+ m_pLoadingCallback = NULL;
+}
+
+inline void CGuiSystem::SetRadarEnabled( bool isEnabled )
+{
+ m_isRadarEnabled = isEnabled;
+}
+
+inline bool CGuiSystem::IsRadarEnabled() const
+{
+ return m_isRadarEnabled;
+}
+
+inline void CGuiSystem::ShowCreditsUponReturnToFE( bool enable )
+{
+ m_isShowCreditsUponReturnToFE = enable;
+}
+
+inline bool CGuiSystem::IsShowCreditsUponReturnToFE() const
+{
+ return m_isShowCreditsUponReturnToFE;
+}
+
+#endif // GUISYSTEM_H
diff --git a/game/code/presentation/gui/guitextbible.cpp b/game/code/presentation/gui/guitextbible.cpp
new file mode 100644
index 0000000..d060cb9
--- /dev/null
+++ b/game/code/presentation/gui/guitextbible.cpp
@@ -0,0 +1,89 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/26 TChu Created
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+
+#include <presentation/gui/guitextbible.h>
+
+#include <app.h>
+#include <textbible.h>
+#include <raddebug.hpp>
+
+#include <sound/soundmanager.h>
+
+Scrooby::TextBible* CGuiTextBible::s_textBible = NULL;
+Scrooby::XLLanguage CGuiTextBible::s_currentLanguage = Scrooby::XL_ENGLISH;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+CGuiTextBible::CGuiTextBible()
+{
+}
+
+CGuiTextBible::~CGuiTextBible()
+{
+ s_textBible = NULL;
+}
+
+void
+CGuiTextBible::SetTextBible( const char* textBible )
+{
+ rAssert( textBible != NULL );
+ s_textBible = Scrooby::App::GetInstance()->GetTextBible( textBible );
+}
+
+P3D_UNICODE*
+CGuiTextBible::GetLocalizedText( const char* stringID )
+{
+ rAssert( stringID != NULL );
+ rAssert( s_textBible != NULL );
+
+ P3D_UNICODE* localizedText = static_cast<P3D_UNICODE*>( s_textBible->GetWChar( stringID ) );
+
+/*
+#ifndef RAD_RELEASE
+ if( localizedText == NULL )
+ {
+ char msg[ 256 ];
+ sprintf( msg, "Can't find text bible string for entry: %s!", stringID );
+ rTuneWarningMsg( false, msg );
+ }
+#endif
+*/
+
+ return localizedText;
+}
+
+void
+CGuiTextBible::SetCurrentLanguage( const Scrooby::XLLanguage language )
+{
+ Scrooby::App::GetInstance()->SetLocalizationLanguage( language );
+
+ s_currentLanguage = language;
+
+ GetSoundManager()->SetDialogueLanguage( language );
+}
+
+Scrooby::XLLanguage
+CGuiTextBible::GetCurrentLanguage()
+{
+ return s_currentLanguage;
+}
+
+bool CGuiTextBible::IsTextBibleLoaded()
+{
+ return s_textBible != NULL;
+}
+
+
diff --git a/game/code/presentation/gui/guitextbible.h b/game/code/presentation/gui/guitextbible.h
new file mode 100644
index 0000000..87a8388
--- /dev/null
+++ b/game/code/presentation/gui/guitextbible.h
@@ -0,0 +1,86 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/26 TChu Created
+//
+//===========================================================================
+
+#ifndef GUITEXTBIBLE_H
+#define GUITEXTBIBLE_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+
+#include <p3d/plat_types.hpp>
+
+// Scrooby
+//
+#include <enums.h>
+
+//===========================================================================
+// External Constants
+//===========================================================================
+
+const Scrooby::XLLanguage SRR2_LANGUAGE[] =
+{
+ Scrooby::XL_ENGLISH,
+ Scrooby::XL_FRENCH,
+ Scrooby::XL_GERMAN,
+// Scrooby::XL_ITALIAN,
+ Scrooby::XL_SPANISH,
+
+ Scrooby::XL_LAST_LANGUAGE
+};
+
+const int NUM_SRR2_LANGUAGES =
+ sizeof( SRR2_LANGUAGE ) / sizeof( SRR2_LANGUAGE[ 0 ] ) - 1;
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class TextBible;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+class CGuiTextBible
+{
+public:
+ CGuiTextBible();
+ virtual ~CGuiTextBible();
+
+ // update reference to Scrooby text bible
+ //
+ void SetTextBible( const char* textBible );
+
+ // get localized text for string ID
+ //
+ static P3D_UNICODE* GetLocalizedText( const char* stringID );
+
+ // get/set current locale language
+ //
+ static void SetCurrentLanguage( const Scrooby::XLLanguage language );
+ static Scrooby::XLLanguage GetCurrentLanguage();
+ static bool IsTextBibleLoaded();
+
+private:
+ static Scrooby::TextBible* s_textBible;
+ static Scrooby::XLLanguage s_currentLanguage;
+
+};
+
+inline P3D_UNICODE* GetTextBibleString( const char* stringID )
+{
+ return CGuiTextBible::GetLocalizedText( stringID );
+}
+
+#endif // GUITEXTBIBLE_H
diff --git a/game/code/presentation/gui/guiuserinputhandler.cpp b/game/code/presentation/gui/guiuserinputhandler.cpp
new file mode 100644
index 0000000..f53b3b6
--- /dev/null
+++ b/game/code/presentation/gui/guiuserinputhandler.cpp
@@ -0,0 +1,938 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiUserInputHandler
+//
+// Description: Implementation of the CGuiUserInputHandler class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/10/20 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/guiuserinputhandler.h>
+#include <presentation/gui/guisystem.h>
+
+#include <gameflow/gameflow.h>
+
+#include <raddebug.hpp>
+
+#include <contexts/context.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+struct ControlMap
+{
+ char* inputName;
+ GuiInput::eGuiInput inputID;
+};
+
+const ControlMap GUI_CONTROL_MAP[] =
+{
+#ifdef RAD_GAMECUBE
+ { "LeftStickX", GuiInput::XAxis },
+ { "LeftStickY", GuiInput::YAxis },
+ { "RightStickX", GuiInput::XAxisRight },
+ { "RightStickY", GuiInput::YAxisRight },
+ { "DPadLeft", GuiInput::Left },
+ { "DPadRight", GuiInput::Right },
+ { "DPadUp", GuiInput::Up },
+ { "DPadDown", GuiInput::Down },
+ { "Menu", GuiInput::Start },
+ { "A", GuiInput::Select },
+ { "B", GuiInput::Back },
+ { "X", GuiInput::AuxX },
+ { "Y", GuiInput::AuxY },
+ { "TriggerL", GuiInput::L1 },
+ { "TriggerR", GuiInput::R1 },
+#endif
+
+#ifdef RAD_PS2
+ { "LeftStickX", GuiInput::XAxis },
+ { "LeftStickY", GuiInput::YAxis },
+ { "RightStickX", GuiInput::XAxisRight },
+ { "RightStickY", GuiInput::YAxisRight },
+ { "DPadLeft", GuiInput::Left },
+ { "DPadRight", GuiInput::Right },
+ { "DPadUp", GuiInput::Up },
+ { "DPadDown", GuiInput::Down },
+ { "Start", GuiInput::Start },
+ { "X", GuiInput::Select },
+ { "Triangle", GuiInput::Back },
+ { "Square", GuiInput::AuxX },
+ { "Circle", GuiInput::AuxY },
+ { "L1", GuiInput::L1 },
+ { "R1", GuiInput::R1 },
+ { "LGA", GuiInput::AuxStart }, //Only on the GT Wheel
+ { "LGX", GuiInput::AuxSelect }, //Only on the GT Wheel
+ { "LGY", GuiInput::AuxBack }, //Only on the GT Wheel
+ { "Wheel", GuiInput::AuxXAxis }, //Only on the GT Wheel
+ { "LGR1", GuiInput::AuxUp }, //Only on the GT Wheel
+ { "LGL1", GuiInput::AuxDown }, //Only on the GT Wheel
+
+#endif
+
+#ifdef RAD_XBOX
+ { "LeftStickX", GuiInput::XAxis },
+ { "LeftStickY", GuiInput::YAxis },
+ { "RightStickX", GuiInput::XAxisRight },
+ { "RightStickY", GuiInput::YAxisRight },
+ { "DPadLeft", GuiInput::Left },
+ { "DPadRight", GuiInput::Right },
+ { "DPadUp", GuiInput::Up },
+ { "DPadDown", GuiInput::Down },
+ { "Start", GuiInput::Start },
+ { "Back", GuiInput::Back },
+ { "A", GuiInput::Select },
+ { "B", GuiInput::Back },
+ { "X", GuiInput::AuxX },
+ { "Y", GuiInput::AuxY },
+ { "LeftTrigger", GuiInput::L1 },
+ { "RightTrigger", GuiInput::R1 },
+#endif
+
+#ifdef RAD_WIN32
+ { "feMoveLeft", GuiInput::Left },
+ { "feMoveRight", GuiInput::Right },
+ { "feMoveUp", GuiInput::Up },
+ { "feMoveDown", GuiInput::Down },
+ { "feStart", GuiInput::Start },
+ { "feBack", GuiInput::Back },
+ { "feSelect", GuiInput::Select },
+ { "feFunction1", GuiInput::AuxX },
+ { "feFunction2", GuiInput::L1 },
+
+ { "P1_KBD_Start", GuiInput::P1_KBD_Start },
+ { "P1_KBD_Gas", GuiInput::P1_KBD_Select },
+ { "P1_KBD_Brake", GuiInput::P1_KBD_Back },
+ { "P1_KBD_Left", GuiInput::P1_KBD_Left },
+ { "P1_KBD_Right", GuiInput::P1_KBD_Right },
+#endif
+
+ { "", GuiInput::UNKNOWN }
+};
+
+const int NUM_GUI_CONTROL_MAPPINGS = sizeof( GUI_CONTROL_MAP ) /
+ sizeof( GUI_CONTROL_MAP[ 0 ] );
+
+// time between repeated inputs
+const int INPUT_REPEAT_PERIOD = 166; // in milliseconds
+
+// time before first repeated input
+const int INPUT_REPEAT_WAIT = INPUT_REPEAT_PERIOD; // in milliseconds
+
+const float ANALOG_BUTTON_THRESHOLD = 0.5f;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiUserInputHandler::CGuiUserInputHandler
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiUserInputHandler::CGuiUserInputHandler( void )
+: Mappable( Input::ACTIVE_ALL ),
+ m_XAxisValue( 0.0f ),
+ m_YAxisValue( 0.0f ),
+ m_XAxisDuration( 0 ),
+ m_YAxisDuration( 0 ),
+#ifdef RAD_WIN32
+ m_RightValue( 0 ),
+ m_LeftValue( 0 ),
+ m_UpValue( 0 ),
+ m_DownValue( 0 ),
+ m_RightDuration( 0 ),
+ m_LeftDuration( 0 ),
+ m_UpDuration( 0 ),
+ m_DownDuration( 0 ),
+#endif
+ m_isStartToSelectMappingEnabled( true )
+{
+ this->ResetRepeatableButtons();
+}
+
+
+//===========================================================================
+// CGuiUserInputHandler::~CGuiUserInputHandler
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiUserInputHandler::~CGuiUserInputHandler( void )
+{
+}
+
+
+//===========================================================================
+// CGuiUserInputHandler::Left
+//===========================================================================
+// Description:
+//
+// Constraints:
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+void CGuiUserInputHandler::Left( int controllerId )
+{
+ GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_LEFT, controllerId );
+}
+
+
+//===========================================================================
+// CGuiUserInputHandler::Right
+//===========================================================================
+// Description:
+//
+// Constraints:
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+void CGuiUserInputHandler::Right( int controllerId )
+{
+ GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_RIGHT, controllerId );
+}
+
+
+//===========================================================================
+// CGuiUserInputHandler::Up
+//===========================================================================
+// Description:
+//
+// Constraints:
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+void CGuiUserInputHandler::Up( int controllerId )
+{
+ GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_UP, controllerId );
+}
+
+
+//===========================================================================
+// CGuiUserInputHandler::Down
+//===========================================================================
+// Description:
+//
+// Constraints:
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+void CGuiUserInputHandler::Down( int controllerId )
+{
+ GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_DOWN, controllerId );
+}
+
+
+//===========================================================================
+// CGuiUserInputHandler::Start
+//===========================================================================
+// Description:
+//
+// Constraints:
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+void CGuiUserInputHandler::Start( int controllerId )
+{
+ GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_START, controllerId );
+}
+
+
+//===========================================================================
+// CGuiUserInputHandler::Select
+//===========================================================================
+// Description:
+//
+// Constraints:
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+void CGuiUserInputHandler::Select( int controllerId )
+{
+ GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_SELECT, controllerId );
+}
+
+
+//===========================================================================
+// CGuiUserInputHandler::Back
+//===========================================================================
+// Description:
+//
+// Constraints:
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+void CGuiUserInputHandler::Back( int controllerId )
+{
+ GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_BACK, controllerId );
+}
+
+
+//===========================================================================
+// CGuiUserInputHandler::AuxX
+//===========================================================================
+// Description:
+//
+// Constraints:
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+void CGuiUserInputHandler::AuxX( int controllerId )
+{
+ GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_AUX_X, controllerId );
+}
+
+
+//===========================================================================
+// CGuiUserInputHandler::AuxY
+//===========================================================================
+// Description:
+//
+// Constraints:
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+void CGuiUserInputHandler::AuxY( int controllerId )
+{
+ GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_AUX_Y, controllerId );
+}
+
+
+//===========================================================================
+// CGuiUserInputHandler::L1
+//===========================================================================
+// Description:
+//
+// Constraints:
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+void CGuiUserInputHandler::L1( int controllerId )
+{
+ GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_L1, controllerId );
+}
+
+
+//===========================================================================
+// CGuiUserInputHandler::R1
+//===========================================================================
+// Description:
+//
+// Constraints:
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+void CGuiUserInputHandler::R1( int controllerId )
+{
+ GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_R1, controllerId );
+}
+
+
+void CGuiUserInputHandler::OnControllerDisconnect( int id )
+{
+ GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_DISCONNECT, id );
+
+ this->ResetRepeatableButtons();
+
+ Mappable::OnControllerDisconnect( id );
+}
+
+
+void CGuiUserInputHandler::OnControllerConnect( int id )
+{
+ GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_CONNECT, id );
+
+ Mappable::OnControllerConnect( id );
+}
+
+//===========================================================================
+// CGuiUserInputHandler::OnButton
+//===========================================================================
+// Description:
+//
+// Constraints:
+//
+// Parameters:
+//
+// Return:
+//
+//===========================================================================
+
+//////////////////////////////////////////////////////////////////////////////
+// IButtonedObject declarations
+//
+void CGuiUserInputHandler::OnButton( int controllerId, int buttonId, const IButton* pButton )
+{
+ rAssert( pButton != NULL );
+
+ switch ( buttonId )
+ {
+ case GuiInput::AuxXAxis:
+ case GuiInput::XAxis:
+ {
+ if ( pButton->GetValue() > ANALOG_BUTTON_THRESHOLD && !( m_XAxisValue > ANALOG_BUTTON_THRESHOLD ) )
+ {
+ Right( controllerId );
+
+ m_XAxisDuration = -INPUT_REPEAT_WAIT;
+ }
+
+ if ( pButton->GetValue() < -ANALOG_BUTTON_THRESHOLD && !( m_XAxisValue < -ANALOG_BUTTON_THRESHOLD ) )
+ {
+ Left( controllerId );
+
+ m_XAxisDuration = -INPUT_REPEAT_WAIT;
+ }
+
+ m_XAxisValue = pButton->GetValue();
+
+ break;
+ }
+ case GuiInput::YAxis:
+ {
+ if ( pButton->GetValue() > ANALOG_BUTTON_THRESHOLD && !( m_YAxisValue > ANALOG_BUTTON_THRESHOLD ) )
+ {
+ Up( controllerId );
+
+ m_YAxisDuration = -INPUT_REPEAT_WAIT;
+ }
+
+ if ( pButton->GetValue() < -ANALOG_BUTTON_THRESHOLD && !( m_YAxisValue < -ANALOG_BUTTON_THRESHOLD ) )
+ {
+ Down( controllerId );
+
+ m_YAxisDuration = -INPUT_REPEAT_WAIT;
+ }
+
+ m_YAxisValue = pButton->GetValue();
+
+ break;
+ }
+ case GuiInput::XAxisRight:
+ case GuiInput::YAxisRight:
+ {
+ // TC: *** temporary for now ***
+ //
+ GetGuiSystem()->HandleMessage( GUI_MSG_CONTROLLER_AUX_LEFT, controllerId );
+
+ break;
+ }
+#ifdef RAD_WIN32
+ case GuiInput::Left:
+ {
+ if ( pButton->GetValue() > ANALOG_BUTTON_THRESHOLD && !( m_LeftValue > ANALOG_BUTTON_THRESHOLD ) )
+ {
+ Left( controllerId );
+
+ m_LeftDuration = -INPUT_REPEAT_WAIT;
+ }
+ m_LeftValue = pButton->GetValue();
+ break;
+ }
+ case GuiInput::Right:
+ {
+ if ( pButton->GetValue() > ANALOG_BUTTON_THRESHOLD && !( m_RightValue > ANALOG_BUTTON_THRESHOLD ) )
+ {
+ Right( controllerId );
+
+ m_RightDuration = -INPUT_REPEAT_WAIT;
+ }
+ m_RightValue = pButton->GetValue();
+ break;
+ }
+ case GuiInput::Up:
+ {
+ if ( pButton->GetValue() > ANALOG_BUTTON_THRESHOLD && !( m_UpValue > ANALOG_BUTTON_THRESHOLD ) )
+ {
+ Up( controllerId );
+
+ m_UpDuration = -INPUT_REPEAT_WAIT;
+ }
+ m_UpValue = pButton->GetValue();
+ break;
+ }
+ case GuiInput::Down:
+ {
+ if ( pButton->GetValue() > ANALOG_BUTTON_THRESHOLD && !( m_DownValue > ANALOG_BUTTON_THRESHOLD ) )
+ {
+ Down( controllerId );
+
+ m_DownDuration = -INPUT_REPEAT_WAIT;
+ }
+ m_DownValue = pButton->GetValue();
+ break;
+ }
+#endif
+ default:
+ {
+ break;
+ }
+ }
+}
+
+void CGuiUserInputHandler::OnButtonUp( int controllerId, int buttonId, const IButton* pButton )
+{
+ rAssert( buttonId >= 0 && buttonId < GuiInput::NUM_GUI_INPUTS );
+
+ if ( static_cast<unsigned int>( buttonId ) < sizeof( m_buttonDownDuration ) /
+ sizeof( m_buttonDownDuration[ 0 ] ) )
+ {
+ // reset button down duration time
+ m_buttonDownDuration[ buttonId ] = -INPUT_REPEAT_WAIT;
+ }
+}
+
+void CGuiUserInputHandler::OnButtonDown( int controllerId, int buttonId, const IButton* pButton )
+{
+ ContextEnum context = GetGameFlow()->GetCurrentContext();
+
+ switch( buttonId )
+ {
+#ifndef RAD_WIN32 // for windows we handle them in onbutton()
+ case GuiInput::Left:
+ {
+ this->Left( controllerId );
+
+ break;
+ }
+ case GuiInput::Right:
+ {
+ this->Right( controllerId );
+
+ break;
+ }
+ case GuiInput::AuxUp:
+ {
+ if ( context != CONTEXT_SUPERSPRINT_FE &&
+ context != CONTEXT_SUPERSPRINT )
+ {
+ break;
+ }
+
+ //Fall through
+ }
+ case GuiInput::Up:
+ {
+ this->Up( controllerId );
+
+ break;
+ }
+ case GuiInput::AuxDown:
+ {
+ if ( context != CONTEXT_SUPERSPRINT_FE &&
+ context != CONTEXT_SUPERSPRINT )
+ {
+ break;
+ }
+
+ //Fall through
+ }
+ case GuiInput::Down:
+ {
+ this->Down( controllerId );
+
+ break;
+ }
+#endif
+ case GuiInput::AuxStart:
+ {
+ if ( context != CONTEXT_SUPERSPRINT_FE &&
+ context != CONTEXT_SUPERSPRINT )
+ {
+ break;
+ }
+
+ //Fall through
+ }
+ case GuiInput::Start:
+ {
+ this->Start( controllerId );
+
+#ifdef RAD_XBOX
+ if( m_isStartToSelectMappingEnabled )
+ {
+ // for Xbox only, START is mapped to same functionality as SELECT
+ this->Select( controllerId );
+ }
+#endif
+
+ break;
+ }
+ case GuiInput::AuxSelect:
+ {
+ if ( context != CONTEXT_SUPERSPRINT_FE &&
+ context != CONTEXT_SUPERSPRINT )
+ {
+ break;
+ }
+
+ //Fall through
+ }
+ case GuiInput::Select:
+ {
+ this->Select( controllerId );
+
+ break;
+ }
+ case GuiInput::AuxBack:
+ {
+ if ( context != CONTEXT_SUPERSPRINT_FE &&
+ context != CONTEXT_SUPERSPRINT )
+ {
+ break;
+ }
+
+ //Fall through
+ }
+ case GuiInput::Back:
+ {
+ this->Back( controllerId );
+
+ break;
+ }
+ case GuiInput::AuxX:
+ {
+ this->AuxX( controllerId );
+
+ break;
+ }
+ case GuiInput::AuxY:
+ {
+ this->AuxY( controllerId );
+
+ break;
+ }
+ case GuiInput::L1:
+ {
+ this->L1( controllerId );
+
+ break;
+ }
+ case GuiInput::R1:
+ {
+ this->R1( controllerId );
+
+ break;
+ }
+ default:
+ {
+#ifdef RAD_WIN32
+ if ( buttonId >= GuiInput::P1_KBD_Start && buttonId <= GuiInput::P1_KBD_Right )
+ {
+ //This is a super sprint Key.
+ if ( context == CONTEXT_SUPERSPRINT_FE || context == CONTEXT_SUPERSPRINT )
+ {
+ unsigned int button = (buttonId - GuiInput::P1_KBD_Start);
+ int player = 3;
+
+ enum
+ {
+ Start,
+ Select,
+ Back,
+ Left,
+ Right
+ };
+
+ switch( button )
+ {
+ case Start:
+ this->Start( player );
+ break;
+ case Select:
+ this->Select( player );
+ break;
+ case Back:
+ this->Back( player );
+ break;
+ case Left:
+ this->Left( player );
+ break;
+ case Right:
+ this->Right( player );
+ break;
+ default:
+ break;
+ }
+ }
+ }
+#endif
+ break;
+ }
+ }
+}
+
+void CGuiUserInputHandler::LoadControllerMappings( unsigned int controllerId )
+{
+ // now set controller mappings
+ for( int i = 0; i < NUM_GUI_CONTROL_MAPPINGS; i++ )
+ {
+ this->Map( GUI_CONTROL_MAP[ i ].inputName,
+ GUI_CONTROL_MAP[ i ].inputID,
+ 0,
+ controllerId );
+ }
+}
+
+void CGuiUserInputHandler::Update( unsigned int elapsedTime, unsigned int controllerId )
+{
+ if( !this->IsActive() )
+ {
+ this->ResetRepeatableButtons();
+ }
+
+#ifndef RAD_WIN32
+ // check for repeated DPad inputs
+ //
+ for( unsigned int i = 0; i < sizeof( m_buttonDownDuration ) /
+ sizeof( m_buttonDownDuration[ 0 ] ); i++ )
+ {
+ // check if button is still down
+ if( this->IsButtonDown( i ) )
+ {
+ m_buttonDownDuration[ i ] += elapsedTime;
+
+ if( m_buttonDownDuration[ i ] > INPUT_REPEAT_PERIOD )
+ {
+ // repeat button down event
+ this->OnButtonDown( controllerId, i, NULL );
+
+ m_buttonDownDuration[ i ] = (m_buttonDownDuration[ i ] + elapsedTime ) % INPUT_REPEAT_PERIOD;
+ }
+ }
+ }
+#endif
+
+ // check for repeated Thumbstick inputs
+ //
+ if( m_XAxisValue > ANALOG_BUTTON_THRESHOLD )
+ {
+ m_XAxisDuration += elapsedTime;
+
+ if( m_XAxisDuration > INPUT_REPEAT_PERIOD )
+ {
+ // repeat right input
+ this->Right( controllerId );
+
+ m_XAxisDuration = (m_XAxisDuration + elapsedTime ) % INPUT_REPEAT_PERIOD;
+ }
+ }
+
+ if( m_XAxisValue < -ANALOG_BUTTON_THRESHOLD )
+ {
+ m_XAxisDuration += elapsedTime;
+
+ if( m_XAxisDuration > INPUT_REPEAT_PERIOD )
+ {
+ // repeat left input
+ this->Left( controllerId );
+
+ m_XAxisDuration = (m_XAxisDuration + elapsedTime ) % INPUT_REPEAT_PERIOD;
+ }
+ }
+
+ if( m_YAxisValue > ANALOG_BUTTON_THRESHOLD )
+ {
+ m_YAxisDuration += elapsedTime;
+
+ if( m_YAxisDuration > INPUT_REPEAT_PERIOD )
+ {
+ // repeat up input
+ this->Up( controllerId );
+
+ m_YAxisDuration = (m_YAxisDuration + elapsedTime ) % INPUT_REPEAT_PERIOD;
+ }
+ }
+
+ if( m_YAxisValue < -ANALOG_BUTTON_THRESHOLD )
+ {
+ m_YAxisDuration += elapsedTime;
+
+ if( m_YAxisDuration > INPUT_REPEAT_PERIOD )
+ {
+ // repeat down input
+ this->Down( controllerId );
+
+ m_YAxisDuration = (m_YAxisDuration + elapsedTime ) % INPUT_REPEAT_PERIOD;
+ }
+ }
+
+#ifdef RAD_WIN32
+ if( m_LeftValue > ANALOG_BUTTON_THRESHOLD )
+ {
+ m_LeftDuration += elapsedTime;
+
+ if( m_LeftDuration > INPUT_REPEAT_PERIOD )
+ {
+ // repeat down input
+ Left( controllerId );
+
+ m_LeftDuration = (m_LeftDuration + elapsedTime ) % INPUT_REPEAT_PERIOD;
+ }
+ }
+ if( m_RightValue > ANALOG_BUTTON_THRESHOLD )
+ {
+ m_RightDuration += elapsedTime;
+
+ if( m_RightDuration > INPUT_REPEAT_PERIOD )
+ {
+ // repeat down input
+ Right( controllerId );
+
+ m_RightDuration = (m_RightDuration + elapsedTime ) % INPUT_REPEAT_PERIOD;
+ }
+ }
+ if( m_UpValue > ANALOG_BUTTON_THRESHOLD )
+ {
+ m_UpDuration += elapsedTime;
+
+ if( m_UpDuration > INPUT_REPEAT_PERIOD )
+ {
+ // repeat down input
+ Up( controllerId );
+
+ m_UpDuration = (m_UpDuration + elapsedTime ) % INPUT_REPEAT_PERIOD;
+ }
+ }
+ if( m_DownValue > ANALOG_BUTTON_THRESHOLD )
+ {
+ m_DownDuration += elapsedTime;
+
+ if( m_DownDuration > INPUT_REPEAT_PERIOD )
+ {
+ // repeat down input
+ Down( controllerId );
+
+ m_DownDuration = (m_DownDuration + elapsedTime ) % INPUT_REPEAT_PERIOD;
+ }
+ }
+#endif
+}
+
+bool
+CGuiUserInputHandler::IsXAxisOnLeft() const
+{
+#ifdef RAD_WIN32
+ return( m_LeftValue > ANALOG_BUTTON_THRESHOLD );
+#else
+ return( m_XAxisValue < -ANALOG_BUTTON_THRESHOLD );
+#endif
+}
+
+bool
+CGuiUserInputHandler::IsXAxisOnRight() const
+{
+#ifdef RAD_WIN32
+ return( m_RightValue > ANALOG_BUTTON_THRESHOLD );
+#else
+ return( m_XAxisValue > ANALOG_BUTTON_THRESHOLD );
+#endif
+}
+
+bool
+CGuiUserInputHandler::IsYAxisOnUp() const
+{
+#ifdef RAD_WIN32
+ return( m_UpValue > ANALOG_BUTTON_THRESHOLD );
+#else
+ return( m_YAxisValue > ANALOG_BUTTON_THRESHOLD );
+#endif
+}
+
+bool
+CGuiUserInputHandler::IsYAxisOnDown() const
+{
+#ifdef RAD_WIN32
+ return( m_DownValue > ANALOG_BUTTON_THRESHOLD );
+#else
+ return( m_YAxisValue < -ANALOG_BUTTON_THRESHOLD );
+#endif
+}
+
+//===========================================================================
+// Private Member Functions
+//===========================================================================
+
+void
+CGuiUserInputHandler::ResetRepeatableButtons()
+{
+ for( unsigned int i = 0; i < sizeof( m_buttonDownDuration ) /
+ sizeof( m_buttonDownDuration[ 0 ] ); i++ )
+ {
+ m_buttonDownDuration[ i ] = -INPUT_REPEAT_WAIT;
+ }
+
+ m_XAxisValue = 0.0f;
+ m_YAxisValue = 0.0f;
+ m_XAxisDuration = -INPUT_REPEAT_WAIT;
+ m_YAxisDuration = -INPUT_REPEAT_WAIT;
+
+#ifdef RAD_WIN32
+ m_RightValue = 0;
+ m_LeftValue = 0;
+ m_UpValue = 0;
+ m_DownValue = 0;
+ m_RightDuration = 0;
+ m_LeftDuration = 0;
+ m_UpDuration = 0;
+ m_DownDuration = 0;
+#endif
+}
+
diff --git a/game/code/presentation/gui/guiuserinputhandler.h b/game/code/presentation/gui/guiuserinputhandler.h
new file mode 100644
index 0000000..af55835
--- /dev/null
+++ b/game/code/presentation/gui/guiuserinputhandler.h
@@ -0,0 +1,162 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiUserInputHandler
+//
+// Description: This class feeds the inputs received by the controller
+// system into the GUI system.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/10/20 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef GUIUSERINPUTHANDLER_H
+#define GUIUSERINPUTHANDLER_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <input/mappable.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiSystem;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+namespace GuiInput
+{
+ // Definition of control points for an abstracted player controller
+ //
+ enum eGuiInput
+ {
+ UNKNOWN = -1,
+
+ Left,
+ Right,
+ Up,
+ Down,
+
+ NUM_DPAD_INPUTS,
+
+ L1,
+ R1,
+ XAxis,
+ YAxis,
+ XAxisRight,
+ YAxisRight,
+ Start,
+ Select,
+ Back,
+ AuxX,
+ AuxY,
+
+ //These are just for the PS2 GT Wheel.
+ AuxStart,
+ AuxSelect,
+ AuxBack,
+ AuxUp,
+ AuxDown,
+ AuxXAxis,
+
+#ifdef RAD_WIN32
+ P1_KBD_Start,
+ P1_KBD_Select,
+ P1_KBD_Back,
+ P1_KBD_Left,
+ P1_KBD_Right,
+#endif
+
+ NUM_GUI_INPUTS
+ };
+};
+
+class CGuiUserInputHandler : public Mappable
+{
+public:
+
+ CGuiUserInputHandler( void );
+ virtual ~CGuiUserInputHandler( void );
+
+ void Left( int controllerId = 0 );
+ void Right( int controllerId = 0 );
+ void Up( int controllerId = 0 );
+ void Down( int controllerId = 0 );
+ void Start( int controllerId = 0 );
+ void Select( int controllerId = 0 );
+ void Back( int controllerId = 0 );
+ void AuxX( int controllerId = 0 );
+ void AuxY( int controllerId = 0 );
+ void L1( int controllerId = 0 );
+ void R1( int controllerId = 0 );
+
+ // Mappable interface declarations
+ //
+ virtual void OnButton( int controllerId, int buttonId, const IButton* pButton );
+ virtual void OnButtonUp( int controllerId, int buttonId, const IButton* pButton );
+ virtual void OnButtonDown( int controllerId, int buttonId, const IButton* pButton );
+
+ // Mappable interface declarations.
+ // Dispatch a message when controller is disconnected.
+ //
+ virtual void OnControllerDisconnect( int id );
+
+ // Mappable interface declarations.
+ // Dispatch a message when controller is connected.
+ //
+ virtual void OnControllerConnect( int id );
+
+ // Mappable interface declarations
+ //
+ virtual void LoadControllerMappings( unsigned int controllerId );
+
+ // Update repeated input states
+ void Update( unsigned int elapsedTime, unsigned int controllerId );
+
+ bool IsXAxisOnLeft() const;
+ bool IsXAxisOnRight() const;
+ bool IsYAxisOnUp() const;
+ bool IsYAxisOnDown() const;
+
+ void EnableStartToSelectMapping( bool isEnabled ) { m_isStartToSelectMappingEnabled = isEnabled; }
+
+private:
+ // Disallow object copying or assigning until we know we need it
+ //
+ CGuiUserInputHandler( const CGuiUserInputHandler& original );
+ CGuiUserInputHandler& operator=( const CGuiUserInputHandler& rhs );
+
+ void ResetRepeatableButtons();
+
+ int m_buttonDownDuration[ GuiInput::NUM_DPAD_INPUTS ];
+
+ float m_XAxisValue;
+ float m_YAxisValue;
+
+ int m_XAxisDuration;
+ int m_YAxisDuration;
+
+#ifdef RAD_WIN32
+ float m_RightValue;
+ float m_LeftValue;
+ float m_UpValue;
+ float m_DownValue;
+
+ int m_RightDuration;
+ int m_LeftDuration;
+ int m_UpDuration;
+ int m_DownDuration;
+#endif
+
+ bool m_isStartToSelectMappingEnabled : 1;
+
+};
+
+#endif // GUIUSERINPUTHANDLER_H
diff --git a/game/code/presentation/gui/guiwindow.cpp b/game/code/presentation/gui/guiwindow.cpp
new file mode 100644
index 0000000..19c2193
--- /dev/null
+++ b/game/code/presentation/gui/guiwindow.cpp
@@ -0,0 +1,241 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiWindow
+//
+// Description: Implementation of the CGuiWindow class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/09/21 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <memory/classsizetracker.h>
+#include <presentation/gui/guiwindow.h>
+#include <presentation/gui/guimanager.h>
+#include <raddebug.hpp> // Foundation
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiWindow::CGuiWindow
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiWindow::CGuiWindow
+(
+ eGuiWindowID id,
+ CGuiEntity* pParent
+)
+:
+ CGuiEntity( pParent ),
+ m_state( GUI_WINDOW_STATE_UNITIALIZED ),
+ m_ID( id ),
+ m_numTransitionsPending( 0 ),
+ m_firstTimeEntered( true )
+{
+ CLASSTRACKER_CREATE( CGuiWindow );
+}
+
+
+//===========================================================================
+// CGuiWindow::~CGuiWindow
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiWindow::~CGuiWindow()
+{
+ CLASSTRACKER_CREATE( CGuiWindow );
+}
+
+
+//===========================================================================
+// CGuiWindow::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters:
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiWindow::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ switch( message )
+ {
+ case GUI_MSG_WINDOW_ENTER:
+ {
+/*
+ // Ignore multiple enter requests.
+ //
+ if( GUI_WINDOW_STATE_UNITIALIZED != m_state )
+ {
+ break;
+ }
+*/
+ m_state = GUI_WINDOW_STATE_INTRO;
+ this->InitIntro();
+
+ break;
+ }
+
+ case GUI_MSG_WINDOW_EXIT:
+ {
+/*
+ if( GUI_WINDOW_STATE_OUTRO == m_state ||
+ GUI_WINDOW_STATE_UNITIALIZED == m_state )
+ {
+ // Ignore multiple exit requests.
+ //
+ break;
+ }
+*/
+ m_state = GUI_WINDOW_STATE_OUTRO;
+ this->InitOutro();
+
+ break;
+ }
+
+ case GUI_MSG_WINDOW_PAUSE:
+ {
+ m_prevState = m_state;
+ m_state = GUI_WINDOW_STATE_PAUSED;
+ break;
+ }
+
+ case GUI_MSG_WINDOW_RESUME:
+ {
+ m_state = m_prevState;
+ break;
+ }
+
+ case GUI_MSG_UPDATE:
+ {
+ if( GUI_WINDOW_STATE_UNITIALIZED == m_state
+ || GUI_WINDOW_STATE_PAUSED == m_state )
+ {
+ return;
+ }
+
+ switch( m_state )
+ {
+ case GUI_WINDOW_STATE_INTRO:
+ {
+ // The intro transition is complete if there are no more
+ // non-persistent sequencers running.
+ //
+ if( m_numTransitionsPending == 0 )
+ {
+ m_state = GUI_WINDOW_STATE_RUNNING;
+ this->InitRunning();
+ }
+
+ break;
+ }
+
+ case GUI_WINDOW_STATE_OUTRO:
+ {
+ // The outro transition is complete if there are no more
+ // non-persistent sequencers running.
+ //
+ if( m_numTransitionsPending == 0 )
+ {
+ // wait one more frame for last transition update to get rendered
+ //
+ m_numTransitionsPending--;
+ CleanUp();
+ }
+ else if( m_numTransitionsPending < 0 )
+ {
+ m_state = GUI_WINDOW_STATE_UNITIALIZED;
+ m_firstTimeEntered = false;
+
+ m_pParent->HandleMessage( GUI_MSG_WINDOW_FINISHED );
+ }
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+}
+
+//===========================================================================
+// CGuiWindow::CleanUp
+//===========================================================================
+// Description: Called after the last outro transition is done
+//
+// Constraints: None.
+//
+// Parameters:
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiWindow::CleanUp()
+{
+ //do nothing
+}
+
+//===========================================================================
+// CGuiWindow::ForceClearTransitions
+//===========================================================================
+// Description: Forces all transitions to think they are done
+//
+// Constraints: None.
+//
+// Parameters:
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiWindow::ForceClearTransitions()
+{
+ m_numTransitionsPending = 0;
+} \ No newline at end of file
diff --git a/game/code/presentation/gui/guiwindow.h b/game/code/presentation/gui/guiwindow.h
new file mode 100644
index 0000000..c7d3aa1
--- /dev/null
+++ b/game/code/presentation/gui/guiwindow.h
@@ -0,0 +1,188 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiWindow
+//
+// Description: Interface for the CGuiWindow class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/09/20 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef GUIWINDOW_H
+#define GUIWINDOW_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guientity.h>
+#include <presentation/gui/guimenu.h>
+#ifdef RAD_WIN32
+#include <input/FEMouse.h>
+#endif
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiManager;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiWindow : public CGuiEntity
+{
+ public:
+ enum eGuiWindowID
+ {
+ GUI_WINDOW_ID_UNDEFINED = -1,
+
+ // generic screens
+ //
+ GUI_SCREEN_ID_GENERIC_MESSAGE,
+ GUI_SCREEN_ID_GENERIC_PROMPT,
+ GUI_SCREEN_ID_ERROR_PROMPT,
+
+ // bootup and backend screens
+ //
+ GUI_SCREEN_ID_BOOTUP_LOAD,
+ GUI_SCREEN_ID_LICENSE,
+ GUI_SCREEN_ID_LANGUAGE,
+ GUI_SCREEN_ID_LOADING,
+ GUI_SCREEN_ID_LOADING_FE,
+ GUI_SCREEN_ID_DEMO,
+
+ GUI_SCREEN_ID_MEMORY_CARD,
+ GUI_SCREEN_ID_MEMORY_CARD_CHECK,
+ GUI_SCREEN_ID_AUTO_LOAD,
+
+ // front-end screens
+ //
+ GUI_SCREEN_ID_SPLASH,
+ GUI_SCREEN_ID_INTRO_TRANSITION,
+ GUI_SCREEN_ID_MAIN_MENU,
+ GUI_SCREEN_ID_LOAD_GAME,
+ GUI_SCREEN_ID_SCRAP_BOOK,
+ GUI_SCREEN_ID_SCRAP_BOOK_CONTENTS,
+ GUI_SCREEN_ID_SCRAP_BOOK_STATS,
+ GUI_SCREEN_ID_CARD_GALLERY,
+ GUI_SCREEN_ID_MISSION_GALLERY,
+ GUI_SCREEN_ID_SKIN_GALLERY,
+ GUI_SCREEN_ID_VEHICLE_GALLERY,
+// GUI_SCREEN_ID_MULTIPLAYER_SETUP,
+// GUI_SCREEN_ID_MULTIPLAYER_CHOOSE_CHARACTER,
+ GUI_SCREEN_ID_OPTIONS,
+ GUI_SCREEN_ID_CONTROLLER,
+ GUI_SCREEN_ID_SOUND,
+ GUI_SCREEN_ID_VIEW_MOVIES,
+ GUI_SCREEN_ID_VIEW_CREDITS,
+#ifdef RAD_WIN32
+ GUI_SCREEN_ID_DISPLAY,
+#endif
+ GUI_SCREEN_ID_PLAY_MOVIE,
+ GUI_SCREEN_ID_PLAY_MOVIE_DEMO,
+ GUI_SCREEN_ID_PLAY_MOVIE_INTRO,
+ GUI_SCREEN_ID_PLAY_MOVIE_NEW_GAME,
+
+ // in-game screens
+ //
+ GUI_SCREEN_ID_HUD,
+ GUI_SCREEN_ID_MULTI_HUD,
+ GUI_SCREEN_ID_PAUSE_SUNDAY,
+ GUI_SCREEN_ID_PAUSE_MISSION,
+ GUI_SCREEN_ID_MISSION_SELECT,
+ GUI_SCREEN_ID_SETTINGS,
+ GUI_SCREEN_ID_LEVEL_STATS,
+ GUI_SCREEN_ID_VIEW_CARDS,
+ GUI_SCREEN_ID_SAVE_GAME,
+ GUI_SCREEN_ID_MISSION_LOAD,
+ GUI_SCREEN_ID_MISSION_OVER,
+ GUI_SCREEN_ID_MISSION_SUCCESS,
+ GUI_SCREEN_ID_LETTER_BOX,
+ GUI_SCREEN_ID_PHONE_BOOTH,
+ GUI_SCREEN_ID_PURCHASE_REWARDS,
+ GUI_SCREEN_ID_IRIS_WIPE,
+ GUI_SCREEN_ID_LEVEL_END,
+ GUI_SCREEN_ID_TUTORIAL,
+
+ // mini-game screens
+ //
+ GUI_SCREEN_ID_MINI_MENU,
+ GUI_SCREEN_ID_MINI_HUD,
+ GUI_SCREEN_ID_MINI_PAUSE,
+ GUI_SCREEN_ID_MINI_SUMMARY,
+
+ NUM_GUI_WINDOW_IDS
+ };
+
+ CGuiWindow( eGuiWindowID id, CGuiEntity* pParent );
+ virtual ~CGuiWindow();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return NULL; }
+ eGuiWindowID GetWindowID( void ) const { return( m_ID ); };
+ void ForceClearTransitions();
+
+ bool IsRunning(void) {return m_state == GUI_WINDOW_STATE_RUNNING;}
+
+#ifdef RAD_WIN32
+ virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y )
+ {
+ return HOTSPOT_NONE;
+ }
+#endif
+ protected:
+
+ //---------------------------------------------------------------------
+ // Protected Functions
+ //---------------------------------------------------------------------
+
+ virtual void InitIntro() = 0;
+ virtual void InitRunning() = 0;
+ virtual void InitOutro() = 0;
+ virtual void CleanUp();
+
+ enum eGuiWindowState
+ {
+ GUI_WINDOW_STATE_UNITIALIZED,
+ GUI_WINDOW_STATE_INTRO,
+ GUI_WINDOW_STATE_RUNNING,
+ GUI_WINDOW_STATE_PAUSED,
+ GUI_WINDOW_STATE_IDLE,
+ GUI_WINDOW_STATE_OUTRO,
+
+ GUI_WINDOW_STATE_DISABLED,
+
+ GUI_WINDOW_STATE_COUNT
+ };
+
+ eGuiWindowState m_state;
+ eGuiWindowState m_prevState;
+
+ eGuiWindowID m_ID;
+
+ int m_numTransitionsPending;
+
+ bool m_firstTimeEntered;
+
+ private:
+
+ //---------------------------------------------------------------------
+ // Private Functions
+ //---------------------------------------------------------------------
+
+ // No copying or assignement. Declare but don't define.
+ //
+ CGuiWindow( const CGuiWindow& );
+ CGuiWindow& operator= ( const CGuiWindow& );
+
+};
+
+#endif // GUIWINDOW_H
diff --git a/game/code/presentation/gui/ingame/allingame.cpp b/game/code/presentation/gui/ingame/allingame.cpp
new file mode 100644
index 0000000..ee04a6f
--- /dev/null
+++ b/game/code/presentation/gui/ingame/allingame.cpp
@@ -0,0 +1,27 @@
+#include <presentation/gui/ingame/guimanageringame.cpp>
+#include <presentation/gui/ingame/guiscreenhastransitions.cpp>
+#include <presentation/gui/ingame/guiscreenhud.cpp>
+#include <presentation/gui/ingame/guiscreeniriswipe.cpp>
+#include <presentation/gui/ingame/guiscreenlevelstats.cpp>
+#include <presentation/gui/ingame/guiscreenlevelend.cpp>
+#include <presentation/gui/ingame/guiscreenletterbox.cpp>
+#include <presentation/gui/ingame/guiscreenmissionbase.cpp>
+#include <presentation/gui/ingame/guiscreenmissionload.cpp>
+#include <presentation/gui/ingame/guiscreenmissionover.cpp>
+#include <presentation/gui/ingame/guiscreenmissionsuccess.cpp>
+#include <presentation/gui/ingame/guiscreenmultihud.cpp>
+#include <presentation/gui/ingame/guiscreenpause.cpp>
+#include <presentation/gui/ingame/guiscreenpausemission.cpp>
+#include <presentation/gui/ingame/guiscreenpauseoptions.cpp>
+#include <presentation/gui/ingame/guiscreenpausecontroller.cpp>
+#include <presentation/gui/ingame/guiscreenpausesound.cpp>
+#include <presentation/gui/ingame/guiscreenpausesettings.cpp>
+#include <presentation/gui/ingame/guiscreenpausesunday.cpp>
+#include <presentation/gui/ingame/guiscreenrewards.cpp>
+#include <presentation/gui/ingame/guiscreenphonebooth.cpp>
+#include <presentation/gui/ingame/guiscreenpurchaserewards.cpp>
+#include <presentation/gui/ingame/guiscreenmissionselect.cpp>
+#include <presentation/gui/ingame/guiscreensavegame.cpp>
+#include <presentation/gui/ingame/guiscreenviewcards.cpp>
+#include <presentation/gui/ingame/guiscreentutorial.cpp>
+#include <presentation/gui/ingame/guiscreencreditspostfmv.cpp>
diff --git a/game/code/presentation/gui/ingame/guihudtextbox.h b/game/code/presentation/gui/ingame/guihudtextbox.h
new file mode 100644
index 0000000..4645818
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guihudtextbox.h
@@ -0,0 +1,41 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/07/27 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUIHUDTEXTBOX_H
+#define GUIHUDTEXTBOX_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+
+//===========================================================================
+// External Constants
+//===========================================================================
+
+const float MESSAGE_TEXT_SCALE = 0.8f;
+const float MESSGAE_TEXT_HORIZONTAL_STRETCH = 1.1f;
+
+#ifdef RAD_WIN32
+const float MESSAGE_BOX_CORRECTION_SCALE = 1.0f;
+const float MESSAGE_BOX_HORIZONTAL_STRETCH = 1.1f;
+#else
+const float MESSAGE_BOX_CORRECTION_SCALE = 2.0f;
+const float MESSAGE_BOX_HORIZONTAL_STRETCH = 1.1f;
+#endif
+
+#ifdef PAL
+ const int MESSAGE_TEXT_VERTICAL_TRANSLATION = +10;
+ const float MESSAGE_BOX_VERTICAL_STRETCH = 1.2f;
+#else
+ const int MESSAGE_TEXT_VERTICAL_TRANSLATION = 0;
+ const float MESSAGE_BOX_VERTICAL_STRETCH = 1.0f;
+#endif // PAL
+
+#endif // GUIHUDTEXTBOX_H
diff --git a/game/code/presentation/gui/ingame/guimanageringame.cpp b/game/code/presentation/gui/ingame/guimanageringame.cpp
new file mode 100644
index 0000000..0a32ae3
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guimanageringame.cpp
@@ -0,0 +1,1646 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiManagerInGame
+//
+// Description: Implementation of the CGuiManagerInGame class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/09/21 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guimanageringame.h>
+#include <presentation/gui/guiwindow.h> // for window IDs
+#include <presentation/gui/guisystem.h>
+
+#include <presentation/gui/guiscreenmessage.h>
+#include <presentation/gui/guiscreenprompt.h>
+#include <presentation/gui/guiscreenmemorycard.h>
+
+#include <presentation/gui/ingame/guiscreenhud.h>
+#include <presentation/gui/ingame/guiscreenmultihud.h>
+#include <presentation/gui/ingame/guiscreenpausesunday.h>
+#include <presentation/gui/ingame/guiscreenpausemission.h>
+#include <presentation/gui/ingame/guiscreenmissionselect.h>
+#include <presentation/gui/ingame/guiscreenhudmap.h>
+#include <presentation/gui/ingame/guiscreenpauseoptions.h>
+#ifdef RAD_WIN32
+#include <presentation/gui/ingame/guiscreenpausedisplay.h>
+#endif
+#include <presentation/gui/ingame/guiscreenpausecontroller.h>
+#include <presentation/gui/ingame/guiscreenpausesound.h>
+#include <presentation/gui/ingame/guiscreenpausesettings.h>
+#include <presentation/gui/ingame/guiscreenmissionload.h>
+#include <presentation/gui/ingame/guiscreenmissionover.h>
+#include <presentation/gui/ingame/guiscreenmissionsuccess.h>
+#include <presentation/gui/ingame/guiscreenlevelstats.h>
+#include <presentation/gui/ingame/guiscreenlevelend.h>
+#include <presentation/gui/ingame/guiscreenviewcards.h>
+#include <presentation/gui/ingame/guiscreenletterbox.h>
+#include <presentation/gui/ingame/guiscreeniriswipe.h>
+#include <presentation/gui/ingame/guiscreenphonebooth.h>
+#include <presentation/gui/ingame/guiscreenpurchaserewards.h>
+#include <presentation/gui/ingame/guiscreensavegame.h>
+#include <presentation/gui/ingame/guiscreentutorial.h>
+#include <presentation/gui/ingame/guiscreencreditspostfmv.h>
+#include <presentation/gui/backend/guimanagerbackend.h>
+#include <presentation/gui/backend/guiscreenloadingfe.h>
+#include <presentation/gui/utility/hudmap.h>
+
+#include <contexts/context.h>
+#include <contexts/pausecontext.h>
+#include <contexts/gameplay/gameplaycontext.h>
+#include <data/memcard/memorycardmanager.h>
+#include <events/eventmanager.h>
+#include <gameflow/gameflow.h>
+#include <input/inputmanager.h>
+#include <interiors/interiormanager.h>
+#include <main/commandlineoptions.h>
+#include <memory/srrmemory.h>
+#include <mission/missionmanager.h>
+#include <mission/objectives/missionobjective.h>
+#include <mission/gameplaymanager.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <presentation/presentation.h>
+#include <render/rendermanager/rendermanager.h>
+#include <render/rendermanager/renderlayer.h>
+#include <sound/soundmanager.h>
+#include <meta/eventlocator.h>
+
+#include <p3d/fileftt.hpp>
+#include <p3d/utility.hpp>
+#include <p3d/view.hpp>
+
+#include <main/platform.h>
+#include <main/game.h>
+
+#include <raddebug.hpp>
+#include <raddebugwatch.hpp>
+
+#include <layer.h>
+#include <page.h>
+#include <screen.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const unsigned int MINIMUM_DYNA_LOAD_TIME = 250; // in msec
+
+#ifdef DEBUGWATCH
+ static const char* WATCHER_NAMESPACE = "GUI System - Ingame";
+ bool g_wReversePauseMenus;
+#endif
+
+const char* INGAME_PROJECT_FILES[] =
+{
+ "art\\frontend\\scrooby\\ingame.p3d",
+ "art\\frontend\\scrooby\\pause.p3d",
+ "art\\frontend\\scrooby\\rewards.p3d",
+
+ "" // dummy terminator
+};
+
+CGuiScreenHud* CGuiManagerInGame::s_currentHUD = NULL;
+bool cGuiManagerInGameActive = false;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiManagerInGame::CGuiManagerInGame
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiManagerInGame::CGuiManagerInGame
+(
+ Scrooby::Project* pProject,
+ CGuiEntity* pParent
+)
+: CGuiManager( pProject, pParent ),
+ m_nextLevelIndex( -1 ),
+ m_nextMissionIndex( -1 ),
+ m_isLoadingNewMission( false ),
+ m_quitAndReload( false ),
+ m_controllerPromptShown( false ),
+ m_enteringPauseMenu( false ),
+ m_exitingPauseMenu( false ),
+ m_onHudEnterCommand( ON_HUD_ENTER_NO_COMMAND ),
+ m_levelScreen( NULL ),
+ m_levelLayer( NULL ),
+ m_elapsedDynaLoadTime( 0 ),
+ m_pRewardsProject( NULL ),
+ m_unloadMemcardInfoWhenLoaded( false ),
+ m_promptSaveBeforeQuit( true ),
+ m_quitAfterSave( false ),
+#ifdef RAD_WIN32
+ m_quitToSystemAfterSave(false),
+#endif
+ m_isControllerReconnected( false ),
+ m_RecieveIrisClosed( "Recieve Iris Closed" ),
+ m_resumeGameScreenID( CGuiWindow::GUI_WINDOW_ID_UNDEFINED )
+{
+ //
+ // Set Up Transitions
+ //
+ m_RecieveIrisClosed.SetEvent( EVENT_GUI_IRIS_WIPE_CLOSED );
+
+ m_RestartMissionTransition.SetNextTransition( m_RecieveIrisClosed );
+ m_RecieveIrisClosed. SetNextTransition( m_RestartMission );
+ m_RestartMission. SetNextTransition( NULL );
+
+ m_AbortMissionTransition. SetNextTransition( m_AbortMission );
+ m_AbortMission. SetNextTransition( NULL );
+
+ cGuiManagerInGameActive = true;
+ GetEventManager()->AddListener( this, EVENT_CONVERSATION_INIT );
+ GetEventManager()->AddListener( this, EVENT_CONVERSATION_DONE_AND_FINISHED );
+ GetEventManager()->AddListener( this, EVENT_ENTER_INTERIOR_TRANSITION_START );
+ GetEventManager()->AddListener( this, EVENT_ENTER_INTERIOR_TRANSITION_END );
+ GetEventManager()->AddListener( this, EVENT_EXIT_INTERIOR_START );
+ GetEventManager()->AddListener( this, EVENT_EXIT_INTERIOR_END );
+ GetEventManager()->AddListener( this, (EventEnum)(EVENT_LOCATOR + LocatorEvent::DEATH) );
+
+ Scrooby::Project* pLevelProject = GetGuiSystem()->GetScroobyLevelProject();
+ if( pLevelProject != NULL )
+ {
+ m_levelScreen = pLevelProject->GetCurrentScreen();
+ rAssert( m_levelScreen );
+
+ // get layer
+ //
+ Scrooby::Page* pPage = m_levelScreen->GetPage( "PauseBgd" );
+ rAssert( pPage );
+ m_levelLayer = pPage->GetLayerByIndex( 0 );
+ rAssert( m_levelLayer );
+ m_levelLayer->SetAlpha( 0.0f );
+ }
+
+#ifdef DEBUGWATCH
+ radDbgWatchAddBoolean( &g_wReversePauseMenus,
+ "Reverse Pause Menus",
+ WATCHER_NAMESPACE );
+#endif
+}
+
+
+//===========================================================================
+// CGuiManagerInGame::~CGuiManagerInGame
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiManagerInGame::~CGuiManagerInGame()
+{
+ cGuiManagerInGameActive = false;
+ GetEventManager()->RemoveAll( this );
+
+#ifdef DEBUGWATCH
+ radDbgWatchDelete( &g_wReversePauseMenus );
+#endif
+ s_currentHUD = NULL;
+}
+
+
+//===========================================================================
+// CGuiManagerInGame::Popluate
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiManagerInGame::Populate()
+{
+MEMTRACK_PUSH_GROUP( "CGUIManagerInGame" );
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ Scrooby::Screen* pScroobyScreen = NULL;
+ CGuiScreen* pScreen = NULL;
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Message" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMessage( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_GENERIC_MESSAGE, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Prompt" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPrompt( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "ErrorPrompt" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPrompt( pScroobyScreen, this,
+ CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT );
+
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_ERROR_PROMPT, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Hud" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenHud( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_HUD, pScreen );
+
+ // store current HUD reference
+ //
+ s_currentHUD = dynamic_cast<CGuiScreenHud*>( pScreen );
+ rAssert( s_currentHUD != NULL );
+ }
+/*
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MultiHud" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMultiHud( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MULTI_HUD, pScreen );
+ }
+*/
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MissionLoad" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMissionLoad( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MISSION_LOAD, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MissionOver" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMissionOver( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MISSION_OVER, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MissionLoad" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMissionSuccess( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MISSION_SUCCESS, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "LevelStats" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenLevelStats( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LEVEL_STATS, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "LevelEnd" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenLevelEnd( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LEVEL_END, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "PauseViewCards" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenViewCards( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_VIEW_CARDS, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "LetterBox" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenLetterBox( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_LETTER_BOX, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "IrisWipe" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenIrisWipe( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_IRIS_WIPE, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "PhoneBooth" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPhoneBooth( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PHONE_BOOTH, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "PurchaseRewards" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPurchaseRewards( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PURCHASE_REWARDS, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "PauseSunday" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPauseSunday( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PAUSE_SUNDAY, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "PauseMission" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPauseMission( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_PAUSE_MISSION, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "PauseOptions" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPauseOptions( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_OPTIONS, pScreen );
+ }
+#ifdef RAD_WIN32
+ pScroobyScreen = m_pScroobyProject->GetScreen( "PauseDisplay" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPauseDisplay( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_DISPLAY, pScreen );
+ }
+#endif
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "PauseController" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPauseController( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_CONTROLLER, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "PauseSound" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPauseSound( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SOUND, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "PauseSettings" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenPauseSettings( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SETTINGS, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MissionSelect" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMissionSelect( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MISSION_SELECT, pScreen );
+ }
+/*
+ pScroobyScreen = m_pScroobyProject->GetScreen( "ViewMap" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenHudMap( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_HUD_MAP, pScreen );
+ }
+*/
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MemoryCard" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenMemoryCard( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MEMORY_CARD, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "SaveGame" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenSaveGame( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_SAVE_GAME, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Tutorial" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenTutorial( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_TUTORIAL, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "CreditsPostFMV" );
+ if( pScroobyScreen != NULL )
+ {
+ pScreen = new CGuiScreenCreditsPostFMV( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_VIEW_CREDITS, pScreen );
+ }
+
+ // hide HUD if specified in commandline options
+ //
+ if( CommandLineOptions::Get( CLO_NO_HUD ) )
+ {
+ if( s_currentHUD != NULL )
+ {
+ s_currentHUD->SetVisible( false );
+ }
+ }
+
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+MEMTRACK_POP_GROUP("CGUIManagerInGame");
+}
+
+void
+CGuiManagerInGame::Start( CGuiWindow::eGuiWindowID initialWindow )
+{
+ rAssert( GUI_FE_UNINITIALIZED == m_state || m_isLoadingNewMission );
+
+ m_nextScreen = initialWindow != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ?
+ initialWindow :
+ CGuiWindow::GUI_SCREEN_ID_HUD;
+
+ m_state = GUI_FE_CHANGING_SCREENS; // must be set before calling GotoScreen()
+
+ CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) );
+ rAssert( nextScreen != NULL );
+ m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this );
+}
+
+//===========================================================================
+// CGuiManagerInGame::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiManagerInGame::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_FE_DYNAMIC_LOADING )
+ {
+ rAssertMsg( false, "Dynamic loading of pause menu and HUD is no longer implemented!" );
+
+ return;
+ }
+
+ if( m_isLoadingNewMission )
+ {
+ if( message == GUI_MSG_UPDATE )
+ {
+ this->UpdateDuringMissionLoading( param1 );
+ }
+ else if( message == GUI_MSG_RESUME_INGAME )
+ {
+ this->OnNewMissionLoadEnd();
+ }
+
+ CGuiManager::HandleMessage( message, param1, param2 );
+
+ // and ignore all other messages
+ //
+ return;
+ }
+
+ if( m_state == GUI_FE_TERMINATED )
+ {
+ if( message == GUI_MSG_UPDATE )
+ {
+ this->UpdateWhileLoadingNotDone( param1 );
+ }
+
+ // and ignore all other messages
+ //
+ return;
+ }
+
+#ifdef RAD_DEMO
+ if( this->IsControllerMessage( message ) )
+ {
+ GetGameplayManager()->ResetIdleTime();
+ }
+#endif
+
+ switch( message )
+ {
+ case GUI_MSG_PROMPT_START_RESPONSE:
+ {
+ HandleMessage( GUI_MSG_UNPAUSE_INGAME );
+ break;
+ }
+ case GUI_MSG_QUIT_INGAME_FOR_RELOAD:
+ {
+ m_quitAndReload = true;
+ m_nextLevelIndex = static_cast<int>( param1 );
+ m_nextMissionIndex = static_cast<int>( param2 );
+
+ if( GetGameplayManager()->GetLevelComplete() )
+ {
+ if( GetGameplayManager()->GetGameComplete() )
+ {
+ // wrap back to level 1, mission 1 (not the tutorial mission)
+ //
+ GetCharacterSheetManager()->SetCurrentMission( RenderEnums::L1, RenderEnums::M2 ); // M2 = mission 1
+
+ // tell GUI system to show credits upon returning to FE
+ //
+// GetGuiSystem()->ShowCreditsUponReturnToFE( true );
+
+ m_quitAndReload = false;
+ }
+ else
+ {
+ GetCharacterSheetManager()->SetCurrentMission( static_cast<RenderEnums::LevelEnum>( m_nextLevelIndex ),
+ static_cast<RenderEnums::MissionEnum>( m_nextMissionIndex ) );
+ }
+
+#ifdef RAD_DEMO
+ m_promptSaveBeforeQuit = false;
+ m_quitAndReload = false;
+#else
+ this->DisplayPrompt( PROMPT_CONFIRM_SAVE_BEFORE_QUIT,
+ this,
+ PROMPT_TYPE_YES_NO,
+ false );
+
+ break;
+#endif // RAD_DEMO
+ }
+ else
+ {
+ // don't prompt to save unless we're advancing to a new level
+ //
+ m_promptSaveBeforeQuit = false;
+ }
+
+ // follow-thru ...
+ //
+ }
+
+ case GUI_MSG_QUIT_INGAME:
+ {
+ if( GUI_FE_SCREEN_RUNNING == m_state )
+ {
+#ifndef RAD_DEMO
+ if( m_promptSaveBeforeQuit && GetGameplayManager()->IsSundayDrive() )
+ {
+ this->DisplayPrompt( PROMPT_CONFIRM_SAVE_BEFORE_QUIT,
+ this,
+ PROMPT_TYPE_YES_NO,
+ false );
+ }
+ else
+#endif
+ {
+ m_state = GUI_FE_SHUTTING_DOWN;
+
+ // if paused in sunday drive mode, unload memory card info
+ //
+ if( GetGameplayManager()->IsSundayDrive() )
+ {
+ if( GetMemoryCardManager()->IsMemcardInfoLoaded() )
+ {
+ // unload it now
+ //
+ GetMemoryCardManager()->UnloadMemcardInfo();
+ }
+ else
+ {
+ // wait until loading is complete, then unload it
+ //
+ m_unloadMemcardInfoWhenLoaded = true;
+ }
+ }
+/*
+ CGuiScreenPrompt* promptScreen = static_cast<CGuiScreenPrompt*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT ) );
+ rAssert( promptScreen != NULL );
+ promptScreen->RestoreScreenCover();
+*/
+ // Tell the current screen to shut down.
+ //
+ this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT );
+ }
+ }
+
+ break;
+ }
+#ifdef RAD_WIN32
+ case GUI_MSG_QUIT_TO_SYSTEM:
+ {
+ if( GUI_FE_SCREEN_RUNNING == m_state )
+ {
+ if( m_promptSaveBeforeQuit && GetGameplayManager()->IsSundayDrive() )
+ {
+ this->DisplayPrompt( PROMPT_CONFIRM_SAVE_BEFORE_QUITTOSYSTEM,
+ this,
+ PROMPT_TYPE_YES_NO,
+ false );
+ }
+ else
+ {
+ m_state = GUI_FE_SHUTTING_DOWN;
+
+ // if paused in sunday drive mode, unload memory card info
+ //
+ if( GetGameplayManager()->IsSundayDrive() )
+ {
+ if( GetMemoryCardManager()->IsMemcardInfoLoaded() )
+ {
+ // unload it now
+ //
+ GetMemoryCardManager()->UnloadMemcardInfo();
+ }
+ else
+ {
+ // wait until loading is complete, then unload it
+ //
+ m_unloadMemcardInfoWhenLoaded = true;
+ }
+ }
+ /*
+ CGuiScreenPrompt* promptScreen = static_cast<CGuiScreenPrompt*>( this->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT ) );
+ rAssert( promptScreen != NULL );
+ promptScreen->RestoreScreenCover();
+ */
+ // Tell the current screen to shut down.
+ //
+ this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT );
+
+ // let's begin the quit procedure
+ //
+ GetGameFlow()->SetContext( CONTEXT_EXIT );
+ }
+ }
+
+ break;
+ }
+#endif
+ case GUI_MSG_MENU_PROMPT_RESPONSE:
+ {
+#ifdef RAD_WIN32
+ if( param1 == PROMPT_CONFIRM_SAVE_BEFORE_QUITTOSYSTEM )
+ {
+ if( param2 == CGuiMenuPrompt::RESPONSE_YES )
+ {
+ this->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_SAVE_GAME );
+
+ m_quitToSystemAfterSave = true;
+ }
+ else
+ {
+ rAssert( param2 == CGuiMenuPrompt::RESPONSE_NO );
+
+ m_promptSaveBeforeQuit = false;
+
+ this->HandleMessage( GUI_MSG_QUIT_TO_SYSTEM );
+ }
+
+ }
+#endif
+ if( param1 == PROMPT_CONFIRM_SAVE_BEFORE_QUIT )
+ {
+ if( param2 == CGuiMenuPrompt::RESPONSE_YES )
+ {
+#ifdef RAD_XBOX
+ // Xbox TCR Requirement: always prompt user to select memory
+ // device before loading/saving
+ //
+ CGuiScreenLoadSave::s_forceGotoMemoryCardScreen = true;
+#endif
+// this->PushScreenHistory( GetGameplayManager()->IsSundayDrive() ?
+// CGuiWindow::GUI_SCREEN_ID_PAUSE_SUNDAY :
+// CGuiWindow::GUI_SCREEN_ID_PAUSE_MISSION );
+
+ this->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_SAVE_GAME );
+
+ m_quitAfterSave = true;
+ }
+ else
+ {
+ rAssert( param2 == CGuiMenuPrompt::RESPONSE_NO );
+
+ m_promptSaveBeforeQuit = false;
+
+ this->HandleMessage( GUI_MSG_QUIT_INGAME );
+ }
+ }
+
+ break;
+ }
+ case GUI_MSG_PAUSE_INGAME:
+ {
+ if( !this->IsPausingAllowed() )
+ {
+ rTuneWarningMsg( false, "*** Pause request ingored! ***" );
+ break;
+ }
+
+ // switch to pause context
+ //
+ GetGameFlow()->SetContext( CONTEXT_PAUSE );
+
+ bool inSundayDriveMode = GetGameplayManager()->IsSundayDrive();
+#ifdef DEBUGWATCH
+ if( g_wReversePauseMenus )
+ {
+ inSundayDriveMode = !inSundayDriveMode;
+ }
+#endif
+ CGuiWindow::eGuiWindowID pauseWindow = inSundayDriveMode ?
+ CGuiWindow::GUI_SCREEN_ID_PAUSE_SUNDAY :
+ CGuiWindow::GUI_SCREEN_ID_PAUSE_MISSION;
+
+ // remember current screen before going to pause menu
+ //
+ m_resumeGameScreenID = m_currentScreen;
+
+ CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN,
+ pauseWindow,
+ CLEAR_WINDOW_HISTORY );
+
+ // if pausing in sunday drive mode, load memory card info
+ // for saving games
+ //
+ if( GetGameplayManager()->IsSundayDrive() )
+ {
+ m_unloadMemcardInfoWhenLoaded = false;
+ GetMemoryCardManager()->LoadMemcardInfo( this );
+ }
+
+ GetSoundManager()->OnPauseStart();
+
+ m_enteringPauseMenu = true;
+ GetGameplayContext()->PauseAllButPresentation( true );
+
+ m_promptSaveBeforeQuit = true;
+
+ break;
+ }
+ case GUI_MSG_UNPAUSE_INGAME:
+ {
+ if( GetGameplayManager()->GetLevelComplete() || GetGameplayManager()->GetGameComplete() )
+ {
+ // can't un-pause the game if either level or game is just completed (i.e. just
+ // finished the last mission of the level)
+ //
+ break;
+ }
+
+ GetSoundManager()->OnPauseEnd();
+
+ // if paused in sunday drive mode, unload memory card info
+ //
+ if( GetGameplayManager()->IsSundayDrive() )
+ {
+ if( GetMemoryCardManager()->IsMemcardInfoLoaded() )
+ {
+ // unload it now
+ //
+ GetMemoryCardManager()->UnloadMemcardInfo();
+ }
+ else
+ {
+ // wait until loading is complete, then unload it
+ //
+ m_unloadMemcardInfoWhenLoaded = true;
+ }
+ }
+
+ m_exitingPauseMenu = true;
+
+ // follow-thru ...
+ //
+ }
+ case GUI_MSG_RESUME_INGAME:
+ {
+ if( GetInteriorManager()->IsEntering() || GetInteriorManager()->IsExiting() )
+ {
+ // ignore this message, cuz if we're either entering or exiting an interior,
+ // we're waiting for either the EVENT_ENTER_INTERIOR_TRANSITION_END or
+ // EVENT_EXIT_INTERIOR_END event from the InteriorManager to resume the game
+ // screen
+ //
+ break;
+ }
+
+ this->ResumeGame( param1, param2 );
+
+ break;
+ }
+ case GUI_MSG_ON_SAVE_GAME_COMPLETE:
+ {
+ m_promptSaveBeforeQuit = false;
+
+ if( m_quitAfterSave )
+ {
+ this->HandleMessage( GUI_MSG_QUIT_INGAME );
+ }
+#ifdef RAD_WIN32
+ else if( m_quitToSystemAfterSave )
+ {
+ this->HandleMessage( GUI_MSG_QUIT_TO_SYSTEM );
+ }
+#endif
+ else
+ {
+ this->HandleMessage( GUI_MSG_BACK_SCREEN );
+ }
+
+ break;
+ }
+ case GUI_MSG_BACK_SCREEN:
+ {
+ if( this->GetPreviousScreen( param1 ) == CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT )
+ {
+ m_quitAfterSave = false;
+
+ CGuiMenuPrompt::ePromptResponse responses[] =
+ {
+ CGuiMenuPrompt::RESPONSE_YES,
+ CGuiMenuPrompt::RESPONSE_NO
+ };
+
+ CGuiScreenPrompt::Display( PROMPT_CONFIRM_SAVE_BEFORE_QUIT, this, 2, responses );
+ CGuiScreenPrompt::EnableDefaultToNo( false );
+ }
+
+ break;
+ }
+ case GUI_MSG_WINDOW_FINISHED:
+ {
+ if( GUI_FE_CHANGING_SCREENS == m_state )
+ {
+ m_currentScreen = m_nextScreen;
+
+ if( m_exitingPauseMenu )
+ {
+ this->GotoHUDScreen();
+ }
+ else if( m_enteringPauseMenu )
+ {
+ this->GotoPauseScreen();
+ }
+ else
+ {
+ if( this->IsHudScreen( m_nextScreen ) )
+ {
+ this->GotoHUDScreen();
+ }
+ else
+ {
+ CGuiScreen* nextScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) );
+ rAssert( nextScreen != NULL );
+ m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this );
+ }
+ }
+ }
+ else if( GUI_FE_SHUTTING_DOWN == m_state )
+ {
+ m_state = GUI_FE_TERMINATED;
+
+ // set backend scrooby project as active project
+ //
+ GetGuiSystem()->SwitchToBackendProject();
+
+ // pre-run backend loading screen
+ //
+ CGuiManagerBackEnd* backendManager = GetGuiSystem()->GetBackendManager();
+ rAssert( backendManager != NULL );
+ backendManager->HandleMessage( GUI_MSG_PRE_RUN_BACKEND,
+ m_quitAndReload ? IS_LOADING_GAMEPLAY : 0 );
+
+ // enable screen clearing
+ //
+ GetRenderManager()->mpLayer(RenderEnums::GUI)->pView( 0 )->SetClearMask( PDDI_BUFFER_ALL );
+ }
+
+ break;
+ }
+ case GUI_MSG_INGAME_MISSION_COMPLETE:
+ {
+ // param1 = 1 --> New Best Time!
+ //
+ if( s_currentHUD != NULL )
+ {
+ s_currentHUD->HandleMessage( GUI_MSG_SHOW_HUD_OVERLAY,
+ HUD_MISSION_COMPLETE, param1 );
+ }
+
+ break;
+ }
+ case GUI_MSG_INGAME_MISSION_FAILED:
+ {
+ CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_MISSION_OVER,
+ CLEAR_WINDOW_HISTORY );
+
+ // switch to pause context
+ GetGameFlow()->SetContext( CONTEXT_PAUSE );
+ break;
+ }
+ case GUI_MSG_INGAME_MISSION_LOAD_BEGIN:
+ {
+ //
+ // if we're on the iris screen, then we don't want to open the iris
+ //
+ CGuiWindow::eGuiWindowID current = CGuiManager::GetCurrentScreen();
+ if( current == CGuiWindow::GUI_SCREEN_ID_IRIS_WIPE )
+ {
+ CGuiScreenIrisWipe::DoNotOpenOnNextOutro();
+ }
+ CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_MISSION_LOAD,
+ CLEAR_WINDOW_HISTORY );
+
+ // switch to pause context
+ GetGameFlow()->SetContext( CONTEXT_PAUSE );
+
+ break;
+ }
+ case GUI_MSG_INGAME_MISSION_LOAD_END:
+ {
+ // notify MissionLoad screen that mission load has completed
+ //
+ if( !GetGameplayManager()->GetCurrentMission()->IsSundayDrive() )
+ {
+ GetEventManager()->TriggerEvent( EVENT_GUI_MISSION_LOAD_COMPLETE );
+ }
+
+ break;
+ }
+ case GUI_MSG_SHOW_HUD_OVERLAY:
+ case GUI_MSG_HIDE_HUD_OVERLAY:
+ {
+ // send HUD overlay messages to current HUD
+ //
+ if( s_currentHUD != NULL )
+ {
+ s_currentHUD->HandleMessage( message, param1, param2 );
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_CONNECT:
+ {
+#ifndef RAD_GAMECUBE
+ if( m_oldControllerState == Input::ACTIVE_ANIM_CAM )
+ {
+ // deactivate anim cam state first, since the input manager
+ // won't let us set the game state to anything else prior
+ // to that
+ //
+ GetInputManager()->SetGameState( Input::DEACTIVE_ANIM_CAM );
+ }
+ GetInputManager()->SetGameState( Input::ACTIVE_FRONTEND );
+#endif // !RAD_GAMECUBE
+
+ break;
+ }
+ case GUI_MSG_START_IRIS_WIPE_OPEN:
+ {
+ this->HandleMessage( GUI_MSG_RESUME_INGAME );
+
+ break;
+ }
+ case GUI_MSG_START_IRIS_WIPE_CLOSE:
+ {
+ this->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_IRIS_WIPE,
+ CLEAR_WINDOW_HISTORY );
+
+ break;
+ }
+ case GUI_MSG_INGAME_DISPLAY_PROMPT:
+ {
+ int ingameMessageIndex = NUM_PROMPT_QUESTIONS + static_cast<int>( param1 );
+ this->DisplayPrompt( ingameMessageIndex, s_currentHUD, PROMPT_TYPE_CONTINUE );
+
+ rAssert( GetGameFlow()->GetCurrentContext() == CONTEXT_GAMEPLAY );
+ GetGameFlow()->SetContext( CONTEXT_PAUSE );
+
+ break;
+ }
+ default:
+ {
+ if( message == GUI_MSG_UPDATE && m_isControllerReconnected )
+ {
+ m_isControllerReconnected = false;
+ m_controllerPromptShown = false;
+
+ }
+
+ if (m_controllerPromptShown) // don't pass event if controller error
+ {
+ if (message==GUI_MSG_CONTROLLER_START) // start trigger reconnection
+ {
+ this->OnControllerConnected( static_cast<int>( param1 ) );
+ }
+
+ break;
+ }
+
+ if( m_state != GUI_FE_UNINITIALIZED &&
+ m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED )
+ {
+ // Send the messages down to the current screen.
+ //
+ CGuiWindow* pScreen = this->FindWindowByID( m_currentScreen );
+ rAssert( pScreen );
+
+ pScreen->HandleMessage( message, param1, param2 );
+ }
+
+#ifndef RAD_GAMECUBE
+ // poll controller connection status
+ //
+ if( message == GUI_MSG_UPDATE )
+ {
+ int controllerID = GetInputManager()->GetControllerIDforPlayer( 0 );
+ if( !GetInputManager()->GetController( controllerID )->IsConnected() )
+ {
+ bool setState = !m_controllerPromptShown;
+ this->OnControllerDisconnected( controllerID );
+
+ if ( setState )
+ {
+ m_oldControllerState = InputManager::GetInstance()->GetGameState();
+ }
+ }
+ }
+#endif // !RAD_GAMECUBE
+
+ break;
+ }
+ }
+
+ // propogate message up the hierarchy
+ CGuiManager::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiManagerInGame::HandleEvent
+//===========================================================================
+// Description: This function translates events from to GUI messages
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void
+CGuiManagerInGame::HandleEvent( EventEnum id, void* pEventData )
+{
+ switch( id )
+ {
+ case EVENT_CONVERSATION_INIT:
+ {
+ this->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_LETTER_BOX,
+ CLEAR_WINDOW_HISTORY );
+
+ GetInputManager()->SetGameState(Input::ACTIVE_FRONTEND);
+
+ break;
+ }
+ case EVENT_CONVERSATION_DONE_AND_FINISHED:
+ {
+ //
+ // Was this mission a patty and selma conversation
+ //
+ GameplayManager* gpm = GetGameplayManager();
+ Mission* mission = gpm->GetCurrentMission();
+ bool pattyAndSelma = mission->GetCurrentStage()->GetObjective()->IsPattyAndSelmaDialog();
+ if( pattyAndSelma )
+ {
+
+ GetInputManager()->SetGameState(Input::ACTIVE_GAMEPLAY);
+ this->HandleMessage( GUI_MSG_RESUME_INGAME );
+ GetEventManager()->TriggerEvent( EVENT_GUI_TRIGGER_PATTY_AND_SELMA_SCREEN );
+
+ /*
+ GetGuiSystem()->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_MISSION_SUCCESS,
+ CLEAR_WINDOW_HISTORY );
+ GetEventManager()->TriggerEvent( EVENT_GUI_ENTERING_MISSION_SUCCESS_SCREEN );
+ GetGameFlow()->SetContext( CONTEXT_PAUSE );
+ */
+ }
+ else
+ {
+ GetInputManager()->SetGameState(Input::ACTIVE_GAMEPLAY);
+ this->HandleMessage( GUI_MSG_RESUME_INGAME );
+ }
+
+ break;
+ }
+ case EVENT_ENTER_INTERIOR_TRANSITION_START:
+ case EVENT_EXIT_INTERIOR_START:
+ {
+/*
+ if( m_currentScreen == CGuiWindow::GUI_SCREEN_ID_IRIS_WIPE )
+ {
+ // ignore, if we're already on the iris wipe screen
+ //
+ break;
+ }
+*/
+ if( id == EVENT_ENTER_INTERIOR_TRANSITION_START )
+ {
+ rReleasePrintf( "CGuiManagerInGame <= EVENT_ENTER_INTERIOR_TRANSITION_START.\n" );
+ }
+ else
+ {
+ rReleasePrintf( "CGuiManagerInGame <= EVENT_EXIT_INTERIOR_START.\n" );
+ }
+
+ this->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_IRIS_WIPE,
+ CLEAR_WINDOW_HISTORY );
+
+ break;
+ }
+ case EVENT_ENTER_INTERIOR_TRANSITION_END:
+ case EVENT_EXIT_INTERIOR_END:
+ {
+ if( id == EVENT_ENTER_INTERIOR_TRANSITION_END )
+ {
+ rReleasePrintf( "CGuiManagerInGame <= EVENT_ENTER_INTERIOR_TRANSITION_END.\n" );
+ }
+ else
+ {
+ rReleasePrintf( "CGuiManagerInGame <= EVENT_EXIT_INTERIOR_END.\n" );
+ }
+
+ this->ResumeGame();
+
+ break;
+ }
+ case (EventEnum)(EVENT_LOCATOR + LocatorEvent::DEATH):
+ {
+ EventLocator* evtLoc = static_cast<EventLocator*>(pEventData);
+ if ( evtLoc->GetPlayerID() < static_cast<unsigned int>(MAX_PLAYERS) )
+ {
+ //chuck: check if the current hud is active, if it's not then it may not generate the
+ //EVENT_DEATH_VOLUME_SCREEN_BLANK, so we should artifically trigger it
+ if( s_currentHUD != NULL && s_currentHUD->IsActive() )
+ {
+ //This is a player who triggered this.
+ s_currentHUD->HandleMessage( GUI_MSG_DEATH_VOLUME_START, reinterpret_cast< unsigned int >( pEventData ) );
+ }
+ else
+ {
+ // current HUD is not active, so letz just fire this event back to whoever is
+ // waiting for it and ditch the presentation
+ //
+ GetEventManager()->TriggerEvent(EVENT_DEATH_VOLUME_SCREEN_BLANK,pEventData);
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ rWarningMsg( false, "Why are we receiving messages we care nothing about?" );
+
+ break;
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiManagerInGame::OnProjectLoadComplete
+//===========================================================================
+void
+CGuiManagerInGame::OnProjectLoadComplete( Scrooby::Project* pProject )
+{
+ m_pScroobyProject = pProject;
+ GetGuiSystem()->SetCurrentScroobyProject( m_pScroobyProject );
+
+ rReleasePrintf( "Scrooby dynamic loading completed. (%d msec)\n", m_elapsedDynaLoadTime );
+}
+
+void
+CGuiManagerInGame::OnMemcardInfoLoadComplete()
+{
+ if( m_unloadMemcardInfoWhenLoaded )
+ {
+ GetMemoryCardManager()->UnloadMemcardInfo();
+ }
+}
+
+//===========================================================================
+// Private Member Functions
+//===========================================================================
+
+void
+CGuiManagerInGame::UpdateDuringMissionLoading( unsigned int elapsedTime )
+{
+ // update backend loading screen
+ //
+ CGuiManagerBackEnd* backendManager = GetGuiSystem()->GetBackendManager();
+ rAssert( backendManager != NULL );
+ backendManager->HandleMessage( GUI_MSG_UPDATE, elapsedTime );
+}
+
+void
+CGuiManagerInGame::UpdateWhileLoadingNotDone( unsigned int elapsedTime )
+{
+ // update backend loading screen
+ //
+ CGuiManagerBackEnd* backendManager = GetGuiSystem()->GetBackendManager();
+ rAssert( backendManager != NULL );
+ backendManager->HandleMessage( GUI_MSG_UPDATE, elapsedTime );
+
+ // waiting for loading manger queue to empty before quitting
+ //
+ if( GetLoadingManager()->IsLoading() )
+ {
+ rTunePrintf( ">> Waiting for loading manager to finish loading ... ...\n" );
+ }
+ else
+ {
+ // ok, let's quit outa here!
+ //
+ this->QuitGame();
+ }
+}
+
+void
+CGuiManagerInGame::GotoPauseScreen()
+{
+ m_enteringPauseMenu = false;
+ GetGameplayContext()->PauseAllButPresentation( false );
+
+ rAssert( m_nextScreen == CGuiWindow::GUI_SCREEN_ID_PAUSE_SUNDAY ||
+ m_nextScreen == CGuiWindow::GUI_SCREEN_ID_PAUSE_MISSION );
+
+ CGuiScreen* pauseScreen = (CGuiScreen*)CGuiManager::FindWindowByID( m_nextScreen );
+ rAssert( pauseScreen );
+ pauseScreen->SetZoomingEnabled( true );
+
+ m_pScroobyProject->GotoScreen( pauseScreen->GetScroobyScreen(), this );
+}
+
+void
+CGuiManagerInGame::GotoHUDScreen()
+{
+ m_exitingPauseMenu = false;
+
+ GetEventManager()->TriggerEvent( EVENT_GUI_LEAVING_PAUSE_MENU );
+
+ CGuiScreen* hudScreen = static_cast< CGuiScreen* >( this->FindWindowByID( m_nextScreen ) );
+ rAssert( hudScreen != NULL );
+ m_pScroobyProject->GotoScreen( hudScreen->GetScroobyScreen(), this );
+
+ // handle any commands specified for upon entering HUD
+ //
+ switch( m_onHudEnterCommand )
+ {
+ case ON_HUD_ENTER_RESTART_MISSION:
+ {
+ GetGuiSystem()->HandleMessage( GUI_MSG_START_IRIS_WIPE_CLOSE, 0x00 );
+ m_RestartMissionTransition.Activate();
+
+ // stop any dialog that may still be in progress
+ //
+ GetEventManager()->TriggerEvent( EVENT_DIALOG_SHUTUP );
+
+ break;
+ }
+ case ON_HUD_ENTER_ABORT_MISSION:
+ {
+ m_AbortMissionTransition.Activate();
+
+ // stop any dialog that may still be in progress
+ //
+ GetEventManager()->TriggerEvent( EVENT_DIALOG_SHUTUP );
+
+ break;
+ }
+ case ON_HUD_ENTER_SKIP_MISSION:
+ {
+ GetGameFlow()->SetContext( CONTEXT_GAMEPLAY );
+ GetGameplayManager()->AbortCurrentMission();
+ GetGameplayManager()->NextMission();
+
+ RenderEnums::LevelEnum currentLevel = GetCharacterSheetManager()->QueryCurrentMission().mLevel;
+ RenderEnums::MissionEnum currentMission = GetCharacterSheetManager()->QueryCurrentMission().mMissionNumber;
+ GetCharacterSheetManager()->SetMissionSkipped( currentLevel, currentMission );
+
+ break;
+ }
+ default:
+ {
+ // don't switch to gameplay context if returning to tutorial screen
+ //
+ if(m_nextScreen == CGuiWindow::GUI_SCREEN_ID_HUD)
+ {
+ GetGameFlow()->SetContext( CONTEXT_GAMEPLAY );
+ }
+
+ break;
+ }
+ }
+
+ m_onHudEnterCommand = ON_HUD_ENTER_NO_COMMAND;
+}
+
+void
+CGuiManagerInGame::ResumeGame( unsigned int param1, unsigned int param2 )
+{
+ if( m_resumeGameScreenID != CGuiWindow::GUI_WINDOW_ID_UNDEFINED )
+ {
+ CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN,
+ m_resumeGameScreenID,
+ CLEAR_WINDOW_HISTORY );
+ }
+ else
+ {
+ CGuiManager::HandleMessage( GUI_MSG_GOTO_SCREEN,
+ CGuiWindow::GUI_SCREEN_ID_HUD,
+ CLEAR_WINDOW_HISTORY );
+ }
+
+ m_resumeGameScreenID = CGuiWindow::GUI_WINDOW_ID_UNDEFINED;
+
+ m_onHudEnterCommand = param1;
+ m_nextMissionIndex = param2;
+}
+
+void
+CGuiManagerInGame::QuitGame()
+{
+ if( m_quitAndReload )
+ {
+ rAssert( m_nextLevelIndex != -1 && m_nextMissionIndex != -1 );
+
+ // switch to loading context
+ //
+ if( m_nextLevelIndex != GetGameplayManager()->GetCurrentLevelIndex() )
+ {
+ if( GetGameplayManager()->GetGameComplete() ) // game finished
+ {
+ GetGameFlow()->SetContext( CONTEXT_FRONTEND );
+ }
+ else
+ {
+ GetGameFlow()->SetContext( CONTEXT_LOADING_GAMEPLAY );
+ }
+ }
+ else
+ {
+ this->OnNewMissionLoadBegin();
+ }
+
+ m_quitAndReload = false;
+ }
+ else
+ {
+ // switch to frontend context
+ GetGameFlow()->SetContext( CONTEXT_FRONTEND );
+ }
+}
+
+void
+CGuiManagerInGame::OnControllerDisconnected( int controllerID )
+{
+/*
+ if( s_currentHUD != NULL )
+ {
+ s_currentHUD->SetFadingEnabled( false );
+ }
+*/
+
+ m_controllerPromptShown = true;
+ char str_buffer[256];
+ CGuiScreenMessage::GetControllerDisconnectedMessage(controllerID, str_buffer, 255);
+ GetGame()->GetPlatform()->OnControllerError(str_buffer);
+
+}
+
+void
+CGuiManagerInGame::OnControllerConnected( int controllerID )
+{
+ if( m_controllerPromptShown
+ && GetInputManager()->GetControllerIDforPlayer( 0 ) == controllerID )
+ {
+
+#ifdef RAD_XBOX
+// go to pause screen after disconnection
+ rAssert(s_currentHUD);
+ if( s_currentHUD && s_currentHUD->IsActive() )
+ this->HandleMessage( GUI_MSG_PAUSE_INGAME );
+#endif
+ GetGame()->GetPlatform()->ClearControllerError();
+
+ InputManager::GetInstance()->SetGameState(m_oldControllerState);
+
+ m_isControllerReconnected = true;
+
+ }
+}
+
+//===========================================================================
+// CGuiManagerInGame::OnNewMissionLoadBegin
+//===========================================================================
+// Description: Starting point for loading a new mission (within the same
+// level) from the Mission Select screen.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void
+CGuiManagerInGame::OnNewMissionLoadBegin()
+{
+ GetGameplayManager()->RestartToMission( static_cast<RenderEnums::MissionEnum>( m_nextMissionIndex ) );
+
+ GetPauseContext()->SetWaitingForContextSwitch( true );
+
+ m_resumeGameScreenID = CGuiWindow::GUI_WINDOW_ID_UNDEFINED;
+
+ // run backend loading screen
+ //
+ CGuiManagerBackEnd* backendManager = GetGuiSystem()->GetBackendManager();
+ rAssert( backendManager != NULL );
+ backendManager->HandleMessage( GUI_MSG_RUN_BACKEND, IS_LOADING_GAMEPLAY );
+
+ m_state = GUI_FE_UNINITIALIZED;
+
+ m_isLoadingNewMission = true;
+}
+
+//===========================================================================
+// CGuiManagerInGame::OnNewMissionLoadEnd
+//===========================================================================
+// Description: Finishing point for loading a new mission (within the same
+// level) from the Mission Select screen.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void
+CGuiManagerInGame::OnNewMissionLoadEnd()
+{
+ this->Start();
+ this->ClearScreenHistory();
+
+ // quit backend loading screen
+ //
+ CGuiManagerBackEnd* backendManager = GetGuiSystem()->GetBackendManager();
+ rAssert( backendManager != NULL );
+ backendManager->HandleMessage( GUI_MSG_QUIT_BACKEND );
+
+ GetGuiSystem()->SwitchToCurrentProject();
+
+ m_isLoadingNewMission = false;
+}
+
+//===========================================================================
+// CGuiManagerInGame::IsPausingAllowed
+//===========================================================================
+// Description: returns FALSE if in-game pausing is not allowed due to
+// at least one condition; otherwise, returns TRUE
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+bool
+CGuiManagerInGame::IsPausingAllowed() const
+{
+ if( m_state == GUI_FE_CHANGING_SCREENS )
+ {
+ // don't allow pausing if we're currently in the middle of changing screens
+ //
+ return false;
+ }
+
+ if( GameplayContext::GetInstance()->IsPaused() || GetPresentationManager()->IsBusy() )
+ {
+ return false;
+ }
+
+ if( GetGameplayManager()->GetCurrentMessage() != GameplayManager::NONE )
+ {
+ // don't allow pausing if the gameplay manager is in the middle of changing missions
+ //
+ rAssert( GetGameplayManager()->GetCurrentMessage() == GameplayManager::PREV_MISSION ||
+ GetGameplayManager()->GetCurrentMessage() == GameplayManager::NEXT_MISSION );
+
+ return false;
+ }
+
+ Mission* currentMission = GetGameplayManager()->GetCurrentMission();
+ if( currentMission->IsChangingStages() )
+ {
+ // don't allow pausing if the current mission is in the middle of changing stages
+ //
+ return false;
+ }
+
+ if( GetGameplayManager()->GetLevelComplete() || GetGameplayManager()->GetGameComplete() )
+ {
+ // don't allow pausing if level/game has just been completed
+ //
+ return false;
+ }
+
+ return true;
+}
+
+
+//===========================================================================
+// AbortCurrentMission::Activate
+//===========================================================================
+// Description: cancels a mission
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void GuiSFX::AbortCurrentMission::Activate()
+{
+ GetGameFlow()->SetContext( CONTEXT_GAMEPLAY );
+ GetGameplayManager()->AbortCurrentMission();
+ ContinueChain();
+};
+
+//===========================================================================
+// RestartCurrentMission::OpenIris
+//===========================================================================
+// Description: reactivates a paused mission
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void GuiSFX::OpenIris::Activate()
+{
+ bool irisClosed = CGuiScreenIrisWipe::IsIrisClosed();
+ if( irisClosed )
+ {
+ GetGuiSystem()->HandleMessage( GUI_MSG_START_IRIS_WIPE_OPEN, 0x00 );
+ }
+ ContinueChain();
+};
+
+//===========================================================================
+// RestartCurrentMission::Activate
+//===========================================================================
+// Description: reactivates a paused mission
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void GuiSFX::RestartCurrentMission::Activate()
+{
+ GetGameplayManager()->RestartCurrentMission();
+ ContinueChain();
+};
diff --git a/game/code/presentation/gui/ingame/guimanageringame.h b/game/code/presentation/gui/ingame/guimanageringame.h
new file mode 100644
index 0000000..7356585
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guimanageringame.h
@@ -0,0 +1,231 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiManagerInGame
+//
+// Description: Interface for the CGuiManagerInGame class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/09/20 DChau Created
+// 2002/05/29 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef GUIMANAGERINGAME_H
+#define GUIMANAGERINGAME_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/utility/transitions.h>
+#include <data/memcard/memorycardmanager.h>
+#include <input/inputmanager.h>
+
+#include <app.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class CGuiScreenHud;
+namespace GuiSFX
+{
+ class RecieveEvent;
+
+ class AbortCurrentMission : public GuiSFX::Chainable1
+ {
+ public:
+ virtual void Activate();
+ }; //class AbortCurrentMission;
+
+ class OpenIris : public GuiSFX::Chainable1
+ {
+ public:
+ virtual void Activate();
+ }; //class RestartCurrentMission;
+
+ class RestartCurrentMission : public GuiSFX::Chainable1
+ {
+ public:
+ virtual void Activate();
+ }; //class RestartCurrentMission;
+}; //namespace GuiSFX
+
+namespace Scrooby
+{
+ class Layer;
+}
+
+enum eOnHudEnterCommand
+{
+ ON_HUD_ENTER_NO_COMMAND = 0,
+
+ ON_HUD_ENTER_RESTART_MISSION,
+ ON_HUD_ENTER_ABORT_MISSION,
+ ON_HUD_ENTER_SKIP_MISSION,
+
+ NUM_ON_HUD_ENTER_COMMANDS
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+class CGuiManagerInGame : public CGuiManager,
+ public Scrooby::LoadProjectCallback,
+ public IMemoryCardInfoLoadCallback
+{
+public:
+ CGuiManagerInGame( Scrooby::Project* pProject, CGuiEntity* pParent );
+ virtual ~CGuiManagerInGame();
+
+ virtual void Populate();
+ virtual void Start( CGuiWindow::eGuiWindowID initialWindow = CGuiWindow::GUI_WINDOW_ID_UNDEFINED );
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual void HandleEvent( EventEnum id, void* pEventData );
+
+ int GetNextLevelToLoad() const { return m_nextLevelIndex; }
+ int GetNextMissionToLoad() const { return m_nextMissionIndex; }
+
+ bool IsEnteringPauseMenu() const { return m_enteringPauseMenu; }
+ bool isExitingPauseMenu() const { return m_exitingPauseMenu; }
+
+ bool IsLoadingNewMissionInSundayDrive() const; // newspaper loading screen displayed
+ bool IsLoadingNewMission() const; // mission briefing screen displayed
+
+ CGuiWindow::eGuiWindowID GetResumeGameScreenID() const { return m_resumeGameScreenID; }
+
+ //
+ // Implements Scrooby::LoadProjectCallback interface.
+ //
+ virtual void OnProjectLoadComplete( Scrooby::Project* pProject );
+
+ // Implements IMemoryCardInfoLoadCallback interface.
+ //
+ virtual void OnMemcardInfoLoadComplete();
+
+ // Pointer to current HUD.
+ //
+ static CGuiScreenHud* s_currentHUD;
+
+private:
+
+ //---------------------------------------------------------------------
+ // Private Functions
+ //---------------------------------------------------------------------
+
+ // No copying or assignment. Declare but don't define.
+ //
+ CGuiManagerInGame( const CGuiManagerInGame& );
+ CGuiManagerInGame& operator= ( const CGuiManagerInGame& );
+
+ bool IsHudScreen( CGuiWindow::eGuiWindowID windowID ) const;
+ bool IsRewardsScreen( CGuiWindow::eGuiWindowID windowID ) const;
+
+ enum eInGameProject
+ {
+ PROJECT_INGAME,
+ PROJECT_PAUSE,
+ PROJECT_REWARDS,
+
+ NUM_INGAME_PROJECTS
+ };
+
+ void PopulateInGame( eInGameProject project = PROJECT_INGAME );
+
+ void UpdateDuringDynamicLoading( unsigned int elapsedTime );
+ void UpdateDuringMissionLoading( unsigned int elapsedTime );
+ void UpdateWhileLoadingNotDone( unsigned int elapsedTime );
+
+ void GotoPauseScreen();
+ void GotoHUDScreen();
+
+ void ResumeGame( unsigned int param1 = 0, unsigned int param2 = 0 );
+ void QuitGame();
+
+ void OnControllerDisconnected( int controllerID );
+ void OnControllerConnected( int controllerID );
+
+ void OnNewMissionLoadBegin();
+ void OnNewMissionLoadEnd();
+
+ bool IsPausingAllowed() const;
+
+ //---------------------------------------------------------------------
+ // Private Data
+ //---------------------------------------------------------------------
+
+ int m_nextLevelIndex;
+ int m_nextMissionIndex;
+
+ bool m_isLoadingNewMission : 1;
+ bool m_quitAndReload : 1;
+ bool m_controllerPromptShown : 1;
+ bool m_enteringPauseMenu : 1;
+ bool m_exitingPauseMenu : 1;
+
+ unsigned int m_onHudEnterCommand;
+
+ Scrooby::Screen* m_levelScreen;
+ Scrooby::Layer* m_levelLayer;
+ unsigned int m_elapsedDynaLoadTime;
+
+ Scrooby::Project* m_pRewardsProject;
+
+ bool m_unloadMemcardInfoWhenLoaded : 1;
+ bool m_promptSaveBeforeQuit : 1;
+ bool m_quitAfterSave : 1;
+#ifdef RAD_WIN32
+ bool m_quitToSystemAfterSave : 1;
+#endif
+ bool m_isControllerReconnected : 1;
+
+ GuiSFX::Dummy m_RestartMissionTransition;
+ GuiSFX::RecieveEvent m_RecieveIrisClosed;
+ GuiSFX::RestartCurrentMission m_RestartMission;
+
+ GuiSFX::Dummy m_AbortMissionTransition;
+ GuiSFX::AbortCurrentMission m_AbortMission;
+
+ Input::ActiveState m_oldControllerState;
+
+ CGuiWindow::eGuiWindowID m_resumeGameScreenID;
+
+};
+
+inline CGuiScreenHud* GetCurrentHud()
+{
+ // return reference to current in-game HUD
+ //
+ return CGuiManagerInGame::s_currentHUD;
+}
+
+inline bool CGuiManagerInGame::IsLoadingNewMissionInSundayDrive() const
+{
+ return m_isLoadingNewMission;
+}
+
+inline bool CGuiManagerInGame::IsLoadingNewMission() const
+{
+ return ( m_currentScreen == CGuiWindow::GUI_SCREEN_ID_MISSION_LOAD );
+}
+
+inline bool CGuiManagerInGame::IsHudScreen( CGuiWindow::eGuiWindowID windowID ) const
+{
+ return( windowID == CGuiWindow::GUI_SCREEN_ID_HUD ||
+ windowID == CGuiWindow::GUI_SCREEN_ID_MULTI_HUD );
+}
+
+inline bool CGuiManagerInGame::IsRewardsScreen( CGuiWindow::eGuiWindowID windowID ) const
+{
+ return( windowID == CGuiWindow::GUI_SCREEN_ID_PURCHASE_REWARDS );
+}
+
+#endif // GUIMANAGERINGAME_H
diff --git a/game/code/presentation/gui/ingame/guiscreencreditspostfmv.cpp b/game/code/presentation/gui/ingame/guiscreencreditspostfmv.cpp
new file mode 100644
index 0000000..1d8e0e8
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreencreditspostfmv.cpp
@@ -0,0 +1,267 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenCreditsPostFMV
+//
+// Description: Implementation of the CGuiScreenCreditsPostFMV class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/06/02 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreencreditspostfmv.h>
+#include <presentation/gui/guimanager.h>
+
+#include <events/eventmanager.h>
+#include <sound/soundmanager.h>
+
+// Scrooby
+#include <screen.h>
+#include <page.h>
+#include <group.h>
+#include <sprite.h>
+
+// ATG
+#include <p3d/utility.hpp>
+#include <raddebug.hpp>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const float KANG_KODOS_IMAGE_CORRECTION_SCALE = 1.5f;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenCreditsPostFMV::CGuiScreenCreditsPostFMV
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenCreditsPostFMV::CGuiScreenCreditsPostFMV
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreenViewCredits( pScreen, pParent ),
+ m_kang( NULL ),
+ m_kodos( NULL )
+{
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "CreditsKK" );
+ rAssert( pPage != NULL );
+
+ m_kang = pPage->GetSprite( "Kang" );
+ rAssert( m_kang != NULL );
+ m_kang->SetVisible( false ); // hide by default
+
+ m_kodos = pPage->GetSprite( "Kodos" );
+ rAssert( m_kodos != NULL );
+ m_kodos->SetVisible( false ); // hide by default
+}
+
+
+//===========================================================================
+// CGuiScreenCreditsPostFMV::~CGuiScreenCreditsPostFMV
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenCreditsPostFMV::~CGuiScreenCreditsPostFMV()
+{
+ if( m_kang != NULL )
+ {
+ m_kang->SetRawSprite( NULL );
+ }
+
+ if( m_kodos != NULL )
+ {
+ m_kodos->SetRawSprite( NULL );
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenCreditsPostFMV::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenCreditsPostFMV::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ this->OnScrollingDone();
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ // ignore back controller inputs
+ //
+ return;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreenViewCredits::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenCreditsPostFMV::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenCreditsPostFMV::InitIntro()
+{
+ GetEventManager()->TriggerEvent( EVENT_PLAY_CREDITS );
+
+ m_playKKDialog = true;
+
+ this->ResetScrolling();
+
+ GetSoundManager()->DuckForInGameCredits();
+
+ rAssert( m_creditsGroup != NULL );
+ m_creditsGroup->SetVisible( false );
+
+ //
+ // TC: [TODO] remove the loading of these images from the mission script
+ // for level 7 - mission 8 - sunday drive
+ //
+/*
+ // search for kang and kodos images
+ //
+ tSprite* pSprite = NULL;
+
+ pSprite = p3d::find<tSprite>( "kang.png" );
+ if( pSprite != NULL )
+ {
+ rAssert( m_kang != NULL );
+ m_kang->SetRawSprite( pSprite );
+ m_kang->SetVisible( true );
+
+ m_kang->ResetTransformation();
+ m_kang->ScaleAboutCenter( KANG_KODOS_IMAGE_CORRECTION_SCALE );
+ }
+ else
+ {
+ rAssertMsg( false, "Can't find kang image!" );
+ }
+
+ pSprite = p3d::find<tSprite>( "kodos.png" );
+ if( pSprite != NULL )
+ {
+ rAssert( m_kodos != NULL );
+ m_kodos->SetRawSprite( pSprite );
+ m_kodos->SetVisible( true );
+
+ m_kodos->ResetTransformation();
+ m_kodos->ScaleAboutCenter( KANG_KODOS_IMAGE_CORRECTION_SCALE );
+ }
+ else
+ {
+ rAssertMsg( false, "Can't find kodos image!" );
+ }
+*/
+}
+
+
+//===========================================================================
+// CGuiScreenCreditsPostFMV::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenCreditsPostFMV::InitRunning()
+{
+ rAssert( m_creditsGroup != NULL );
+ m_creditsGroup->SetVisible( true );
+}
+
+
+//===========================================================================
+// CGuiScreenCreditsPostFMV::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenCreditsPostFMV::InitOutro()
+{
+ GetEventManager()->TriggerEvent( EVENT_DIALOG_SHUTUP );
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenCreditsPostFMV::OnScrollingDone()
+{
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ GUI_SCREEN_ID_LEVEL_END,
+ CLEAR_WINDOW_HISTORY );
+}
+
diff --git a/game/code/presentation/gui/ingame/guiscreencreditspostfmv.h b/game/code/presentation/gui/ingame/guiscreencreditspostfmv.h
new file mode 100644
index 0000000..5a2d523
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreencreditspostfmv.h
@@ -0,0 +1,54 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenCreditsPostFMV
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/06/02 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENCREDITSPOSTFMV_H
+#define GUISCREENCREDITSPOSTFMV_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreenviewcredits.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenCreditsPostFMV : public CGuiScreenViewCredits
+{
+public:
+ CGuiScreenCreditsPostFMV( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenCreditsPostFMV();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ virtual void OnScrollingDone();
+
+ Scrooby::Sprite* m_kang;
+ Scrooby::Sprite* m_kodos;
+
+};
+
+#endif // GUISCREENCREDITSPOSTFMV_H
diff --git a/game/code/presentation/gui/ingame/guiscreenhastransitions.cpp b/game/code/presentation/gui/ingame/guiscreenhastransitions.cpp
new file mode 100644
index 0000000..95eaeba
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenhastransitions.cpp
@@ -0,0 +1,213 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLetterBox
+//
+// Description: Implementation of the CGuiScreenLetterBox class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/21 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenhastransitions.h>
+#include <presentation/gui/utility/transitions.h>
+#include <drawable.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenHasTransitions::CGuiScreenHasTransitions
+//===========================================================================
+// Description: Constructor
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenHasTransitions::CGuiScreenHasTransitions():
+ mDoneAddingTransitions( false )
+{
+ // zero out the array of transitions (use a memset instead)?
+ int i;
+ for( i = 0; i < MAX_TRANSITIONS; ++i )
+ {
+ m_Transitions[ i ] = NULL;
+ }
+}
+
+//===========================================================================
+// CGuiScreenHasTransitions::AddTransition
+//===========================================================================
+// Description: Adds the transition to the array of transitions
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHasTransitions::AddTransition( GuiSFX::Transition* transition )
+{
+ int i;
+ for( i = 0; i < MAX_TRANSITIONS; ++i )
+ {
+ if( m_Transitions[ i ] == NULL )
+ {
+ m_Transitions[ i ] = transition;
+ return;
+ }
+ }
+ rAssertMsg( false, "Need to bump up the size of the array of transitions" );
+}
+
+//===========================================================================
+// CGuiScreenMissionLoad::AddTransition
+//===========================================================================
+// Description: Adds the transition to the array of transitions
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHasTransitions::AddTransition( GuiSFX::Transition& transition )
+{
+ int i;
+ for( i = 0; i < MAX_TRANSITIONS; ++i )
+ {
+ if( m_Transitions[ i ] == NULL )
+ {
+ m_Transitions[ i ] = &transition;
+ return;
+ }
+ }
+ rAssertMsg( false, "Need to bump up the size of the array of transitions" );
+}
+
+//===========================================================================
+// CGuiScreenMissionLoad::DoneAddingTransitions
+//===========================================================================
+// Description: tells the class that we're done adding transitions to it. Used
+// for debugging the size of the array
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHasTransitions::DoneAddingTransitions()
+{
+ mDoneAddingTransitions = true;
+}
+
+//===========================================================================
+// CGuiScreenHasTransitions::ResetMovableObjects
+//===========================================================================
+// Description: resets transformations for all movable objects
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHasTransitions::ResetMovableObjects()
+{
+ int i;
+ for( i = 0; i < MAX_TRANSITIONS; ++i )
+ {
+ GuiSFX::Transition* t = m_Transitions[ i ];
+ if( t != NULL )
+ {
+ bool active = t->IsActive();
+ if( active )
+ {
+ bool movable = t->MovesDrawable();
+ if( movable )
+ {
+ Scrooby::Drawable* drawable = t->GetDrawable();
+ if( drawable != NULL )
+ {
+ drawable->ResetTransformation();
+ }
+ }
+ }
+ }
+ }
+}
+
+//===========================================================================
+// CGuiScreenHasTransitions::ResetTransitions
+//===========================================================================
+// Description: resets all of the transitions on the screen
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHasTransitions::ResetTransitions()
+{
+ rAssert( mDoneAddingTransitions );
+ int i;
+ for( i = 0; i < MAX_TRANSITIONS; ++i )
+ {
+ if( m_Transitions[ i ] == NULL )
+ {
+ return;
+ }
+ m_Transitions[ i ]->Reset();
+ }
+}
+
+//===========================================================================
+// CGuiScreenMissionLoad::UpdateTransitions
+//===========================================================================
+// Description: updates all the transitions
+//
+// Constraints: None.
+//
+// Parameters: deltaT - how much time has elapsed
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHasTransitions::UpdateTransitions( const float deltaT )
+{
+ rAssert( mDoneAddingTransitions );
+ int i;
+ for( i = 0; i < MAX_TRANSITIONS; ++i )
+ {
+ if( m_Transitions[ i ] == NULL )
+ {
+ return;
+ }
+ if( m_Transitions[ i ]->IsActive() )
+ {
+ m_Transitions[ i ]->Update( deltaT );
+ }
+ }
+} \ No newline at end of file
diff --git a/game/code/presentation/gui/ingame/guiscreenhastransitions.h b/game/code/presentation/gui/ingame/guiscreenhastransitions.h
new file mode 100644
index 0000000..d175896
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenhastransitions.h
@@ -0,0 +1,54 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenHasTransitions
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/19 Ian Gipson Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENHASTRANSITIONS_H
+#define GUISCREENHASTRANSITIONS_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+#define MAX_TRANSITIONS 64
+
+namespace GuiSFX
+{
+ class Transition;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+class CGuiScreenHasTransitions
+{
+public:
+ CGuiScreenHasTransitions();
+protected:
+ void AddTransition( GuiSFX::Transition* transition );
+ void AddTransition( GuiSFX::Transition& transition );
+ void DoneAddingTransitions();
+ void ResetMovableObjects();
+ void ResetTransitions();
+ void UpdateTransitions( const float deltaT );
+private:
+ GuiSFX::Transition* m_Transitions[ MAX_TRANSITIONS ];
+ bool mDoneAddingTransitions;
+};
+
+#endif // GUISCREENHASTRANSITIONS_H
diff --git a/game/code/presentation/gui/ingame/guiscreenhud.cpp b/game/code/presentation/gui/ingame/guiscreenhud.cpp
new file mode 100644
index 0000000..b138d75
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenhud.cpp
@@ -0,0 +1,2106 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenHud
+//
+// Description: Implementation of the CGuiScreenHud class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/11/20 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenhud.h>
+#include <presentation/gui/ingame/guihudtextbox.h>
+#include <presentation/gui/ingame/hudevents/hudcardcollected.h>
+#include <presentation/gui/ingame/hudevents/hudcoincollected.h>
+#include <presentation/gui/ingame/hudevents/hudmissionprogress.h>
+#include <presentation/gui/ingame/hudevents/hudmissionobjective.h>
+#include <presentation/gui/ingame/hudevents/hudcountdown.h>
+#include <presentation/gui/ingame/hudevents/hudhitnrun.h>
+#include <presentation/gui/ingame/hudevents/hudwaspdestroyed.h>
+#include <presentation/gui/ingame/hudevents/huditemdropped.h>
+#include <presentation/gui/utility/hudmap.h>
+#include <presentation/gui/utility/scrollingtext.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/gui/guisystem.h>
+
+#ifdef SRR2_MOVABLE_HUD_MAP
+ #include <presentation/gui/guisystem.h>
+ #include <presentation/gui/guiuserinputhandler.h>
+#endif
+
+#include <cards/card.h>
+#include <contexts/context.h>
+#include <contexts/gameplay/gameplaycontext.h>
+#include <events/eventmanager.h>
+#include <gameflow/gameflow.h>
+#include <interiors/interiormanager.h>
+#include <mission/gameplaymanager.h>
+#include <mission/mission.h>
+#include <mission/missionmanager.h>
+#include <mission/conditions/getoutofcarcondition.h>
+#include <memory/srrmemory.h>
+#include <worldsim/hitnrunmanager.h>
+#include <worldsim/coins/coinmanager.h>
+
+#include <p3d/unicode.hpp>
+
+// FTech
+//
+#include <raddebug.hpp>
+
+// Scrooby
+//
+#include <app.h>
+#include <group.h>
+#include <layer.h>
+#include <page.h>
+#include <pure3dobject.h>
+#include <screen.h>
+#include <sprite.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+// radar fade in/out transition time
+//
+const unsigned int RADAR_FADE_TIME = 250; // in msec
+
+const float RADAR_SCALE = 0.9f;
+
+//const tColour HNR_METER_EMPTY_COLOUR( 0x02, 0x45, 0x39 );
+const short NUMERIC_TEXT_SPACING = -12;
+
+const float HNR_METER_BLINKING_THRESHOLD = 0.78f;
+const tColour HNR_METER_DEFAULT_COLOUR( 255, 234, 2 );
+const tColour HNR_METER_WARNING_COLOUR( 215, 16, 12 );
+
+const tColour PROXIMITY_METER_RED( 255, 0, 0 );
+const tColour PROXIMITY_METER_GREEN( 0, 255, 0 );
+
+// minimum time required for avatar to be off road before updating
+// race position to a ?/N display
+//
+const unsigned int MIN_AVATAR_OFF_ROAD_TIME = 0; // in msec
+
+const unsigned int MESSAGE_DISPLAY_TIME = 3000; // in msec
+const unsigned int MESSAGE_TRANSITION_TIME = 200; // in msec
+
+Scrooby::Sprite* CGuiScreenHud::s_numCoinsDisplay = NULL;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+MessageQueue::MessageQueue()
+: m_front( 0 ),
+ m_back( 0 ),
+ m_isEmpty( true ),
+ m_isFull( false )
+{
+}
+
+MessageQueue::~MessageQueue()
+{
+}
+
+void
+MessageQueue::Enqueue( unsigned int messageID )
+{
+ rAssertMsg( !m_isFull, "Queue is full!" );
+
+ m_messages[ m_back ] = messageID;
+ m_back = (m_back + 1) % MESSAGE_QUEUE_CAPACITY;
+
+ m_isEmpty = false;
+ m_isFull = (m_front == m_back);
+}
+
+unsigned int
+MessageQueue::Dequeue()
+{
+ // assumes queue is not empty
+ //
+ rAssertMsg( !m_isEmpty, "Queue is empty!" );
+
+ unsigned int messageID = m_messages[ m_front ];
+ m_front = (m_front + 1) % MESSAGE_QUEUE_CAPACITY;
+
+ m_isEmpty = (m_front == m_back);
+ m_isFull = false;
+
+ return messageID;
+}
+
+void
+MessageQueue::Clear()
+{
+ m_front = 0;
+ m_back = 0;
+ m_isEmpty = true;
+ m_isFull= false;
+}
+
+//===========================================================================
+// CGuiScreenHud::CGuiScreenHud
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenHud::CGuiScreenHud
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreenMultiHud( pScreen, pParent, GUI_SCREEN_ID_HUD, 1 ),
+ m_missionOverlays( NULL ),
+ m_helpMessage( NULL ),
+ m_messageBox( NULL ),
+ m_actionButton( NULL ),
+ m_missionComplete( NULL ),
+ m_timer( NULL ),
+ m_defaultTimerColour( 255, 255, 255 ),
+ m_timerBlinkingStartTime( 10000 ),
+ m_timerBlinkingEndTime( 0 ),
+ m_parTime( NULL ),
+ m_collectibles( NULL ),
+ m_collectiblesUpdated( 0 ),
+ m_position( NULL ),
+ m_positionOrdinal( NULL ),
+ m_lap( NULL ),
+ m_lapUpdated( 0 ),
+ m_isSlidingDamageMeter( false ),
+ m_isFadingInRadar( false ),
+ m_isFadingOutRadar( false ),
+ m_hnrLights( NULL ),
+ m_hnrMeter( NULL ),
+ m_hnrMeterBgd( NULL ),
+ m_hnrElapsedTime( 0 ),
+ m_isFadingIn( false ),
+ m_isFadingOut( false ),
+ m_elapsedFadeTime( 0.0f ),
+ m_isBonusMissionJustCompleted( false ),
+ m_isAvatarOffRoad( false ),
+ m_avatarOffRoadDurationTime( 0 ),
+ m_pGetOutOfCarCondition( NULL ),
+ m_elapsedFgdFadeInTime( -1.0f )
+{
+MEMTRACK_PUSH_GROUP( "CGUIScreenHud" );
+ memset( m_overlays, 0, sizeof( m_overlays ) );
+ memset( m_hudEventHandlers, 0, sizeof( m_hudEventHandlers ) );
+ memset( m_hnrSectors, 0, sizeof( m_hnrSectors ) );
+
+ int i = 0;
+/*
+ bool enableFadeIn = (GetGameFlow()->GetCurrentContext() == CONTEXT_LOADING_GAMEPLAY );
+ this->SetFadingEnabled( enableFadeIn );
+*/
+ this->SetFadingEnabled( false );
+
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Hud" );
+ rAssert( pPage != NULL );
+
+ // Get dynamic elements
+ this->RetrieveElements( pPage );
+
+ m_missionOverlays = pPage->GetGroup( "MissionOverlays" );
+ rAssert( m_missionOverlays != NULL );
+
+ Scrooby::Group* pGroup = NULL;
+
+ // Retrieve HUD overlays
+ //
+ pGroup = m_missionOverlays->GetGroup( "Timer" );
+ rAssert( pGroup != NULL );
+ m_overlays[ HUD_TIMER ] = pGroup;
+ m_overlays[ HUD_TIMER_TEMP ] = pGroup;
+ m_timer = pGroup->GetSprite( "Timer" );
+ rAssert( m_timer != NULL );
+ m_timer->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT );
+ m_timer->CreateBitmapTextBuffer( BITMAP_TEXT_BUFFER_SIZE );
+ m_timer->SetBitmapTextSpacing( NUMERIC_TEXT_SPACING );
+ m_defaultTimerColour = m_timer->GetColour();
+#ifdef RAD_WIN32
+ m_timer->Translate( -25, 0 );
+ m_timer->ScaleAboutCenter( 0.5f );
+#endif
+
+ pGroup = m_missionOverlays->GetGroup( "ParTime" );
+ rAssert( pGroup != NULL );
+ m_overlays[ HUD_PAR_TIME ] = pGroup;
+ m_parTime = pGroup->GetSprite( "ParTime" );
+ rAssert( m_parTime != NULL );
+ m_parTime->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT );
+ m_parTime->CreateBitmapTextBuffer( BITMAP_TEXT_BUFFER_SIZE );
+ m_parTime->SetBitmapTextSpacing( NUMERIC_TEXT_SPACING );
+#ifdef RAD_WIN32
+ m_parTime->Translate( -25, 0 );
+ m_parTime->ScaleAboutCenter( 0.5f );
+#endif
+
+ pGroup = m_missionOverlays->GetGroup( "Collectibles" );
+ rAssert( pGroup != NULL );
+ m_overlays[ HUD_COLLECTIBLES ] = pGroup;
+ m_collectibles = pGroup->GetSprite( "Collectibles" );
+ rAssert( m_collectibles != NULL );
+ m_collectibles->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT );
+ m_collectibles->CreateBitmapTextBuffer( BITMAP_TEXT_BUFFER_SIZE );
+ m_collectibles->SetBitmapTextSpacing( NUMERIC_TEXT_SPACING );
+#ifdef RAD_WIN32
+ m_collectibles->Translate( -25, 0 );
+ m_collectibles->ScaleAboutCenter( 0.5f );
+#endif
+
+ pGroup = m_missionOverlays->GetGroup( "Position" );
+ rAssert( pGroup != NULL );
+ m_overlays[ HUD_RACE_POSITION ] = pGroup;
+ m_positionOrdinal = pGroup->GetText( "PositionOrdinal" );
+ m_position = pGroup->GetSprite( "Position" );
+ rAssert( m_position != NULL );
+ m_position->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT );
+ m_position->CreateBitmapTextBuffer( BITMAP_TEXT_BUFFER_SIZE );
+ m_position->SetBitmapTextSpacing( NUMERIC_TEXT_SPACING );
+#ifdef RAD_WIN32
+ m_position->Translate( -25, 0 );
+ m_position->ScaleAboutCenter( 0.5f );
+#endif
+
+ pGroup = m_missionOverlays->GetGroup( "Lap" );
+ rAssert( pGroup != NULL );
+ m_overlays[ HUD_LAP_COUNTER ] = pGroup;
+ m_lap = pGroup->GetSprite( "Lap" );
+ rAssert( m_lap != NULL );
+ m_lap->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT );
+ m_lap->CreateBitmapTextBuffer( BITMAP_TEXT_BUFFER_SIZE );
+ m_lap->SetBitmapTextSpacing( NUMERIC_TEXT_SPACING );
+#ifdef RAD_WIN32
+ m_lap->Translate( -25, 0 );
+ m_lap->ScaleAboutCenter( 0.5f );
+#endif
+
+ pGroup = m_missionOverlays->GetGroup( "DamageMeter" );
+ rAssert( pGroup != NULL );
+ m_overlays[ HUD_DAMAGE_METER ] = pGroup;
+ m_damageMeter.SetScroobyImage( pGroup->GetSprite( "DamageBar" ) );
+
+ pGroup = m_missionOverlays->GetGroup( "ProximityMeter" );
+ rAssert( pGroup != NULL );
+ m_overlays[ HUD_PROXIMITY_METER ] = pGroup;
+ m_proximityMeter.SetScroobyImage( pGroup->GetSprite( "ProximityBar" ) );
+
+ pGroup = m_missionOverlays->GetGroup( "MissionComplete" );
+ rAssert( pGroup != NULL );
+ m_overlays[ HUD_MISSION_COMPLETE ] = pGroup;
+
+ // get 'mission complete' text
+ //
+ m_missionComplete = pGroup->GetSprite( "MissionComplete" );
+ rAssert( m_missionComplete != NULL );
+ m_missionComplete->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT );
+ m_missionComplete->CreateBitmapTextBuffer( 256 );
+ m_missionComplete->SetBitmapText( GetTextBibleString( "MISSION_COMPLETE" ) );
+ m_missionComplete->SetBitmapTextLineSpacing( 10 );
+
+ // get 'mission failed' text
+ //
+ m_missionFailedSprite = pGroup->GetSprite( "MissionFailed" );
+ rAssert( m_missionFailedSprite != NULL );
+ m_missionFailedSprite->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT );
+ m_missionFailedSprite->CreateBitmapTextBuffer( 256 );
+ m_missionFailedSprite->SetBitmapText( GetTextBibleString( "MISSION_FAILED" ) );
+ m_missionFailedSprite->SetBitmapTextLineSpacing( 10 );
+#ifdef RAD_WIN32
+ m_missionFailedSprite->ScaleAboutCenter( 0.5f );
+#endif
+
+ pGroup = pPage->GetGroup( "HudMap0" );
+ rAssert( pGroup != NULL );
+ m_overlays[ HUD_MAP ] = pGroup;
+
+ // scale entire HUD map (or RADAR, if you'd prefer to call it that)
+ //
+ m_overlays[ HUD_MAP ]->ResetTransformation();
+ m_overlays[ HUD_MAP ]->ScaleAboutCenter( RADAR_SCALE );
+
+ Scrooby::Group* pGroupHNR = pGroup->GetGroup( "HitNRunMeter" );
+ if( pGroupHNR != NULL )
+ {
+ for( i = 0; i < NUM_HIT_N_RUN_SECTORS; i++ )
+ {
+ char name[ 16 ];
+ sprintf( name, "HnRSector%d", i );
+ m_hnrSectors[ i ] = pGroupHNR->GetSprite( name );
+
+// rAssert( m_hnrSectors[ i ] != NULL );
+// m_hnrSectors[ i ]->SetColour( HNR_METER_EMPTY_COLOUR );
+
+ }
+
+ m_hnrLights = pGroupHNR->GetSprite( "HitNRun" );
+ m_hnrMeter = pGroupHNR->GetSprite( "HnRMeter" );
+ m_hnrMeterBgd = pGroupHNR->GetSprite( "HnRMeterBgd" );
+ }
+
+ pGroup = pPage->GetGroup( "Message" );
+ rAssert( pGroup != NULL );
+ m_overlays[ HUD_MESSAGE ] = pGroup;
+ m_helpMessage = pGroup->GetText( "Message" );
+ rAssert( m_helpMessage != NULL );
+ m_helpMessage->SetTextMode( Scrooby::TEXT_WRAP );
+ m_helpMessage->ResetTransformation();
+ m_helpMessage->Translate( 0, MESSAGE_TEXT_VERTICAL_TRANSLATION );
+ m_helpMessage->ScaleAboutPoint( MESSAGE_TEXT_SCALE * MESSGAE_TEXT_HORIZONTAL_STRETCH,
+ MESSAGE_TEXT_SCALE,
+ 1.0f, 0, 0 );
+
+ m_messageBox = pGroup->GetSprite( "MessageBox" );
+ rAssert( m_messageBox != NULL );
+ m_messageBox->ResetTransformation();
+ m_messageBox->ScaleAboutCenter( MESSAGE_BOX_CORRECTION_SCALE * MESSAGE_BOX_HORIZONTAL_STRETCH,
+ MESSAGE_BOX_CORRECTION_SCALE * MESSAGE_BOX_VERTICAL_STRETCH,
+ 1.0f );
+
+ pGroup = pPage->GetGroup( "ActionButton" );
+ rAssert( pGroup != NULL );
+ m_overlays[ HUD_ACTION_BUTTON ] = pGroup;
+#ifdef RAD_WIN32
+ m_actionButton = pGroup->GetText( "ActionTextButton" );
+ m_actionLabel = pGroup->GetText( "ActionTextLabel" );
+#else
+ m_actionButton = pGroup->GetSprite( "ActionButton" );
+#endif
+
+ // hide all HUD overlays by default
+ //
+ for( i = 0; i < NUM_HUD_OVERLAYS; i++ )
+ {
+ if( i == NUM_HUD_MISSION_OVERLAYS )
+ {
+ continue;
+ }
+
+ rAssert( m_overlays[ i ] );
+ m_overlays[ i ]->SetVisible( false );
+
+ m_elapsedTime[ i ] = 0;
+ }
+
+ Mission* currentMission = GetGameplayManager()->GetCurrentMission();
+ if( currentMission != NULL )
+ {
+ this->SetVisible( currentMission->IsHUDVisible() );
+ }
+
+ // create HUD event handlers
+ //
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_CARD_COLLECTED ] = new HudCardCollected( pPage );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_COIN_COLLECTED ] = new HudCoinCollected( pPage );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_MISSION_PROGRESS ] = new HudMissionProgress( pPage );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_MISSION_OBJECTIVE ] = new HudMissionObjective( pPage );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_COUNTDOWN ] = new HudCountDown( pPage );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_HIT_N_RUN ] = new HudHitNRun( pPage );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_WASP_DESTROYED ] = new HudWaspDestroyed( pPage );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_ITEM_DROPPED ] = new HudItemDropped( pPage );
+
+ // register event listeners
+ //
+ GetEventManager()->AddListener( this, EVENT_CARD_COLLECTED );
+ GetEventManager()->AddListener( this, EVENT_COLLECTED_COINS );
+ GetEventManager()->AddListener( this, EVENT_LOST_COINS );
+ GetEventManager()->AddListener( this, EVENT_STAGE_COMPLETE );
+ GetEventManager()->AddListener( this, EVENT_SHOW_MISSION_OBJECTIVE );
+ GetEventManager()->AddListener( this, EVENT_GUI_COUNTDOWN_START );
+ GetEventManager()->AddListener( this, EVENT_HIT_AND_RUN_START );
+ GetEventManager()->AddListener( this, EVENT_HIT_AND_RUN_CAUGHT );
+ GetEventManager()->AddListener( this, EVENT_GAMBLERACE_SUCCESS );
+ GetEventManager()->AddListener( this, EVENT_GAMBLERACE_FAILURE );
+ GetEventManager()->AddListener( this, EVENT_WASP_BLOWED_UP );
+ GetEventManager()->AddListener( this, EVENT_GAG_FOUND );
+ GetEventManager()->AddListener( this, EVENT_DUMP_STATUS );
+ GetEventManager()->AddListener( this, EVENT_AVATAR_ON_ROAD );
+ GetEventManager()->AddListener( this, EVENT_AVATAR_OFF_ROAD );
+ GetEventManager()->AddListener( this, EVENT_OUTOFCAR_CONDITION_ACTIVE );
+ GetEventManager()->AddListener( this, EVENT_OUTOFCAR_CONDITION_INACTIVE );
+
+MEMTRACK_POP_GROUP("CGUIScreenHud");
+}
+
+
+//===========================================================================
+// CGuiScreenHud::~CGuiScreenHud
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenHud::~CGuiScreenHud()
+{
+ // destroy hud event handlers
+ //
+ for( int i = 0; i < NUM_HUD_EVENT_HANDLERS; i++ )
+ {
+ if( m_hudEventHandlers[ i ] != NULL )
+ {
+ // stop them first in case they're still in progress
+ //
+ m_hudEventHandlers[ i ]->Stop();
+
+ delete m_hudEventHandlers[ i ];
+ m_hudEventHandlers[ i ] = NULL;
+ }
+ }
+
+ // unregister event listeners
+ //
+ GetEventManager()->RemoveAll( this );
+
+ s_numCoinsDisplay = NULL;
+}
+
+
+//===========================================================================
+// CGuiScreenHud::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( message == GUI_MSG_MENU_PROMPT_RESPONSE )
+ {
+ m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME );
+ }
+
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ this->Update( param1 );
+
+ break;
+ }
+ case GUI_MSG_SHOW_HUD_OVERLAY:
+ {
+ if( param1 == HUD_TIMER_TEMP && m_overlays[ HUD_TIMER ]->IsVisible() )
+ {
+ // ignore, cuz these are both the same overlay
+ //
+ break;
+ }
+
+ // follow-through
+ //
+ }
+ case GUI_MSG_HIDE_HUD_OVERLAY:
+ {
+ rAssert( param1 < NUM_HUD_OVERLAYS );
+ rAssert( m_overlays[ param1 ] != NULL );
+
+ // show/hide HUD overlay
+ //
+ m_overlays[ param1 ]->SetVisible( message == GUI_MSG_SHOW_HUD_OVERLAY );
+ m_elapsedTime[ param1 ] = 0;
+
+ rAssertMsg( param1 != HUD_MESSAGE, "Call CGuiScreenHud::DisplayMessage() instead!" );
+
+ // for mission-related overlays
+ //
+ if( message == GUI_MSG_SHOW_HUD_OVERLAY &&
+ this->IsMissionOverlay( param1 ) )
+ {
+ const float SECONDARY_MISSION_OVERLAY_SCALE = 0.75f;
+ const int SECONDARY_MISSION_OVERLAY_OFFSET_Y = -45;
+
+ m_overlays[ param1 ]->ResetTransformation();
+
+ unsigned int otherOverlayIndex = 0;
+ int numOverlaysEnabled = 0;
+
+ for( unsigned int i = 0; this->IsMissionOverlay( i ); i++ )
+ {
+ if( m_overlays[ i ]->IsVisible() && m_overlays[ i ] != m_overlays[ param1 ] )
+ {
+ otherOverlayIndex = i;
+ numOverlaysEnabled++;
+ }
+ }
+
+ if( numOverlaysEnabled >= 2 )
+ {
+ rAssertMsg( numOverlaysEnabled == 2, "More than two is not handled properly yet!" );
+
+ // if already two overlays enabled, just push this new one down as the third one
+ // w/out re-ordering anything
+ //
+ m_overlays[ param1 ]->ScaleAboutPoint( SECONDARY_MISSION_OVERLAY_SCALE, 0, 0 );
+ m_overlays[ param1 ]->Translate( 0, SECONDARY_MISSION_OVERLAY_OFFSET_Y * 2 );
+ }
+ else if( numOverlaysEnabled == 1 )
+ {
+ // already another mission overlay enabled, need to
+ // scale and translate the secondary one
+ //
+ unsigned int secondaryOverlay = rmt::Max( otherOverlayIndex, param1 );
+
+ m_overlays[ secondaryOverlay ]->ResetTransformation();
+ m_overlays[ secondaryOverlay ]->ScaleAboutPoint( SECONDARY_MISSION_OVERLAY_SCALE, 0, 0 );
+ m_overlays[ secondaryOverlay ]->Translate( 0, SECONDARY_MISSION_OVERLAY_OFFSET_Y );
+ }
+ }
+
+ // special cases
+ //
+ if( param1 == HUD_PROXIMITY_METER )
+ {
+ rAssert( m_proximityMeter.m_pImage != NULL );
+ if( param2 == 0 ) // 0 = red bar
+ {
+ m_proximityMeter.m_pImage->SetColour( PROXIMITY_METER_RED );
+ }
+ else // 1 = green bar
+ {
+ m_proximityMeter.m_pImage->SetColour( PROXIMITY_METER_GREEN );
+ }
+ }
+ else if( param1 == HUD_MISSION_COMPLETE )
+ {
+ m_isBonusMissionJustCompleted = false;
+
+ Mission* currentMission = GetGameplayManager()->GetCurrentMission();
+ rAssert( currentMission != NULL );
+ if( !currentMission->IsWagerMission() ) // not a wager race
+ {
+ if( currentMission->IsBonusMission() )
+ {
+ rAssert( m_missionComplete != NULL );
+ m_missionComplete->SetBitmapText( GetTextBibleString( "BONUS_MISSION_COMPLETE" ) );
+
+ m_isBonusMissionJustCompleted = true;
+ }
+ else
+ {
+ rAssert( m_missionComplete != NULL );
+ m_missionComplete->SetBitmapText( GetTextBibleString( "MISSION_COMPLETE" ) );
+ }
+ }
+ }
+ else if( param1 == HUD_LAP_COUNTER )
+ {
+ m_lapUpdated = 0;
+ }
+/*
+ else if( param1 == HUD_MAP )
+ {
+ if( param2 != 0 ) // != 0 means w/ fading
+ {
+ if( message == GUI_MSG_SHOW_HUD_OVERLAY )
+ {
+ m_isFadingInRadar = true;
+ m_isFadingOutRadar = false;
+ }
+ else
+ {
+ m_isFadingOutRadar = true;
+ m_isFadingInRadar = false;
+
+ // wait for fade out transition to finish
+ // before turning off radar
+ //
+ m_overlays[ HUD_MAP ]->SetVisible( true );
+ }
+ }
+ }
+ else if( param1 == HUD_DAMAGE_METER )
+ {
+ m_isSlidingDamageMeter = (message == GUI_MSG_SHOW_HUD_OVERLAY);
+ }
+*/
+
+ break;
+ }
+ case GUI_MSG_INGAME_FADE_OUT:
+ {
+ if( !m_isFadingOut )
+ {
+ rAssertMsg( !m_isFadingIn, "Fade in currently in progress!" );
+
+ m_isFadingOut = true;
+ m_elapsedFadeTime = 0.0f;
+ ++m_numTransitionsPending;
+ }
+ else
+ {
+ rWarningMsg( false, "Fade out currently in progress! Ignoring redundant request." );
+ }
+
+ break;
+ }
+ case GUI_MSG_INGAME_FADE_IN:
+ {
+ if( !m_isFadingIn )
+ {
+ rAssertMsg( !m_isFadingOut, "Fade out currently in progress!" );
+ ++m_numTransitionsPending;
+ m_isFadingIn = true;
+ m_elapsedFadeTime = 0.0f;
+ }
+ else
+ {
+ rWarningMsg( false, "Fade in currently in progress! Ignoring redundant request." );
+ }
+
+ break;
+ }
+ case GUI_MSG_INGAME_FADE_OUT_CANCEL:
+ {
+ if( m_isFadingOut )
+ {
+ rAssert( m_screenCover != NULL );
+ m_screenCover->SetAlpha( 1.0f );
+
+ m_isFadingOut = false;
+ --m_numTransitionsPending;
+
+ GetEventManager()->TriggerEvent( EVENT_GUI_FADE_OUT_DONE );
+ }
+
+ break;
+ }
+ case GUI_MSG_INGAME_FADE_IN_CANCEL:
+ {
+ if( m_isFadingIn )
+ {
+ rAssert( m_screenCover != NULL );
+ m_screenCover->SetAlpha( 0.0f );
+
+ m_isFadingIn = false;
+ --m_numTransitionsPending;
+
+ GetEventManager()->TriggerEvent( EVENT_GUI_FADE_IN_DONE );
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_START:
+ {
+ if( m_screenCover != NULL && m_screenCover->GetAlpha() > 0.0f )
+ {
+ // don't allow pausing during fade in/out
+ //
+ return;
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreenMultiHud::HandleMessage( message, param1, param2 );
+}
+
+//===========================================================================
+// CGuiScreenHud::Update
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: elapsed time
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::Update( unsigned int elapsedTime )
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ if( m_elapsedFgdFadeInTime != -1.0f )
+ {
+ // fade in entire HUD foreground layer(s) to prevent sudden flashes
+ // on screen during situations where the HUD gets displayed very
+ // briefly before transitioning out to another screen
+ //
+ const float HUD_FGD_FADE_IN_TIME = 100.0f;
+
+ m_elapsedFgdFadeInTime += elapsedTime;
+ if( m_elapsedFgdFadeInTime < HUD_FGD_FADE_IN_TIME )
+ {
+// float alpha = m_elapsedFgdFadeInTime / HUD_FGD_FADE_IN_TIME;
+ this->SetAlphaForLayers( 0.0f, m_foregroundLayers, m_numForegroundLayers );
+ }
+ else
+ {
+ this->SetAlphaForLayers( 1.0f, m_foregroundLayers, m_numForegroundLayers );
+
+ rAssert( m_overlays[ HUD_MAP ] != NULL );
+ m_overlays[ HUD_MAP ]->SetAlpha( 1.0f );
+
+ rAssert( m_hudMap[ 0 ] != NULL );
+ m_hudMap[ 0 ]->SetVisible( GetGuiSystem()->IsRadarEnabled() );
+
+ m_elapsedFgdFadeInTime = -1.0f; // fade in is done
+ }
+ }
+ else
+ {
+ rAssert( m_hudMap[ 0 ] != NULL );
+ m_hudMap[ 0 ]->SetVisible( GetGuiSystem()->IsRadarEnabled() );
+ }
+ }
+
+ static float INGAME_FADE_TIME = 250.0f; // in msec
+
+ if( m_isFadingOut )
+ {
+ rAssert( m_screenCover != NULL );
+
+ m_elapsedFadeTime += (float)elapsedTime;
+ if( m_elapsedFadeTime < INGAME_FADE_TIME )
+ {
+ m_screenCover->SetAlpha( m_elapsedFadeTime / INGAME_FADE_TIME );
+ }
+ else
+ {
+ m_screenCover->SetAlpha( 1.0f );
+
+ --m_numTransitionsPending;
+ m_isFadingOut = false;
+
+ GetEventManager()->TriggerEvent( EVENT_GUI_FADE_OUT_DONE );
+ }
+ }
+
+ if( m_isFadingIn )
+ {
+ rAssert( m_screenCover != NULL );
+
+ m_elapsedFadeTime += (float)elapsedTime;
+ if( m_elapsedFadeTime < INGAME_FADE_TIME )
+ {
+ m_screenCover->SetAlpha( 1.0f - m_elapsedFadeTime / INGAME_FADE_TIME );
+ }
+ else
+ {
+ m_screenCover->SetAlpha( 0.0f );
+
+ --m_numTransitionsPending;
+ m_isFadingIn = false;
+
+ GetEventManager()->TriggerEvent( EVENT_GUI_FADE_IN_DONE );
+ }
+ }
+
+ this->UpdateOverlays( elapsedTime );
+ this->UpdateEventHandlers( elapsedTime );
+ this->UpdateTutorialMode( static_cast<float>( elapsedTime ) );
+
+#ifdef SRR2_MOVABLE_HUD_MAP
+ this->UpdateHudMapPosition( elapsedTime );
+#endif
+
+/*
+ // TC: *** testing only ***
+ //
+ static float s_elapsedTime = 0.0f;
+ s_elapsedTime += static_cast<float>( elapsedTime );
+ float value = 0.5f * rmt::Sin( rmt::PI_2 * s_elapsedTime / 2000.0f ) + 0.5f;
+ this->SetHitAndRunMeter( value );
+*/
+ HitnRunManager* hnrManager = GetHitnRunManager();
+ rAssert( hnrManager != NULL );
+
+ // blink H&R Meter lights
+ //
+ const unsigned int HNR_BLINK_PERIOD = 500;
+
+ rAssert( m_hnrLights != NULL );
+ rAssert( m_hnrMeterBgd != NULL );
+ if( hnrManager->IsHitnRunActive() )
+ {
+ m_hnrMeterBgd->SetColour( tColour( 17, 31, 161 ) );
+ }
+ else
+ {
+ m_hnrMeterBgd->SetColour( tColour( 0, 0, 0 ) );
+
+ m_hnrLights->SetIndex( 2 ); // 2 = lights off
+ }
+
+ m_hnrElapsedTime += elapsedTime;
+ if( m_hnrElapsedTime > HNR_BLINK_PERIOD / 2 )
+ {
+ if( hnrManager->IsHitnRunActive() )
+ {
+ int currentIndex = m_hnrLights->GetIndex();
+ m_hnrLights->SetIndex( currentIndex > 1 ? 0 : 1 - currentIndex );
+
+ rAssert( m_hnrMeter != NULL );
+ m_hnrMeter->SetVisible( !m_hnrMeter->IsVisible() );
+ }
+ else if( (hnrManager->GetHitnRunValue() / 100.0f) > HNR_METER_BLINKING_THRESHOLD )
+ {
+ rAssert( m_hnrMeter != NULL );
+ m_hnrMeter->SetVisible( !m_hnrMeter->IsVisible() );
+
+ // TC: [TODO] throw a sound event to go w/ this
+ //
+ }
+
+ m_hnrElapsedTime %= HNR_BLINK_PERIOD / 2;
+ }
+
+ if( m_isAvatarOffRoad )
+ {
+ // update avatar off-road duration time
+ //
+ m_avatarOffRoadDurationTime += elapsedTime;
+ }
+}
+
+//===========================================================================
+// CGuiScreenHud::SetVisible
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::SetVisible( bool isVisible )
+{
+ rAssert( m_pScroobyScreen != NULL );
+
+ // for each page in screen
+ //
+ int numPages = m_pScroobyScreen->GetNumberOfPages();
+ for( int i = 0; i < numPages; i++ )
+ {
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPageByIndex( i );
+ rAssert( pPage != NULL );
+
+ // for each layer in page
+ //
+ int numLayers = pPage->GetNumberOfLayers();
+ for( int j = 0; j < numLayers; j++ )
+ {
+ Scrooby::Layer* pLayer = pPage->GetLayerByIndex( j );
+ rAssert( pLayer );
+
+ pLayer->SetVisible( isVisible );
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenHud::SetTimerBlinkingInterval
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::SetTimerBlinkingInterval( int startTime, int endTime )
+{
+ m_timerBlinkingStartTime = startTime;
+ m_timerBlinkingEndTime = endTime;
+}
+
+
+//===========================================================================
+// CGuiScreenHud::SetParTime
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::SetParTime( int parTime ) // in seconds
+{
+ char buffer[ BITMAP_TEXT_BUFFER_SIZE ];
+
+ sprintf( buffer, "%d:%02d", parTime / 60, parTime % 60 );
+
+ rAssert( m_parTime != NULL );
+ m_parTime->SetBitmapText( buffer );
+}
+
+
+//===========================================================================
+// CGuiScreenHud::SetCollectibles
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::SetCollectibles( int numCollected, int numToCollect )
+{
+// rAssert( m_collectibles != NULL );
+// m_collectibles->SetVisible( numToCollect > 1 ); // only show collectibles if more than 1 to collect
+
+ char buffer[ BITMAP_TEXT_BUFFER_SIZE ];
+ sprintf( buffer, "%d/%d", numCollected, numToCollect );
+
+ m_collectibles->SetBitmapText( buffer );
+/*
+ m_playerCollected.SetValue( numCollected );
+ m_numToCollect.SetValue( numToCollect );
+*/
+ if( numCollected > 0 )
+ {
+ m_collectiblesUpdated = 1;
+
+ m_elapsedTime[ HUD_COLLECTIBLES ] = 0;
+
+ // TC [TODO]: play sound effect
+ //
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenHud::SetRacePosition
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::SetRacePosition( int currentPosition, int numPositions )
+{
+ char buffer[ BITMAP_TEXT_BUFFER_SIZE ];
+
+ // extra spaces are needed to make more room for the ordinal text
+ //
+ char extraSpaces[ 4 ];
+ strcpy( extraSpaces, " " );
+
+#ifdef PAL
+ if( CGuiTextBible::GetCurrentLanguage() != Scrooby::XL_ENGLISH )
+ {
+ extraSpaces[ 0 ] = '\0';
+ }
+#endif // PAL
+
+ if( m_isAvatarOffRoad && m_avatarOffRoadDurationTime > MIN_AVATAR_OFF_ROAD_TIME )
+ {
+ sprintf( buffer, "?%s/%d", extraSpaces, numPositions );
+ m_positionOrdinal->SetVisible( false );
+ }
+ else
+ {
+ sprintf( buffer, "%d%s/%d", currentPosition, extraSpaces, numPositions );
+ m_positionOrdinal->SetVisible( true );
+ }
+
+ rAssert( m_position != NULL );
+ m_position->SetBitmapText( buffer );
+/*
+ m_currentPosition.SetValue( currentPosition );
+ m_numPositions.SetValue( numPositions );
+*/
+ m_positionOrdinal->SetIndex( currentPosition > 3 ? 3 : currentPosition - 1 );
+}
+
+
+//===========================================================================
+// CGuiScreenHud::SetLap
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::SetLap( int currentLap, int numLaps )
+{
+ char buffer[ BITMAP_TEXT_BUFFER_SIZE ];
+ sprintf( buffer, "%d/%d", currentLap, numLaps );
+
+ rAssert( m_lap != NULL );
+ m_lap->SetBitmapText( buffer );
+/*
+ m_currentLap.SetValue( currentLap );
+ m_numLaps.SetValue( numLaps );
+*/
+ if( currentLap > 1 )
+ {
+ m_lapUpdated = 8;
+
+ m_elapsedTime[ HUD_LAP_COUNTER ] = 0;
+
+ // play sound effect
+ //
+ GetEventManager()->TriggerEvent( EVENT_HUD_LAP_UPDATED );
+ }
+ else
+ {
+ m_lapUpdated = 0;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenHud::SetDamageMeter
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::SetDamageMeter( float value )
+{
+ m_damageMeter.SetValue( value );
+}
+
+
+//===========================================================================
+// CGuiScreenHud::SetProximityMeter
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::SetProximityMeter( float value )
+{
+ m_proximityMeter.SetValue( value );
+}
+
+
+//===========================================================================
+// CGuiScreenHud::SetHitAndRunMeter
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::SetHitAndRunMeter( float value )
+{
+ rAssert( value >= 0.0f && value <= 1.0f );
+
+ rAssert( m_hnrMeter != NULL );
+ if( value > HNR_METER_BLINKING_THRESHOLD || GetHitnRunManager()->IsHitnRunActive() )
+ {
+ m_hnrMeter->SetColour( HNR_METER_WARNING_COLOUR );
+ }
+ else
+ {
+ m_hnrMeter->SetColour( HNR_METER_DEFAULT_COLOUR ); // restore default colour
+ m_hnrMeter->SetVisible( true );
+ }
+
+ const float TOTAL_AMOUNT_COVERED = 1.0f - value;
+ const float SECTOR_AMOUNT = 1.0f / NUM_HIT_N_RUN_SECTORS;
+ const float TOTAL_ANGLE = (1.0f - 1 / (float)NUM_HIT_N_RUN_SECTORS) * 360.0f;
+
+ float amountCovered = 0.0f;
+
+ for( int i = 0; i < NUM_HIT_N_RUN_SECTORS; i++ )
+ {
+ rAssert( m_hnrSectors[ i ] != NULL );
+ m_hnrSectors[ i ]->ResetTransformation();
+
+ if( amountCovered < TOTAL_AMOUNT_COVERED )
+ {
+ float currentCovered = TOTAL_AMOUNT_COVERED - amountCovered;
+ if( currentCovered > SECTOR_AMOUNT )
+ {
+ currentCovered = SECTOR_AMOUNT;
+ }
+
+ amountCovered += currentCovered;
+
+ m_hnrSectors[ i ]->RotateAboutCenter( -amountCovered * TOTAL_ANGLE );
+
+ static float correctionScale = 1.02f;
+ m_hnrSectors[ i ]->ScaleAboutCenter( correctionScale );
+/*
+#ifdef RAD_DEBUG
+ static tColour sectorColour( HNR_METER_EMPTY_COLOUR );
+ m_hnrSectors[ i ]->SetColour( sectorColour );
+#endif
+*/
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenHud::DisplayMessage
+//===========================================================================
+// Description: adds some scrolling text to the queue of text to show
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::DisplayMessage( bool show, const int index )
+{
+ rAssert( m_overlays[ HUD_MESSAGE ] != NULL );
+
+ if( show )
+ {
+ if( !m_helpMessageQueue.IsEmpty() )
+ {
+ m_helpMessageQueue.Enqueue( index );
+ }
+ else
+ {
+ if( m_overlays[ HUD_MESSAGE ]->IsVisible() )
+ {
+ if( m_elapsedTime[ HUD_MESSAGE ] > MESSAGE_DISPLAY_TIME - MESSAGE_TRANSITION_TIME )
+ {
+ m_elapsedTime[ HUD_MESSAGE ] = MESSAGE_DISPLAY_TIME - m_elapsedTime[ HUD_MESSAGE ];
+ }
+ else if( m_elapsedTime[ HUD_MESSAGE ] > MESSAGE_TRANSITION_TIME )
+ {
+ m_elapsedTime[ HUD_MESSAGE ] = MESSAGE_TRANSITION_TIME;
+ }
+ }
+ else
+ {
+ m_overlays[ HUD_MESSAGE ]->SetVisible( true );
+ m_overlays[ HUD_MESSAGE ]->ScaleAboutCenter( 0.0f );
+ m_elapsedTime[ HUD_MESSAGE ] = 0;
+ }
+
+ rAssert( index >= 0 );
+ m_helpMessage->SetIndex( index );
+ }
+ }
+ else
+ {
+ m_overlays[ HUD_MESSAGE ]->SetVisible( false );
+ }
+}
+
+
+void
+CGuiScreenHud::DisplayMissionOverlays( bool show )
+{
+ rAssert( m_missionOverlays != NULL );
+ m_missionOverlays->SetVisible( show );
+}
+
+
+void
+CGuiScreenHud::HandleEvent( EventEnum id, void* pEventData )
+{
+ switch( id )
+ {
+ case EVENT_CARD_COLLECTED:
+ {
+ // stop coin presentation in case it's currently active
+ //
+ rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_COIN_COLLECTED ] != NULL );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_COIN_COLLECTED ]->Stop();
+
+ rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_CARD_COLLECTED ] != NULL );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_CARD_COLLECTED ]->Start();
+
+ Card* collectedCard = reinterpret_cast<Card*>( pEventData );
+ rAssert( collectedCard != NULL );
+ HudCardCollected* hudCardCollected = static_cast<HudCardCollected*>( m_hudEventHandlers[ HUD_EVENT_HANDLER_CARD_COLLECTED ] );
+ hudCardCollected->SetCurrentCard( collectedCard->GetID() );
+
+ break;
+ }
+ case EVENT_COLLECTED_COINS:
+ case EVENT_LOST_COINS:
+ {
+ rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_CARD_COLLECTED ] != NULL );
+ if( !m_hudEventHandlers[ HUD_EVENT_HANDLER_CARD_COLLECTED ]->IsActive() )
+ {
+ // only show coin presentation if card presentation is not active
+ //
+ rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_COIN_COLLECTED ] != NULL );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_COIN_COLLECTED ]->Start();
+ }
+
+ break;
+ }
+ case EVENT_STAGE_COMPLETE:
+ {
+ unsigned int showStageComplete = reinterpret_cast<unsigned int>( pEventData );
+ if( showStageComplete > 0 )
+ {
+ rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_MISSION_PROGRESS ] != NULL );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_MISSION_PROGRESS ]->Start();
+ }
+
+ break;
+ }
+ case EVENT_SHOW_MISSION_OBJECTIVE:
+ {
+ int messageID = reinterpret_cast<unsigned int>( pEventData );
+
+ HudMissionObjective* hudMissionObjective = static_cast<HudMissionObjective*>( m_hudEventHandlers[ HUD_EVENT_HANDLER_MISSION_OBJECTIVE ] );
+ if( messageID != -1 )
+ {
+ rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_MISSION_OBJECTIVE ] != NULL );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_MISSION_OBJECTIVE ]->Start();
+
+// this->DisplayMessage( true, messageID );
+
+ hudMissionObjective->SetMessageID( messageID );
+ }
+ else
+ {
+ hudMissionObjective->UpdateIcon();
+ }
+
+ break;
+ }
+ case EVENT_GUI_COUNTDOWN_START:
+ {
+ rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_COUNTDOWN ] != NULL );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_COUNTDOWN ]->Start();
+
+ break;
+ }
+ case EVENT_HIT_AND_RUN_START:
+ case EVENT_HIT_AND_RUN_CAUGHT:
+ {
+ HudHitNRun* hudHitNRun = static_cast<HudHitNRun*>( m_hudEventHandlers[ HUD_EVENT_HANDLER_HIT_N_RUN] );
+ rAssert( hudHitNRun != NULL );
+ if( id == EVENT_HIT_AND_RUN_START )
+ {
+ hudHitNRun->SetMessage( HudHitNRun::MSG_HIT_N_RUN );
+ }
+ else
+ {
+ rAssert( id == EVENT_HIT_AND_RUN_CAUGHT );
+ hudHitNRun->SetMessage( HudHitNRun::MSG_BUSTED );
+ }
+
+ rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_HIT_N_RUN ] != NULL );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_HIT_N_RUN ]->Start();
+
+ break;
+ }
+ case EVENT_GAMBLERACE_SUCCESS: // (pEventData != 0) means new best time been set
+ {
+ if( pEventData != 0 )
+ {
+ // display "Congratulations! New Best Time!"
+ //
+ rAssert( m_missionComplete != NULL );
+ m_missionComplete->SetBitmapText( GetTextBibleString( "GAMBLING_RACE_SUCCESS_NBT" ) );
+ }
+ else
+ {
+ // display "Congratulations!"
+ //
+ rAssert( m_missionComplete != NULL );
+ m_missionComplete->SetBitmapText( GetTextBibleString( "GAMBLING_RACE_SUCCESS" ) );
+ }
+
+ break;
+ }
+ case EVENT_GAMBLERACE_FAILURE:
+ {
+ rAssert( m_missionComplete != NULL );
+ m_missionComplete->SetBitmapText( GetTextBibleString( "GAMBLING_RACE_FAILURE" ) );
+
+ break;
+ }
+ case EVENT_GAG_FOUND:
+ case EVENT_WASP_BLOWED_UP:
+ {
+ HudWaspDestroyed* hudWaspDestroyed = static_cast<HudWaspDestroyed*>( m_hudEventHandlers[ HUD_EVENT_HANDLER_WASP_DESTROYED] );
+ rAssert( hudWaspDestroyed != NULL );
+ hudWaspDestroyed->SetGagInsteadOfWasp( id == EVENT_GAG_FOUND );
+
+ rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_WASP_DESTROYED ] != NULL );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_WASP_DESTROYED ]->Start();
+
+ break;
+ }
+ case EVENT_DUMP_STATUS:
+ {
+ rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_ITEM_DROPPED ] != NULL );
+
+ int numActiveItems = reinterpret_cast<int>( pEventData );
+ if( numActiveItems > 0 )
+ {
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_ITEM_DROPPED ]->Start();
+ }
+ else
+ {
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_ITEM_DROPPED ]->Stop();
+ }
+
+ break;
+ }
+ case EVENT_AVATAR_ON_ROAD:
+ {
+ m_isAvatarOffRoad = false;
+
+ break;
+ }
+ case EVENT_AVATAR_OFF_ROAD:
+ {
+ if( !m_isAvatarOffRoad ) // if previously on-road
+ {
+ m_avatarOffRoadDurationTime = 0; // reset off-road duration time
+ }
+
+ m_isAvatarOffRoad = true;
+
+ break;
+ }
+ case EVENT_OUTOFCAR_CONDITION_ACTIVE:
+ {
+ m_pGetOutOfCarCondition = static_cast<GetOutOfCarCondition*> (pEventData);
+ rAssert(m_pGetOutOfCarCondition != NULL);
+
+ break;
+ }
+
+ case EVENT_OUTOFCAR_CONDITION_INACTIVE:
+ {
+ m_pGetOutOfCarCondition = NULL;
+
+ break;
+ }
+
+
+ default:
+ {
+ rWarningMsg( false, "Unhandled event caught by GUI HUD!" );
+
+ break;
+ }
+ }
+}
+
+void
+CGuiScreenHud::SetNumCoinsDisplay( Scrooby::Sprite* pSprite )
+{
+ if( s_numCoinsDisplay == NULL )
+ {
+ rAssert( pSprite != NULL );
+ pSprite->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT );
+ pSprite->CreateBitmapTextBuffer( MAX_NUM_COIN_DIGITS );
+ pSprite->SetBitmapTextSpacing( NUMERIC_TEXT_SPACING );
+ pSprite->SetVisible( false ); // hide by default
+
+#ifdef RAD_WIN32
+ pSprite->ResetTransformation();
+ pSprite->Translate( 70, 0 );
+ pSprite->ScaleAboutCenter( 0.5f );
+#endif
+
+ s_numCoinsDisplay = pSprite;
+ }
+}
+
+void
+CGuiScreenHud::UpdateNumCoinsDisplay( int numCoins, bool show )
+{
+ rAssert( s_numCoinsDisplay != NULL );
+ s_numCoinsDisplay->SetVisible( show );
+
+ static int coinPosX = CGuiScreen::IsWideScreenDisplay() ? 540 : 605;
+ static int coinPosY = 432;
+ GetCoinManager()->SetHUDCoin( coinPosX, coinPosY, show );
+
+ if( show )
+ {
+ char buffer[ MAX_NUM_COIN_DIGITS ];
+ sprintf( buffer, "%d", numCoins );
+ s_numCoinsDisplay->SetBitmapText( buffer );
+ }
+}
+
+//===========================================================================
+// CGuiScreenHud::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::InitIntro()
+{
+ Scrooby::Screen* screen = GetScroobyScreen();
+ screen->SetAlpha( 1.0f );
+
+ m_missionFailedSprite->SetVisible( false );
+
+/*
+ if( GetInteriorManager()->IsInside() )
+ {
+ this->HandleMessage( GUI_MSG_HIDE_HUD_OVERLAY, HUD_MAP );
+ }
+ else
+*/
+ {
+ this->HandleMessage( GUI_MSG_SHOW_HUD_OVERLAY, HUD_MAP );
+ }
+
+ // hide hud map, by default
+ //
+ m_overlays[ HUD_MAP ]->SetAlpha( 0.0f );
+ rAssert( m_hudMap[ 0 ] != NULL );
+ m_hudMap[ 0 ]->SetVisible( false );
+
+ this->SetAlphaForLayers( 0.0f, m_foregroundLayers, m_numForegroundLayers );
+
+ // force update on hit & run meter
+ //
+ HitnRunManager* hnrManager = GetHitnRunManager();
+ rAssert( hnrManager != NULL );
+ this->SetHitAndRunMeter( hnrManager->GetHitnRunValue() / 100.0f );
+
+ CGuiScreenMultiHud::InitIntro();
+}
+
+
+//===========================================================================
+// CGuiScreenHud::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::InitRunning()
+{
+// this->SetFadingEnabled( false );
+
+ // for fading in/out ingame
+ //
+ rAssert( m_screenCover != NULL );
+ m_screenCover->SetVisible( true );
+ m_screenCover->SetAlpha( 0.0f );
+
+ // reset HUD foreground fade in time
+ //
+ m_elapsedFgdFadeInTime = 0.0f;
+
+ CGuiScreenMultiHud::InitRunning();
+}
+
+
+//===========================================================================
+// CGuiScreenHud::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::InitOutro()
+{
+/*
+ this->HideMissionObjective();
+
+ rAssert( m_overlays[ HUD_MESSAGE ] );
+ m_overlays[ HUD_MESSAGE ]->SetVisible( false );
+
+ m_helpMessageQueue.Clear();
+*/
+ // stop coin collected presentation
+ //
+ rAssert( m_hudEventHandlers[ HUD_EVENT_HANDLER_COIN_COLLECTED ] != NULL );
+ m_hudEventHandlers[ HUD_EVENT_HANDLER_COIN_COLLECTED ]->Stop();
+
+ if( m_isFadingIn ) // if we're in the middle of fading back in from blackness, just stop it right here
+ {
+ this->HandleMessage( GUI_MSG_INGAME_FADE_IN_CANCEL );
+ }
+
+ CGuiScreenMultiHud::InitOutro();
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+/*
+//===========================================================================
+// CGuiScreenHud::DisplayMissionObjective
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::DisplayMissionObjective( unsigned int messageID )
+{
+ rAssert( m_helpMessage );
+
+ // display mission objective message
+ //
+ m_helpMessage->SetTextIndex( messageID );
+ m_helpMessage->Start();
+}
+
+
+//===========================================================================
+// CGuiScreenHud::HideMissionObjective
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHud::HideMissionObjective()
+{
+ // hide mission objective message
+ //
+ rAssert( m_helpMessage );
+ if( m_helpMessage->GetCurrentState() != ScrollingText::STATE_IDLE )
+ {
+ m_helpMessage->Stop();
+ }
+}
+*/
+
+void
+CGuiScreenHud::UpdateOverlays( unsigned int elapsedTime )
+{
+ // update 'timer' overlay
+ //
+ if( m_overlays[ HUD_TIMER ]->IsVisible() )
+ {
+ this->UpdateTimer( elapsedTime );
+ }
+ else
+ {
+ Mission* currentMission = GetGameplayManager()->GetCurrentMission();
+ rAssert( currentMission != NULL );
+ {
+ // TC: Temporary work-around until I get Cary's help to fix
+ // this properly
+ //
+ if( currentMission->GetMissionTimeLeftInMilliSeconds() > 1000 )
+ {
+ this->HandleMessage( GUI_MSG_SHOW_HUD_OVERLAY, HUD_TIMER );
+
+ this->UpdateTimer( elapsedTime );
+ }
+
+ rWarningMsg( currentMission->GetMissionTimeLeftInMilliSeconds() <= 0,
+ "Why is there mission time left and the HUD timer is not enabled??" );
+ }
+ }
+
+ // update 'message' overlay
+ //
+ if( m_overlays[ HUD_MESSAGE ]->IsVisible() )
+ {
+ m_elapsedTime[ HUD_MESSAGE ] += elapsedTime;
+
+ if( m_elapsedTime[ HUD_MESSAGE ] > MESSAGE_DISPLAY_TIME )
+ {
+ if( !m_helpMessageQueue.IsEmpty() )
+ {
+ unsigned int messageIndex = m_helpMessageQueue.Dequeue();
+ m_helpMessage->SetIndex( static_cast<int>( messageIndex ) );
+
+ // reset elapsed message display time
+ //
+ m_elapsedTime[ HUD_MESSAGE ] = 0;
+ }
+ else
+ {
+ m_overlays[ HUD_MESSAGE ]->SetVisible( false );
+ }
+ }
+ else
+ {
+ m_overlays[ HUD_MESSAGE ]->ResetTransformation();
+
+ if( m_elapsedTime[ HUD_MESSAGE ] < MESSAGE_TRANSITION_TIME )
+ {
+ // transition in
+ //
+ float scaleY = m_elapsedTime[ HUD_MESSAGE ] / (float)MESSAGE_TRANSITION_TIME;
+ m_overlays[ HUD_MESSAGE ]->ScaleAboutCenter( 1.0f, scaleY, 1.0f );
+ }
+ else if( m_elapsedTime[ HUD_MESSAGE ] > MESSAGE_DISPLAY_TIME - MESSAGE_TRANSITION_TIME )
+ {
+ // transition out
+ //
+ float scaleY = (MESSAGE_DISPLAY_TIME - m_elapsedTime[ HUD_MESSAGE ]) / (float)MESSAGE_TRANSITION_TIME;
+ m_overlays[ HUD_MESSAGE ]->ScaleAboutCenter( 1.0f, scaleY, 1.0f );
+ }
+ }
+ }
+
+ // update 'action button' overlay
+ //
+ if( m_overlays[ HUD_ACTION_BUTTON ]->IsVisible() )
+ {
+#ifdef RAD_WIN32
+ const float PULSE_AMPLITUDE = 0.10f;
+ const float PULSE_PERIOD = 600.0f; // in milliseconds
+#else
+ const float PULSE_AMPLITUDE = 0.25f;
+ const float PULSE_PERIOD = 500.0f; // in milliseconds
+#endif
+
+ float scale = GuiSFX::Pulse( (float)m_elapsedTime[ HUD_ACTION_BUTTON ],
+ PULSE_PERIOD,
+ 1.0f,
+ PULSE_AMPLITUDE );
+
+ m_actionButton->ResetTransformation();
+ m_actionButton->ScaleAboutCenter( scale, scale, 1.0f );
+
+#ifdef RAD_WIN32
+ m_actionLabel->ResetTransformation();
+ m_actionLabel->ScaleAboutCenter( 0.85f, 0.85f, 1.0f );
+#endif
+
+ m_elapsedTime[ HUD_ACTION_BUTTON ] += elapsedTime;
+ }
+
+ // update 'mission complete' overlay
+ //
+ if( m_overlays[ HUD_MISSION_COMPLETE ]->IsVisible() )
+ {
+ static float MISSION_COMPLETE_DISPLAY_TIME = 2500; // in milliseconds
+
+#ifdef RAD_WIN32
+ bool done = GuiSFX::Flash( m_missionComplete,
+ (float)m_elapsedTime[ HUD_MISSION_COMPLETE ],
+ MISSION_COMPLETE_DISPLAY_TIME,
+ 3, 0.625f, 0.6f );
+#else
+ bool done = GuiSFX::Flash( m_missionComplete,
+ (float)m_elapsedTime[ HUD_MISSION_COMPLETE ],
+ MISSION_COMPLETE_DISPLAY_TIME,
+ 3, 1.25f, 1.2f );
+#endif
+
+ if( done )
+ {
+ m_overlays[ HUD_MISSION_COMPLETE ]->SetVisible( false );
+
+ if( m_isBonusMissionJustCompleted )
+ {
+ //
+ // Different prompt for different levels
+ //
+ RenderEnums::LevelEnum level = GetGameplayManager()->GetCurrentLevelIndex();
+ int levelInt = static_cast< int >( level );
+ m_pParent->HandleMessage( GUI_MSG_INGAME_DISPLAY_PROMPT, 12 + levelInt );
+ }
+ }
+
+ m_elapsedTime[ HUD_MISSION_COMPLETE ] += elapsedTime;
+ }
+
+ // update 'damage meter' overlay
+ //
+ if( m_overlays[ HUD_DAMAGE_METER ]->IsVisible() )
+ {
+/*
+ if( m_isSlidingDamageMeter )
+ {
+ const float SLIDING_TIME = 1000.0f;
+
+ if( m_elapsedTime[ HUD_DAMAGE_METER ] < SLIDING_TIME )
+ {
+ int xPos, yPos;
+ m_overlays[ HUD_DAMAGE_METER ]->GetOriginPosition( xPos, yPos );
+
+ int screenWidth = (int)Scrooby::App::GetInstance()->GetScreenWidth();
+
+ int xTranslation = (int)( (1.0f - m_elapsedTime[ HUD_DAMAGE_METER ] / SLIDING_TIME) *
+ (screenWidth - xPos) );
+
+ m_overlays[ HUD_DAMAGE_METER ]->ResetTransformation();
+ m_overlays[ HUD_DAMAGE_METER ]->Translate( xTranslation, 0 );
+
+ m_elapsedTime[ HUD_DAMAGE_METER ] += elapsedTime;
+ }
+ else
+ {
+ m_overlays[ HUD_DAMAGE_METER ]->ResetTransformation();
+
+ m_isSlidingDamageMeter = false;
+ }
+ }
+*/
+ const float DAMAGE_METER_BLINK_THRESHOLD = 0.75f;
+
+ if( m_damageMeter.m_value > DAMAGE_METER_BLINK_THRESHOLD )
+ {
+ const unsigned int BLINK_PERIOD = 250;
+
+ bool blinked = GuiSFX::Blink( m_damageMeter.m_pImage,
+ (float)m_elapsedTime[ HUD_DAMAGE_METER ],
+ (float)BLINK_PERIOD );
+ if( blinked )
+ {
+ m_elapsedTime[ HUD_DAMAGE_METER ] %= BLINK_PERIOD;
+ }
+
+ m_elapsedTime[ HUD_DAMAGE_METER ] += elapsedTime;
+ }
+ else
+ {
+ m_damageMeter.m_pImage->SetVisible( true );
+ }
+ }
+
+ // update 'lap counter' overlay
+ //
+ if( m_overlays[ HUD_LAP_COUNTER ]->IsVisible() || m_lapUpdated > 0 )
+ {
+ if( m_lapUpdated > 0 )
+ {
+ const int BLINK_PERIOD = 250; // msec
+ bool blinked = GuiSFX::Blink( m_overlays[ HUD_LAP_COUNTER ],
+ (float)m_elapsedTime[ HUD_LAP_COUNTER ],
+ (float)BLINK_PERIOD );
+
+ if( blinked )
+ {
+ m_elapsedTime[ HUD_LAP_COUNTER ] %= BLINK_PERIOD;
+
+ m_lapUpdated--;
+ }
+
+ m_elapsedTime[ HUD_LAP_COUNTER ] += elapsedTime;
+ }
+ }
+/*
+ // update 'hud map' overlay
+ //
+ if( m_overlays[ HUD_MAP ]->IsVisible() )
+ {
+ if( m_isFadingInRadar )
+ {
+ float radarAlpha = m_overlays[ HUD_MAP ]->GetAlpha() + (elapsedTime / (float)RADAR_FADE_TIME);
+
+ if( radarAlpha < 1.0f )
+ {
+ m_overlays[ HUD_MAP ]->SetAlpha( radarAlpha );
+ }
+ else
+ {
+ m_overlays[ HUD_MAP ]->SetAlpha( 1.0f );
+
+ m_isFadingInRadar = false;
+ }
+ }
+
+ if( m_isFadingOutRadar )
+ {
+ float radarAlpha = m_overlays[ HUD_MAP ]->GetAlpha() - (elapsedTime / (float)RADAR_FADE_TIME);
+
+ if( radarAlpha > 0.0f )
+ {
+ m_overlays[ HUD_MAP ]->SetAlpha( radarAlpha );
+ }
+ else
+ {
+ m_overlays[ HUD_MAP ]->SetAlpha( 0.0f );
+
+ m_isFadingInRadar = false;
+
+ // turn off radar
+ //
+ m_overlays[ HUD_MAP ]->SetVisible( false );
+ }
+ }
+ }
+*/
+}
+
+void
+CGuiScreenHud::UpdateEventHandlers( unsigned int elapsedTime )
+{
+ // update HUD event handlers
+ //
+ for( int j = 0; j < NUM_HUD_EVENT_HANDLERS; j++ )
+ {
+ if( m_hudEventHandlers[ j ] != NULL )
+ {
+ m_hudEventHandlers[ j ]->Update( (float)elapsedTime );
+ }
+ }
+}
+
+void
+CGuiScreenHud::UpdateTimer( unsigned int elapsedTime )
+{
+ const int TIMER_BLINKING_STARTING_PERIOD = 500;
+ const tColour TIMER_BLINKING_COLOUR( 217, 2, 5 );
+
+ int numMillisecondsRemaining = 0;
+
+ Mission* currentMission = GetGameplayManager()->GetCurrentMission();
+ if( currentMission != NULL )
+ {
+ if (m_pGetOutOfCarCondition != NULL)
+ {
+ //use the condition timer
+ numMillisecondsRemaining = m_pGetOutOfCarCondition->GetTimeRemainingTilFailuremilliseconds();
+ }
+ else
+ {
+ numMillisecondsRemaining = currentMission->GetMissionTimeLeftInMilliSeconds();
+ }
+ }
+
+ if( numMillisecondsRemaining > 1000 )
+ {
+ rAssert( m_timer != NULL );
+
+ float blinkPercentage = (numMillisecondsRemaining - m_timerBlinkingStartTime) /
+ (float)(m_timerBlinkingEndTime - m_timerBlinkingStartTime);
+
+ // blink timer if remaining time is btw. timer blinking start
+ // and end time
+ //
+ if( blinkPercentage > 0.0f )
+ {
+ float blinkingPeriod = (float)TIMER_BLINKING_STARTING_PERIOD;
+ if( blinkPercentage > 0.8f )
+ {
+ blinkingPeriod *= 0.50f;
+ }
+ else if( blinkPercentage > 0.5f )
+ {
+ blinkingPeriod *= 0.67f;
+ }
+
+ tColour currentColour;
+ GuiSFX::ModulateColour( &currentColour,
+ (float)numMillisecondsRemaining,
+ blinkingPeriod,
+ m_defaultTimerColour,
+ TIMER_BLINKING_COLOUR,
+ rmt::PI_BY2 );
+
+ m_timer->SetColour( currentColour );
+
+ if( m_elapsedTime[ HUD_TIMER ] >= blinkingPeriod )
+ {
+ GetEventManager()->TriggerEvent( EVENT_HUD_TIMER_BLINK );
+
+ m_elapsedTime[ HUD_TIMER ] %= (int)blinkingPeriod;
+ }
+
+ m_elapsedTime[ HUD_TIMER ] += elapsedTime;
+ }
+ else
+ {
+ // restore timer's default colours
+ //
+ m_timer->SetColour( m_defaultTimerColour );
+
+ m_elapsedTime[ HUD_TIMER ] = TIMER_BLINKING_STARTING_PERIOD;
+ }
+
+ int numSecondsRemaining = numMillisecondsRemaining / 1000;
+
+ char buffer[ BITMAP_TEXT_BUFFER_SIZE ];
+ sprintf( buffer, "%d:%02d", numSecondsRemaining / 60, numSecondsRemaining % 60 );
+
+ m_timer->SetBitmapText( buffer );
+ }
+ else
+ {
+ this->HandleMessage( GUI_MSG_HIDE_HUD_OVERLAY, HUD_TIMER );
+ }
+}
+
+#ifdef SRR2_MOVABLE_HUD_MAP
+
+void
+CGuiScreenHud::UpdateHudMapPosition( unsigned int elapsedTime )
+{
+ // update HUD map screen position
+ //
+ int numUserInputHandlers = GetGuiSystem()->GetNumUserInputHandlers();
+ for( int i = 0; i < numUserInputHandlers; i++ )
+ {
+ CGuiUserInputHandler* userInputHandler = GetGuiSystem()->GetUserInputHandler( i );
+ if( userInputHandler != NULL )
+ {
+#ifdef RAD_PS2
+ if( userInputHandler->IsButtonDown( GuiInput::Back ) ) // action button (for PS2)
+#else
+ if( userInputHandler->IsButtonDown( GuiInput::AuxY ) ) // action button (for Xbox and GC)
+#endif
+ {
+ static int NUM_PIXELS_PER_SECOND = 160;
+ int translationAmount = (int)( (elapsedTime / 1000.0f) * (float)NUM_PIXELS_PER_SECOND );
+
+ if( userInputHandler->IsButtonDown( GuiInput::Left ) )
+ {
+ this->MoveHudMap( -translationAmount, 0 );
+ }
+
+ if( userInputHandler->IsButtonDown( GuiInput::Right ) )
+ {
+ this->MoveHudMap( translationAmount, 0 );
+ }
+
+ if( userInputHandler->IsButtonDown( GuiInput::Up ) )
+ {
+ this->MoveHudMap( 0, translationAmount );
+ }
+
+ if( userInputHandler->IsButtonDown( GuiInput::Down ) )
+ {
+ this->MoveHudMap( 0, -translationAmount );
+ }
+ }
+ }
+ }
+}
+
+void
+CGuiScreenHud::MoveHudMap( int x, int y )
+{
+ rAssert( m_hudMap[ 0 ] );
+
+ // clamp HUD map within screen boundaries
+ //
+ int mapPosX = 0;
+ int mapPosY = 0;
+ int mapWidth = 0;
+ int mapHeight = 0;
+ m_hudMap[ 0 ]->GetPure3dObject()->GetOriginPosition( mapPosX, mapPosY );
+ m_hudMap[ 0 ]->GetPure3dObject()->GetBoundingBoxSize( mapWidth, mapHeight );
+
+ if( (mapPosX + x) < 0 ||
+ (mapPosX + x) > (static_cast<int>( Scrooby::App::GetInstance()->GetScreenWidth() ) - mapWidth) )
+ {
+ x = 0;
+ }
+
+ if( (mapPosY + y) < 0 ||
+ (mapPosY + y) > (static_cast<int>( Scrooby::App::GetInstance()->GetScreenHeight() ) - mapHeight) )
+ {
+ y = 0;
+ }
+
+ // move the HUD map
+ //
+ m_hudMap[ 0 ]->Translate( x, y );
+}
+
+#endif
+
+void CGuiScreenHud::AbortFade()
+{
+ m_elapsedFadeTime = 250.0f;
+ m_screenCover->SetAlpha( 0.0f );
+ Update( 0 );
+}
+
+#ifdef DEBUGWATCH
+const char* CGuiScreenHud::GetWatcherName() const
+{
+ return "CGuiScreenHud";
+}
+#endif \ No newline at end of file
diff --git a/game/code/presentation/gui/ingame/guiscreenhud.h b/game/code/presentation/gui/ingame/guiscreenhud.h
new file mode 100644
index 0000000..3b4f6a0
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenhud.h
@@ -0,0 +1,271 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenHud
+//
+// Description:
+//
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/11/20 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENHUD_H
+#define GUISCREENHUD_H
+
+//#define SRR2_MOVABLE_HUD_MAP // enable user to move HUD map
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenmultihud.h>
+#include <presentation/gui/utility/slider.h>
+
+#include <events/eventlistener.h>
+#include <p3d/p3dtypes.hpp>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class HudEventHandler;
+class GetOutOfCarCondition;
+
+class MessageQueue
+{
+ // This is a very simple queue data structure that uses a circular
+ // array to store unsigned integer values.
+ //
+ // m_front - points to the front slot of the queue
+ // m_back - points to the next free slot right behind the back of the queue
+ //
+public:
+ MessageQueue();
+ virtual ~MessageQueue();
+
+ void Enqueue( unsigned int messageID );
+ unsigned int Dequeue();
+
+ void Clear();
+ bool IsEmpty() const { return m_isEmpty; }
+ bool IsFull() const { return m_isFull; }
+
+private:
+ static const unsigned short MESSAGE_QUEUE_CAPACITY = 8;
+
+ unsigned int m_messages[ MESSAGE_QUEUE_CAPACITY ];
+ unsigned short m_front;
+ unsigned short m_back;
+ bool m_isEmpty : 1;
+ bool m_isFull : 1;
+
+
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+enum eHudOverlay
+{
+ // The following are ordered in precendence priority when more than
+ // one mission-related overlay is enabled (w/ the first one being
+ // the highest priority).
+ //
+ HUD_DAMAGE_METER,
+ HUD_PROXIMITY_METER,
+ HUD_COLLECTIBLES,
+ HUD_TIMER,
+ HUD_RACE_POSITION,
+ HUD_LAP_COUNTER,
+ HUD_TIMER_TEMP,
+ HUD_PAR_TIME,
+
+ NUM_HUD_MISSION_OVERLAYS, // not really an overlay
+
+ HUD_MISSION_COMPLETE,
+ HUD_ACTION_BUTTON,
+ HUD_MESSAGE,
+ HUD_MAP,
+
+ NUM_HUD_OVERLAYS
+};
+
+class CGuiScreenHud : public CGuiScreenMultiHud,
+ public EventListener
+{
+public:
+ CGuiScreenHud( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenHud();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ void Update( unsigned int elapsedTime );
+
+ inline bool IsActive() const;
+
+ // Turns Entire HUD On/Off
+ //
+ void SetVisible( bool isVisible );
+
+ // Set HUD Overlay Info
+ //
+ void SetTimerBlinkingInterval( int startTime, int endTime );
+ void SetParTime( int parTime );
+ void SetCollectibles( int numCollected, int numToCollect );
+ void SetRacePosition( int currentPosition, int numPositions );
+ void SetLap( int currentLap, int numLaps );
+ void SetDamageMeter( float value );
+ void SetProximityMeter( float value );
+ void SetHitAndRunMeter( float value );
+
+ // Show/Hide Text Message
+ //
+ void DisplayMessage( bool show, const int index = 0 );
+
+ // Show/Hide All Mission Overlays
+ //
+ void DisplayMissionOverlays( bool show );
+
+ enum eHudEventHandler
+ {
+ HUD_EVENT_HANDLER_CARD_COLLECTED,
+ HUD_EVENT_HANDLER_COIN_COLLECTED,
+ HUD_EVENT_HANDLER_MISSION_PROGRESS,
+ HUD_EVENT_HANDLER_MISSION_OBJECTIVE,
+ HUD_EVENT_HANDLER_COUNTDOWN,
+ HUD_EVENT_HANDLER_HIT_N_RUN,
+ HUD_EVENT_HANDLER_WASP_DESTROYED,
+ HUD_EVENT_HANDLER_ITEM_DROPPED,
+
+ NUM_HUD_EVENT_HANDLERS
+ };
+
+ HudEventHandler* GetEventHandler( eHudEventHandler eventHandler ) const;
+
+ // Implements EventListener
+ //
+ virtual void HandleEvent( EventEnum id, void* pEventData );
+
+ static void SetNumCoinsDisplay( Scrooby::Sprite* pSprite );
+ static void UpdateNumCoinsDisplay( int numCoins, bool show = true );
+ void AbortFade();
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+ #ifdef DEBUGWATCH
+ virtual const char* GetWatcherName() const;
+ #endif
+
+private:
+ static bool IsMissionOverlay( unsigned int overlayIndex );
+
+ void UpdateOverlays( unsigned int elapsedTime );
+ void UpdateEventHandlers( unsigned int elapsedTime );
+ void UpdateTimer( unsigned int elapsedTime );
+
+#ifdef SRR2_MOVABLE_HUD_MAP
+ void UpdateHudMapPosition( unsigned int elapsedTime );
+ void MoveHudMap( int x, int y );
+#endif
+
+ static const unsigned int BITMAP_TEXT_BUFFER_SIZE = 8;
+ static const int NUM_HIT_N_RUN_SECTORS = 8;
+
+ static const int MAX_NUM_COIN_DIGITS = 8;
+ static Scrooby::Sprite* s_numCoinsDisplay;
+
+ Scrooby::Group* m_overlays[ NUM_HUD_OVERLAYS ];
+ unsigned int m_elapsedTime[ NUM_HUD_OVERLAYS ];
+
+ Scrooby::Group* m_missionOverlays;
+ Scrooby::Sprite* m_missionFailedSprite;
+
+ Scrooby::Text* m_helpMessage;
+ Scrooby::Sprite* m_messageBox;
+ MessageQueue m_helpMessageQueue;
+
+#ifdef RAD_WIN32
+ Scrooby::Text* m_actionButton;
+ Scrooby::Text* m_actionLabel;
+#else
+ Scrooby::Sprite* m_actionButton;
+#endif
+
+ Scrooby::Sprite* m_missionComplete;
+
+ Scrooby::Sprite* m_timer;
+ tColour m_defaultTimerColour;
+ int m_timerBlinkingStartTime;
+ int m_timerBlinkingEndTime;
+
+ Scrooby::Sprite* m_parTime;
+
+ Scrooby::Sprite* m_collectibles;
+ int m_collectiblesUpdated;
+
+ Scrooby::Sprite* m_position;
+ Scrooby::Text* m_positionOrdinal;
+
+ Scrooby::Sprite* m_lap;
+ int m_lapUpdated;
+
+ ImageSlider m_damageMeter;
+ bool m_isSlidingDamageMeter;
+
+ ImageSlider m_proximityMeter;
+
+ bool m_isFadingInRadar : 1;
+ bool m_isFadingOutRadar : 1;
+
+ Scrooby::Sprite* m_hnrSectors[ NUM_HIT_N_RUN_SECTORS ];
+ Scrooby::Sprite* m_hnrLights;
+ Scrooby::Sprite* m_hnrMeter;
+ Scrooby::Sprite* m_hnrMeterBgd;
+ unsigned int m_hnrElapsedTime;
+
+ HudEventHandler* m_hudEventHandlers[ NUM_HUD_EVENT_HANDLERS ];
+
+ bool m_isFadingIn : 1;
+ bool m_isFadingOut : 1;
+ float m_elapsedFadeTime;
+
+ bool m_isBonusMissionJustCompleted : 1;
+
+ bool m_isAvatarOffRoad : 1;
+ unsigned int m_avatarOffRoadDurationTime;
+
+ GetOutOfCarCondition* m_pGetOutOfCarCondition;
+
+ float m_elapsedFgdFadeInTime;
+
+};
+
+inline bool CGuiScreenHud::IsActive() const
+{
+ // TC: if the start button was just pressed, we'll treat the screen
+ // as in-active, since it's about to transition out anyways
+ //
+ return ( m_state == GUI_WINDOW_STATE_RUNNING && !m_isStartButtonPressed );
+}
+
+inline HudEventHandler* CGuiScreenHud::GetEventHandler( eHudEventHandler eventHandler ) const
+{
+ return m_hudEventHandlers[ eventHandler ];
+}
+
+inline bool CGuiScreenHud::IsMissionOverlay( unsigned int overlayIndex )
+{
+ return( static_cast<int>( overlayIndex ) < NUM_HUD_MISSION_OVERLAYS );
+}
+
+#endif // GUISCREENHUD_H
diff --git a/game/code/presentation/gui/ingame/guiscreenhudmap.cpp b/game/code/presentation/gui/ingame/guiscreenhudmap.cpp
new file mode 100644
index 0000000..ebeb36c
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenhudmap.cpp
@@ -0,0 +1,279 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenHudMap
+//
+// Description: Implementation of the CGuiScreenHudMap class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guimanageringame.h>
+#include <presentation/gui/ingame/guiscreenhud.h>
+#include <presentation/gui/ingame/guiscreenhudmap.h>
+#include <presentation/gui/utility/hudmap.h>
+
+#include <memory/srrmemory.h>
+
+#include <p3d/pointcamera.hpp>
+
+#include <raddebug.hpp> // Foundation
+#include <raddebugwatch.hpp>
+#include <page.h>
+#include <polygon.h>
+#include <pure3dobject.h>
+#include <screen.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+#ifdef DEBUGWATCH
+ static const char* HUD_MAP_WATCHER_NAMESPACE = "GUI System - HUD Map Screen";
+ float g_wCamPosY = 700.0f;
+ float g_wCamTargetX = 0.0f;
+ float g_wCamTargetZ = 0.0f;
+#endif
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenHudMap::CGuiScreenHudMap
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenHudMap::CGuiScreenHudMap
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+:
+ CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_HUD_MAP ),
+ m_largeHudMap( NULL ),
+ m_posX( 0 ),
+ m_posY( 0 ),
+ m_width( 0 ),
+ m_height( 0 ),
+ m_camera( NULL )
+{
+MEMTRACK_PUSH_GROUP( "CGUIScreenHudMap" );
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage;
+ pPage = m_pScroobyScreen->GetPage( "ViewMap" );
+ rAssert( pPage );
+
+ Scrooby::Polygon* mapBgd = pPage->GetPolygon( "MapBgd" );
+ rAssert( mapBgd );
+
+ // Get map position and size (based on background polygon)
+ //
+ mapBgd->GetVertexLocation( 0, m_posX, m_posY ); // assuming first vertex
+ // is bottom-left co-ord
+ mapBgd->GetBoundingBoxSize( m_width, m_height );
+
+ // Create an overhead camera
+ //
+ m_camera = new(GMA_LEVEL_HUD) tPointCamera;
+ rAssert( m_camera );
+ m_camera->AddRef();
+ m_camera->SetVUp( rmt::Vector( 1, 0, 0 ) );
+ m_camera->SetPosition( rmt::Vector( 0, 700, 0 ) );
+ m_camera->SetTarget( rmt::Vector( 0, 0, 0 ) );
+
+#ifdef DEBUGWATCH
+ radDbgWatchAddFloat( &g_wCamPosY,
+ "Camera Height (Y)",
+ HUD_MAP_WATCHER_NAMESPACE,
+ NULL,
+ NULL,
+ 100.0f,
+ 1000.0f );
+
+ radDbgWatchAddFloat( &g_wCamTargetX,
+ "Camera Target (X)",
+ HUD_MAP_WATCHER_NAMESPACE,
+ NULL,
+ NULL,
+ -1000.0f,
+ 1000.0f );
+
+ radDbgWatchAddFloat( &g_wCamTargetZ,
+ "Camera Target (Z)",
+ HUD_MAP_WATCHER_NAMESPACE,
+ NULL,
+ NULL,
+ -1000.0f,
+ 1000.0f );
+#endif
+MEMTRACK_POP_GROUP();
+}
+
+
+//===========================================================================
+// CGuiScreenHudMap::~CGuiScreenHudMap
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenHudMap::~CGuiScreenHudMap()
+{
+#ifdef DEBUGWATCH
+ radDbgWatchDelete( &g_wCamPosY );
+ radDbgWatchDelete( &g_wCamTargetX );
+ radDbgWatchDelete( &g_wCamTargetZ );
+#endif
+
+ if( m_camera != NULL )
+ {
+ m_camera->Release();
+ m_camera = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenHudMap::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHudMap::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+#ifdef DEBUGWATCH
+ rAssert( m_camera );
+ m_camera->SetPosition( rmt::Vector( g_wCamTargetX, g_wCamPosY, g_wCamTargetZ ) );
+ m_camera->SetTarget( rmt::Vector( g_wCamTargetX, 0, g_wCamTargetZ ) );
+#endif
+ rAssert( m_largeHudMap );
+ m_largeHudMap->Update( param1 );
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_START:
+ {
+ // resume game
+ m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME );
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenHudMap::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHudMap::InitIntro()
+{
+ m_largeHudMap = GetCurrentHud()->GetHudMap( 0 );
+ rAssert( m_largeHudMap );
+
+ Scrooby::Pure3dObject* p3dMap = m_largeHudMap->GetPure3dObject();
+ rAssert( p3dMap );
+
+ p3dMap->SetPosition( m_posX, m_posY );
+ p3dMap->SetBoundingBoxSize( m_width, m_height );
+
+ p3dMap->SetCamera( m_camera );
+
+ m_largeHudMap->Update( 0 );
+}
+
+
+//===========================================================================
+// CGuiScreenHudMap::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHudMap::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenHudMap::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenHudMap::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/ingame/guiscreenhudmap.h b/game/code/presentation/gui/ingame/guiscreenhudmap.h
new file mode 100644
index 0000000..ea21d2b
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenhudmap.h
@@ -0,0 +1,59 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenHudMap
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENHUDMAP_H
+#define GUISCREENHUDMAP_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CHudMap;
+class tPointCamera;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenHudMap : public CGuiScreen
+{
+public:
+ CGuiScreenHudMap( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenHudMap();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ CHudMap* m_largeHudMap;
+ int m_posX;
+ int m_posY;
+ int m_width;
+ int m_height;
+
+ tPointCamera* m_camera;
+
+};
+
+#endif // GUISCREENHUDMAP_H
diff --git a/game/code/presentation/gui/ingame/guiscreeniriswipe.cpp b/game/code/presentation/gui/ingame/guiscreeniriswipe.cpp
new file mode 100644
index 0000000..8548f3a
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreeniriswipe.cpp
@@ -0,0 +1,366 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenIrisWipe
+//
+// Description: Implementation of the CGuiScreenIrisWipe class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/21 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreeniriswipe.h>
+#include <presentation/gui/utility/specialfx.h>
+
+#include <events/eventmanager.h>
+
+#include <screen.h>
+#include <page.h>
+#include <pure3dobject.h>
+#include <text.h>
+
+#include <p3d/anim/multicontroller.hpp>
+#include <p3d/utility.hpp>
+
+#include <raddebug.hpp> // Foundation
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+const float DEFAULT_REL_SPEED = 0.5f;
+static bool g_doNotOpenOnNextOutro = false;
+bool CGuiScreenIrisWipe::g_IsIrisClosed = false;
+
+const unsigned int MAX_IDLE_TIME_OF_BLACKNESS = 3000; // in msec
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenIrisWipe::CGuiScreenIrisWipe
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenIrisWipe::CGuiScreenIrisWipe
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_IRIS_WIPE ),
+ m_pIris( 0 ),
+ m_pMultiController( 0 ),
+ m_isIrisActive( false ),
+ m_loadingText( NULL ),
+ m_elapsedIdleTime( 0 ),
+ m_elapsedBlinkTime( 0 )
+{
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "3dIris" );
+ rAssert( pPage != NULL );
+
+ m_pIris = pPage->GetPure3dObject( "p3d_iris" );
+ rAssert( m_pIris );
+
+ // Have to find the multicontroller ourselves because for some stupid reason
+ // Scrooby doesn't make it accessable via the Pure3dObject until the first render.
+ //
+ m_pMultiController = p3d::find<tMultiController>( "IrisController" );
+ rAssert( m_pMultiController );
+
+ m_numFrames = m_pMultiController->GetNumFrames();
+
+ // get loading text
+ //
+ pPage = m_pScroobyScreen->GetPage( "LoadingText" );
+ if( pPage != NULL )
+ {
+ m_loadingText = pPage->GetText( "Loading" );
+ rAssert( m_loadingText != NULL );
+ m_loadingText->SetVisible( false ); // hide by default
+ }
+
+ m_relativeSpeed = DEFAULT_REL_SPEED;
+}
+
+
+//===========================================================================
+// CGuiScreenIrisWipe::~CGuiScreenIrisWipe
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenIrisWipe::~CGuiScreenIrisWipe()
+{
+}
+
+//===========================================================================
+// CGuiScreenIrisWipe::DoNotOpenOnNextOutro
+//===========================================================================
+// Description: tells the screen not to transition out next time
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenIrisWipe::DoNotOpenOnNextOutro()
+{
+ g_doNotOpenOnNextOutro = true;
+}
+
+//===========================================================================
+// CGuiScreenIrisWipe::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenIrisWipe::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ if( message == GUI_MSG_UPDATE )
+ {
+ m_elapsedIdleTime += param1;
+
+ if( m_elapsedIdleTime > MAX_IDLE_TIME_OF_BLACKNESS )
+ {
+ m_elapsedBlinkTime += param1;
+
+ if( m_loadingText != NULL )
+ {
+ // blink loading text if idling here on this screen to satisfy
+ // TRC/TCR requirements
+ //
+ const unsigned int BLINKING_PERIOD = 250;
+ bool isBlinked = GuiSFX::Blink( m_loadingText,
+ static_cast<float>( m_elapsedBlinkTime ),
+ static_cast<float>( BLINKING_PERIOD ) );
+ if( isBlinked )
+ {
+ m_elapsedBlinkTime %= BLINKING_PERIOD;
+ }
+ }
+ }
+ }
+ }
+ else if( m_state == GUI_WINDOW_STATE_INTRO )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ if( m_isIrisActive && m_pMultiController->LastFrameReached() )
+ {
+ m_isIrisActive = false;
+
+ m_numTransitionsPending--;
+ rAssert( m_numTransitionsPending == 0 );
+
+ GetEventManager()->TriggerEvent( EVENT_GUI_IRIS_WIPE_CLOSED );
+ rReleasePrintf( "CGuiScreenIrisWipe => EVENT_GUI_IRIS_WIPE_CLOSED.\n" );
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ else if( m_state == GUI_WINDOW_STATE_OUTRO )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ if( m_isIrisActive && m_pMultiController->LastFrameReached() )
+ {
+ m_isIrisActive = false;
+
+ m_numTransitionsPending--;
+ rAssert( m_numTransitionsPending == 0 );
+
+ GetEventManager()->TriggerEvent( EVENT_GUI_IRIS_WIPE_OPEN );
+ rReleasePrintf( "CGuiScreenIrisWipe => EVENT_GUI_IRIS_WIPE_OPEN.\n" );
+ }
+
+ break;
+ }
+ case GUI_MSG_WINDOW_EXIT:
+ {
+ // ignore multiple exit requests
+ //
+ return;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenIrisWipe::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenIrisWipe::InitIntro()
+{
+ if( m_loadingText != NULL )
+ {
+ // hide loading text
+ //
+ m_loadingText->SetVisible( false );
+ }
+
+ if( !m_isIrisActive )
+ {
+ m_isIrisActive = true;
+
+ g_IsIrisClosed = true;
+ m_pIris->SetVisible( true );
+ m_pMultiController->SetRelativeSpeed( m_relativeSpeed );
+
+ rAssertMsg( m_numTransitionsPending == 0, "Bad news if you hit this assert! Please go tell Tony." );
+ m_numTransitionsPending++;
+
+ m_pMultiController->Reset();
+ m_pMultiController->SetFrameRange( 0.0f, m_numFrames * 0.5f );
+ m_pMultiController->SetFrame( 0.0f );
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenIrisWipe::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenIrisWipe::InitRunning()
+{
+ m_elapsedIdleTime = 0;
+ m_elapsedBlinkTime = 0;
+}
+
+
+//===========================================================================
+// CGuiScreenIrisWipe::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenIrisWipe::InitOutro()
+{
+ if( m_loadingText != NULL )
+ {
+ // hide loading text
+ //
+ m_loadingText->SetVisible( false );
+ }
+
+ if( g_doNotOpenOnNextOutro )
+ {
+ g_doNotOpenOnNextOutro = false;
+ }
+ else
+ {
+ g_IsIrisClosed = false;
+ if( !m_isIrisActive )
+ {
+ m_isIrisActive = true;
+
+ rAssertMsg( m_numTransitionsPending == 0, "Bad news if you hit this assert! Please go tell Tony." );
+ m_numTransitionsPending++;
+
+ m_pMultiController->Reset();
+ m_pMultiController->SetFrameRange( m_numFrames * 0.5f, m_numFrames );
+ m_pMultiController->SetFrame( m_numFrames * 0.5f );
+
+ //Reset the relative speed to the default
+ m_relativeSpeed = DEFAULT_REL_SPEED;
+ }
+ }
+}
+
+//===========================================================================
+// CGuiScreenIrisWipe::IsIrisClosed
+//===========================================================================
+// Description: Lets you know if the iris is closed at the moment
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+bool CGuiScreenIrisWipe::IsIrisClosed()
+{
+ return g_IsIrisClosed;
+}
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/ingame/guiscreeniriswipe.h b/game/code/presentation/gui/ingame/guiscreeniriswipe.h
new file mode 100644
index 0000000..c9a24a4
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreeniriswipe.h
@@ -0,0 +1,70 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenIrisWipe
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/21 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENIRISWIPE_H
+#define GUISCREENIRISWIPE_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+namespace Scrooby
+{
+ class Pure3dObject;
+};
+class tMultiController;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenIrisWipe : public CGuiScreen
+{
+public:
+ CGuiScreenIrisWipe( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenIrisWipe();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ inline void SetRelativeSpeed( float speed ) { m_relativeSpeed = speed; };
+ static void DoNotOpenOnNextOutro();
+ static bool IsIrisClosed();
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ Scrooby::Pure3dObject* m_pIris;
+ tMultiController* m_pMultiController;
+ float m_numFrames;
+ float m_relativeSpeed;
+ static bool g_IsIrisClosed;
+
+ bool m_isIrisActive : 1;
+
+ Scrooby::Text* m_loadingText;
+ unsigned int m_elapsedIdleTime;
+ unsigned int m_elapsedBlinkTime;
+
+};
+
+#endif // GUISCREENIRISWIPE_H
diff --git a/game/code/presentation/gui/ingame/guiscreenletterbox.cpp b/game/code/presentation/gui/ingame/guiscreenletterbox.cpp
new file mode 100644
index 0000000..164b1c4
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenletterbox.cpp
@@ -0,0 +1,688 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLetterBox
+//
+// Description: Implementation of the CGuiScreenLetterBox class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/21 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenletterbox.h>
+
+#include <events/eventmanager.h>
+#include <input/inputmanager.h>
+#include <interiors/interiormanager.h>
+#include <mission/missionmanager.h>
+#include <mission/missionstage.h>
+#include <mission/objectives/missionobjective.h>
+
+#include <raddebug.hpp> // Foundation
+#include <group.h>
+#include <page.h>
+#include <pure3dobject.h>
+#include <screen.h>
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const float BAR_SLIDING_TIME = 500.0f; // in msec
+bool CGuiScreenLetterBox::m_enableReopen = false;
+bool CGuiScreenLetterBox::m_forceOpen = false;
+static bool g_SurpressNextSkipButton = false;
+GuiSFX::Translator g_TopIn( "Top In" );
+GuiSFX::Translator g_BottomIn( "Bottom In" );
+GuiSFX::Translator g_TopOut( "Top Out" );
+GuiSFX::Translator g_BottomOut( "Bottom Out" );
+GuiSFX::Translator g_TopClose( "Top Close" );
+GuiSFX::Translator g_BottomClose( "Outro bottom close" );
+GuiSFX::SendEvent g_ClosedEvent( "Outro closed event" );
+GuiSFX::Pause s_OutroPauseBetweenCloseAndIris( "Outro pause between close and open" );
+GuiSFX::IrisWipeOpen s_OutroIrisOpen( "Outro Iris Open" );
+bool CGuiScreenLetterBox::s_suppressAcceptCancelButtons = false;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenLetterBox::CGuiScreenLetterBox
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLetterBox::CGuiScreenLetterBox
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_LETTER_BOX ),
+ m_topBar( NULL ),
+ m_bottomBar( NULL ),
+ m_skipButton( NULL ),
+ m_skipLabel( NULL ),
+ m_elapsedTime( 0 ),
+ m_OutroPending( false )
+{
+ // Retrieve the Scrooby drawing elements.
+ //
+ m_Page = m_pScroobyScreen->GetPage( "LetterBox" ); rAssert( m_Page != NULL );
+ m_IrisPage = m_pScroobyScreen->GetPage( "3dIris" ); rAssert( m_IrisPage != NULL );
+ m_Iris = m_IrisPage->GetPure3dObject( "p3d_iris" );
+
+ // get the top and bottom letterbox bars
+ //
+ m_topBar = m_Page->GetGroup( "TopBar" );
+ m_bottomBar = m_Page->GetGroup( "BottomBar" );
+
+ // get letter box buttons from 'LetterBoxButtons.pag'
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "LetterBoxButtons" );
+ rAssert( pPage != NULL );
+
+ m_skipButton = pPage->GetGroup( "Skip" );
+ rAssert( m_skipButton != NULL );
+
+ m_skipLabel = m_skipButton->GetGroup( "SkipLabel" );
+ m_buttonIcons[ BUTTON_ICON_ACCEPT ] = m_skipButton->GetGroup( "AcceptLabel" );
+ m_buttonIcons[ BUTTON_ICON_BACK ] = m_skipButton->GetGroup( "BackLabel" );
+
+ if( this->IsWideScreenDisplay() )
+ {
+ m_skipButton->ResetTransformation();
+ this->ApplyWideScreenCorrectionScale( m_skipButton );
+ }
+
+ AddTransition( g_TopIn );
+ AddTransition( g_BottomIn );
+ AddTransition( g_TopOut );
+ AddTransition( g_BottomOut );
+ AddTransition( g_TopClose );
+ AddTransition( g_BottomClose );
+ AddTransition( s_OutroIrisOpen );
+ AddTransition( s_OutroPauseBetweenCloseAndIris );
+ DoneAddingTransitions();
+
+ g_TopIn.SetDrawable( m_topBar );
+ g_BottomIn.SetDrawable( m_bottomBar );
+ g_TopOut.SetDrawable( m_topBar );
+ g_BottomOut.SetDrawable( m_bottomBar );
+ g_TopClose.SetDrawable( m_topBar );
+ g_BottomClose.SetDrawable( m_bottomBar );
+ g_ClosedEvent.SetEvent( EVENT_LETTERBOX_CLOSED );
+
+ SetIntroFromOpen();
+ g_TopOut.SetCoordsStart( 0, 240 - 70 );
+ g_TopOut.SetCoordsEnd( 0, 240 );
+ g_TopOut.SetTimeInterval( BAR_SLIDING_TIME );
+ g_BottomOut.SetCoordsStart( 0, -240 + 70 );
+ g_BottomOut.SetCoordsEnd( 0, -240 );
+ g_BottomOut.SetTimeInterval( BAR_SLIDING_TIME );
+ g_TopClose.SetCoordsStart( 0, 240 - 70 );
+ g_TopClose.SetCoordsEnd( 0, 0 );
+ g_TopClose.SetTimeInterval( BAR_SLIDING_TIME );
+ g_BottomClose.SetCoordsStart( 0, -240 + 70 );
+ g_BottomClose.SetCoordsEnd( 0, 0 );
+ g_BottomClose.SetTimeInterval( BAR_SLIDING_TIME );
+ s_OutroPauseBetweenCloseAndIris.SetTimeInterval( 500 );
+ s_OutroIrisShow.SetDrawable( m_Iris );
+ s_OutroLetterBoxHide.SetDrawable( m_Page );
+
+ g_BottomClose.SetNextTransition( s_OutroPauseBetweenCloseAndIris );
+ s_OutroPauseBetweenCloseAndIris.SetNextTransition( s_OutroIrisShow );
+ s_OutroIrisShow.SetNextTransition( s_OutroLetterBoxHide );
+ s_OutroLetterBoxHide.SetNextTransition( g_ClosedEvent );
+ g_ClosedEvent.SetNextTransition( s_OutroIrisOpen );
+}
+
+
+//===========================================================================
+// CGuiScreenLetterBox::~CGuiScreenLetterBox
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLetterBox::~CGuiScreenLetterBox()
+{
+}
+
+//===========================================================================
+// CGuiScreenLetterBox::CheckIfScreenShouldBeBlank
+//===========================================================================
+// Description: this is a huge hack for the one frame glitch you get when
+// switching screens sometimes
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLetterBox::CheckIfScreenShouldBeBlank()
+{
+ bool irisClosed = GetGameplayManager()->IsIrisClosed();
+ if( irisClosed )
+ {
+ m_topBar->ResetTransformation();
+ m_topBar->Translate( 0, 0 );
+ m_bottomBar->ResetTransformation();
+ m_bottomBar->Translate( 0, 0 );
+ }
+ else
+ {
+ m_topBar->ResetTransformation();
+ m_topBar->Translate( 0, 240 );
+ m_bottomBar->ResetTransformation();
+ m_bottomBar->Translate( 0, -240 );
+ }
+}
+
+//===========================================================================
+// CGuiScreenLetterBox::ForceOpen
+//===========================================================================
+// Description: forces the screen to open next time
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLetterBox::ForceOpen()
+{
+ m_forceOpen = true;
+}
+
+//===========================================================================
+// CGuiScreenLetterBox::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLetterBox::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( message == GUI_MSG_UPDATE )
+ {
+ ResetMovableObjects();
+ float deltaT = static_cast< float >( param1 );
+ UpdateTransitions( deltaT );
+
+#ifdef RAD_DEMO
+ // reset idle timer when we're in a conversation
+ //
+ GetGameplayManager()->ResetIdleTime();
+#endif
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ if( m_skipButton->IsVisible() )
+ {
+ if( this->IsButtonVisible( BUTTON_ICON_ACCEPT ) )
+ {
+ this->OnAccept();
+ }
+ else
+ {
+ this->OnSkip();
+ }
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ if( m_skipButton->IsVisible() && this->IsButtonVisible( BUTTON_ICON_BACK ) )
+ {
+ this->OnCancel();
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ else if( m_state == GUI_WINDOW_STATE_INTRO )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ if( g_TopIn.IsChainDone() )
+ {
+ --m_numTransitionsPending;
+ }
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+ else if( m_state == GUI_WINDOW_STATE_OUTRO )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ if( m_enableReopen )
+ {
+ }
+ else
+ {
+ if( g_BottomClose.IsChainDone() || g_BottomOut.IsChainDone() )
+ {
+ --m_numTransitionsPending;
+ }
+ }
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+void
+CGuiScreenLetterBox::HandleEvent( EventEnum id, void* pEventData )
+{
+ rAssert( id == EVENT_CONVERSATION_DONE );
+
+ GetEventManager()->TriggerEvent( EVENT_CONVERSATION_DONE_AND_FINISHED );
+}
+
+
+//===========================================================================
+// CGuiScreenLetterBox::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLetterBox::InitIntro()
+{
+ s_OutroIrisOpen.Reset();
+
+ m_Page->SetVisible( true );
+ m_Iris->SetVisible( false );
+ m_topBar->SetVisible( true );
+ m_bottomBar->SetVisible( true );
+ ResetTransitions();
+ m_topBar->Translate( 0, 240 );
+ m_bottomBar->Translate( 0, -240 );
+ g_TopIn.Activate();
+ g_BottomIn.Activate();
+ m_elapsedTime = 0;
+ m_numTransitionsPending++;
+ m_OutroPending = false;
+
+ //
+ // Is the screen already black from some sort of fade?
+ //
+ bool irisClosed = GetGameplayManager()->IsIrisClosed();
+ if( irisClosed )
+ {
+ SetIntroFromClosed();
+ }
+ else
+ {
+ SetIntroFromOpen();
+ }
+
+
+ rAssert( m_skipButton != NULL );
+ if( g_SurpressNextSkipButton )
+ {
+ m_skipButton->SetVisible( false );
+ }
+ else
+ {
+ m_skipButton->SetVisible( true );
+
+ MissionStage* currentStage = GetGameplayManager()->GetCurrentMission()->GetCurrentStage();
+ rAssert( currentStage != NULL );
+ bool showAcceptCancel = GetGameplayManager()->IsSundayDrive() &&
+ currentStage->IsMissionAbortAllowed() &&
+ !GetInteriorManager()->IsPlayingISMovieDialog();
+
+ if( s_suppressAcceptCancelButtons )
+ {
+ showAcceptCancel = false;
+ }
+
+ rAssert( m_skipLabel != NULL );
+ m_skipLabel->SetVisible( !showAcceptCancel );
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, showAcceptCancel );
+ this->SetButtonVisible( BUTTON_ICON_BACK, showAcceptCancel );
+ }
+
+ s_suppressAcceptCancelButtons = false; // reset this flag
+
+ GetEventManager()->AddListener( this, EVENT_CONVERSATION_DONE );
+
+ //
+ // Double check if we were doing a "fade in" beforehand, and abort it
+ //
+ bool fadeInProgress = GetGameplayManager()->FadeInProgress();
+ GetGameplayManager()->AbortFade();
+}
+
+
+//===========================================================================
+// CGuiScreenLetterBox::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLetterBox::InitRunning()
+{
+}
+
+//===========================================================================
+// CGuiScreenLetterBox::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLetterBox::InitOutro()
+{
+ if( m_OutroPending )
+ {
+ return;
+ }
+ m_OutroPending = true;
+ g_TopIn.Deactivate();
+ g_BottomIn.Deactivate();
+ bool sundayDrive = GetGameplayManager()->IsSundayDrive();
+ int numStages = GetGameplayManager()->GetCurrentMission()->GetNumStages();
+ int currentIndex = GetGameplayManager()->GetCurrentMission()->GetCurrentStageIndex();
+ Mission* mission = GetGameplayManager()->GetCurrentMission();
+ MissionStage* stage = mission->GetCurrentStage();
+ MissionObjective* obj = stage->GetObjective();
+ bool pattyAndSelma = obj->IsPattyAndSelmaDialog();
+ bool raceDialog = obj->IsRaceDialog();
+
+ g_BottomClose.SetNextTransition( NULL );
+
+ //
+ // Sometimes we close the letterbox, sometimes it just opens up. when does
+ // it do what? If we're going to a hud screen, then it closes first, if
+ // we're staying in gameplay, then it just opens up
+ //
+ if( m_forceOpen )
+ {
+ g_TopOut.Activate();
+ g_BottomOut.Activate();
+ m_forceOpen = false;
+ }
+ else
+ {
+ if( ( sundayDrive && (currentIndex >= numStages - 1) ) || pattyAndSelma || raceDialog )
+ {
+ g_TopClose.Activate();
+ g_BottomClose.Activate();
+ }
+ else
+ {
+ g_TopOut.Activate();
+ g_BottomOut.Activate();
+ }
+ }
+
+ rAssert( m_skipButton != NULL );
+ m_skipButton->SetVisible( false );
+
+ m_elapsedTime = 0;
+ m_numTransitionsPending++;
+ g_SurpressNextSkipButton = false;
+
+ GetEventManager()->RemoveListener( this, EVENT_CONVERSATION_DONE );
+}
+
+//===========================================================================
+// CGuiScreenLetterBox::SurpressSkipButton
+//===========================================================================
+// Description: Surpresses showing
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLetterBox::SurpressSkipButton()
+{
+ g_SurpressNextSkipButton = true;
+}
+
+//===========================================================================
+// CGuiScreenLetterBox::UnSurpressSkipButton
+//===========================================================================
+// Description: The skip button will be visible again
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLetterBox::UnSurpressSkipButton()
+{
+ g_SurpressNextSkipButton = false;
+}
+
+//===========================================================================
+// CGuiScreenLetterBox::OnAccept
+//===========================================================================
+// Description: If necessary, stop conversation. Then, start mission.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLetterBox::OnAccept()
+{
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT ); // sound effect
+
+ // skip conversation in case it's still playing
+ //
+ GetEventManager()->TriggerEvent( EVENT_CONVERSATION_SKIP );
+/*
+ // send event to dialog objective to indicate that user has accepted
+ // the mission
+ //
+ GetEventManager()->TriggerEvent( EVENT_CONVERSATION_DONE_AND_FINISHED );
+*/
+}
+
+//===========================================================================
+// CGuiScreenLetterBox::OnCancel
+//===========================================================================
+// Description: If necessary, stop conversation. Then, return to sunday
+// drive.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLetterBox::OnCancel()
+{
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); // sound effect
+
+ // don't listen to this event on cancelling
+ //
+ GetEventManager()->RemoveListener( this, EVENT_CONVERSATION_DONE );
+
+ // skip conversation in case it's still playing
+ //
+ GetEventManager()->TriggerEvent( EVENT_CONVERSATION_SKIP );
+
+ if( GetGameplayManager()->IsBonusMissionDesired() )
+ {
+ // cancel bonus mission
+ //
+ GetGameplayManager()->CancelBonusMission();
+ }
+ else
+ {
+ // go back a stage in sunday drive mode
+ //
+ GetGameplayManager()->GetCurrentMission()->PrevStage();
+ GetGameplayManager()->GetCurrentMission()->GetCurrentStage()->Start();
+ }
+
+ this->ForceOpen();
+
+ GetInputManager()->SetGameState(Input::ACTIVE_GAMEPLAY);
+ m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME );
+}
+
+//===========================================================================
+// CGuiScreenLetterBox::OnSkip
+//===========================================================================
+// Description: Skip NIS conversation.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLetterBox::OnSkip()
+{
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT ); // sound effect
+
+ // skip conversation in case it's still playing
+ //
+ GetEventManager()->TriggerEvent( EVENT_CONVERSATION_SKIP );
+}
+
+//===========================================================================
+// CGuiScreenLetterBox::SetIntroFromClosed
+//===========================================================================
+// Description: sets things up so the letterbox opens from the start
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLetterBox::SetIntroFromClosed()
+{
+ g_TopIn.SetCoordsStart( 0, 0 );
+ g_TopIn.SetCoordsEnd( 0, 240 - 70 );
+ g_TopIn.SetTimeInterval( BAR_SLIDING_TIME );
+ g_BottomIn.SetCoordsStart( 0, 0 );
+ g_BottomIn.SetCoordsEnd( 0, -240 + 70 );
+ g_BottomIn.SetTimeInterval( BAR_SLIDING_TIME );
+ m_topBar->ResetTransformation();
+ m_topBar->Translate( 0, 0 );
+ m_bottomBar->ResetTransformation();
+ m_bottomBar->Translate( 0, 0 );
+}
+
+//===========================================================================
+// CGuiScreenLetterBox::SetIntroFromOpen
+//===========================================================================
+// Description: sets things up so the letterbox closes a little from the start
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLetterBox::SetIntroFromOpen()
+{
+ g_TopIn.SetCoordsStart( 0, 240 );
+ g_TopIn.SetCoordsEnd( 0, 240 - 70 );
+ g_TopIn.SetTimeInterval( BAR_SLIDING_TIME );
+ g_BottomIn.SetCoordsStart( 0, -240 );
+ g_BottomIn.SetCoordsEnd( 0, -240 + 70 );
+ g_BottomIn.SetTimeInterval( BAR_SLIDING_TIME );
+}
+
+#ifdef DEBUGWATCH
+const char* CGuiScreenLetterBox::GetWatcherName() const
+{
+ return "CGuiScreenLetterBox";
+}
+#endif \ No newline at end of file
diff --git a/game/code/presentation/gui/ingame/guiscreenletterbox.h b/game/code/presentation/gui/ingame/guiscreenletterbox.h
new file mode 100644
index 0000000..f7ddc46
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenletterbox.h
@@ -0,0 +1,101 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLetterBox
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/21 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENLETTERBOX_H
+#define GUISCREENLETTERBOX_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <presentation/gui/ingame/guiscreenhastransitions.h>
+#include <presentation/gui/utility/transitions.h>
+
+#include <events/eventlistener.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+namespace Scrooby
+{
+ class Group;
+}
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenLetterBox :
+ public CGuiScreen,
+ public CGuiScreenHasTransitions,
+ public EventListener
+{
+public:
+ CGuiScreenLetterBox( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenLetterBox();
+ static void ForceOpen();
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual void HandleEvent( EventEnum id, void* pEventData );
+
+ static void SurpressSkipButton();
+ static void UnSurpressSkipButton();
+
+ static void SuppressAcceptCancelButtons( bool suppress = true );
+ void CheckIfScreenShouldBeBlank();
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+ void SetIntroFromClosed();
+ void SetIntroFromOpen();
+ #ifdef DEBUGWATCH
+ virtual const char* GetWatcherName() const;
+ #endif
+
+
+private:
+ void OnAccept();
+ void OnCancel();
+ void OnSkip();
+
+ Scrooby::Page* m_Page;
+ Scrooby::Page* m_IrisPage;
+ Scrooby::Group* m_topBar;
+ Scrooby::Group* m_bottomBar;
+ Scrooby::Group* m_skipButton;
+ Scrooby::Group* m_skipLabel;
+ Scrooby::Pure3dObject* m_Iris;
+
+ unsigned int m_elapsedTime;
+ static bool m_enableReopen;
+ static bool m_forceOpen;
+ bool m_OutroPending : 1;
+ GuiSFX::Pause s_OutroPauseBetweenCloseAndIris;
+ GuiSFX::Show s_OutroIrisShow;
+ GuiSFX::Hide s_OutroLetterBoxHide;
+ GuiSFX::IrisWipeOpen s_OutroIrisOpen;
+
+ static bool s_suppressAcceptCancelButtons;
+
+};
+
+inline void CGuiScreenLetterBox::SuppressAcceptCancelButtons( bool suppress )
+{
+ s_suppressAcceptCancelButtons = suppress;
+}
+
+#endif // GUISCREENLETTERBOX_H
diff --git a/game/code/presentation/gui/ingame/guiscreenlevelend.cpp b/game/code/presentation/gui/ingame/guiscreenlevelend.cpp
new file mode 100644
index 0000000..ff5a557
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenlevelend.cpp
@@ -0,0 +1,202 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLevelEnd
+//
+// Description: Implementation of the CGuiScreenLevelEnd class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/10 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenlevelend.h>
+
+#include <data/memcard/memorycardmanager.h>
+#include <events/eventmanager.h>
+#include <memory/srrmemory.h>
+#include <mission/gameplaymanager.h>
+
+// Scrooby
+//
+#include <screen.h>
+#include <page.h>
+#include <text.h>
+
+// ATG
+//
+#include <raddebug.hpp>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenLevelEnd::CGuiScreenLevelEnd
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLevelEnd::CGuiScreenLevelEnd
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreenLevelStats( pScreen, pParent, GUI_SCREEN_ID_LEVEL_END )
+{
+}
+
+
+//===========================================================================
+// CGuiScreenLevelEnd::~CGuiScreenLevelEnd
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLevelEnd::~CGuiScreenLevelEnd()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenLevelEnd::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLevelEnd::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ m_pParent->HandleMessage( GUI_MSG_QUIT_INGAME_FOR_RELOAD,
+ GetGameplayManager()->GetCurrentLevelIndex() + 1,
+ 0 );
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenLevelEnd::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLevelEnd::InitIntro()
+{
+ // set heading to "Level Complete"
+ //
+ rAssert( m_levelStatsHeading != NULL );
+ m_levelStatsHeading->SetIndex( 1 );
+
+ // show "use mission select" info text
+ //
+ if( m_useMissionSelect != NULL )
+ {
+ m_useMissionSelect->SetVisible( true );
+ }
+
+ // update current level stats
+ //
+ this->UpdateLevelStats();
+
+ // load memory card info (in case user decides to save before advancing
+ // to next level)
+ //
+ GetMemoryCardManager()->LoadMemcardInfo( dynamic_cast<IMemoryCardInfoLoadCallback*>( m_pParent ) );
+}
+
+
+//===========================================================================
+// CGuiScreenLevelEnd::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLevelEnd::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenLevelEnd::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLevelEnd::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/ingame/guiscreenlevelend.h b/game/code/presentation/gui/ingame/guiscreenlevelend.h
new file mode 100644
index 0000000..861b2e2
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenlevelend.h
@@ -0,0 +1,48 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLevelEnd
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/10 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENLEVELEND_H
+#define GUISCREENLEVELEND_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenlevelstats.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenLevelEnd : public CGuiScreenLevelStats
+{
+public:
+ CGuiScreenLevelEnd( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenLevelEnd();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+};
+
+#endif // GUISCREENLEVELEND_H
diff --git a/game/code/presentation/gui/ingame/guiscreenlevelstats.cpp b/game/code/presentation/gui/ingame/guiscreenlevelstats.cpp
new file mode 100644
index 0000000..13f7ae3
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenlevelstats.cpp
@@ -0,0 +1,270 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLevelStats
+//
+// Description: Implementation of the CGuiScreenLevelStats class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/10 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenlevelstats.h>
+
+#include <cards/cardgallery.h>
+#include <memory/srrmemory.h>
+#include <mission/gameplaymanager.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <mission/rewards/rewardsmanager.h>
+#include <render/enums/renderenums.h>
+
+// Scrooby
+//
+#include <screen.h>
+#include <page.h>
+#include <group.h>
+#include <text.h>
+
+// ATG
+//
+#include <raddebug.hpp>
+
+#include <string.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenLevelStats::CGuiScreenLevelStats
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLevelStats::CGuiScreenLevelStats
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent,
+ eGuiWindowID windowID
+)
+: CGuiScreen( pScreen, pParent, windowID ),
+ m_levelStatsHeading( NULL ),
+ m_useMissionSelect( NULL )
+{
+ memset( m_levelStats, 0, sizeof( m_levelStats ) );
+
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "LevelStats" );
+ rAssert( pPage != NULL );
+
+ this->AutoScaleFrame( pPage );
+
+ m_levelStatsHeading = pPage->GetText( "LevelProgress" );
+ rAssert( m_levelStatsHeading != NULL );
+
+ Scrooby::Group* pGroup = pPage->GetGroup( "Stats" );
+ rAssert( pGroup != NULL );
+
+ m_levelStats[ STAT_STORY_MISSIONS ] = pGroup->GetText( "StoryMissions_Unlocked" );
+ m_levelStats[ STAT_BONUS_MISSIONS ] = pGroup->GetText( "BonusMissions_Unlocked" );
+ m_levelStats[ STAT_STREET_RACES ] = pGroup->GetText( "StreetRaces_Unlocked" );
+ m_levelStats[ STAT_CARDS ] = pGroup->GetText( "Cards_Unlocked" );
+ m_levelStats[ STAT_CLOTHING ] = pGroup->GetText( "Clothing_Unlocked" );
+ m_levelStats[ STAT_VEHICLES ] = pGroup->GetText( "Vehicles_Unlocked" );
+ m_levelStats[ STAT_WASPS ] = pGroup->GetText( "Wasps_Unlocked" );
+ m_levelStats[ STAT_GAGS ] = pGroup->GetText( "Gags_Unlocked" );
+ m_levelStats[ STAT_LEVEL_COMPLETE ] = pGroup->GetText( "LevelComplete_Value" );
+
+#ifdef RAD_DEBUG
+ for( int i = 0; i < NUM_LEVEL_STATS; i++ )
+ {
+ rAssert( m_levelStats[ i ] != NULL );
+ }
+#endif
+
+ m_useMissionSelect = pPage->GetText( "UseMissionSelect" );
+ if( m_useMissionSelect != NULL )
+ {
+ m_useMissionSelect->SetVisible( false ); // hide by default
+
+ m_useMissionSelect->SetTextMode( Scrooby::TEXT_WRAP );
+ m_useMissionSelect->SetDisplayOutline( true );
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenLevelStats::~CGuiScreenLevelStats
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenLevelStats::~CGuiScreenLevelStats()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenLevelStats::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLevelStats::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_START:
+ {
+ m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenLevelStats::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLevelStats::InitIntro()
+{
+ // update current level stats
+ //
+ this->UpdateLevelStats();
+}
+
+
+//===========================================================================
+// CGuiScreenLevelStats::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLevelStats::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenLevelStats::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenLevelStats::InitOutro()
+{
+}
+
+
+void
+CGuiScreenLevelStats::UpdateLevelStats()
+{
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ char buffer[ 32 ];
+ RenderEnums::LevelEnum currentLevel = GetGameplayManager()->GetCurrentLevelIndex();
+
+ sprintf( buffer, "%d / %d", GetCharacterSheetManager()->QueryNumMissionsCompleted( currentLevel ), 7 );
+ m_levelStats[ STAT_STORY_MISSIONS ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%d / %d", GetCharacterSheetManager()->QueryBonusMissionCompleted( currentLevel ) ? 1 : 0, 1 );
+ m_levelStats[ STAT_BONUS_MISSIONS ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%d / %d", GetCharacterSheetManager()->QueryNumStreetRacesCompleted( currentLevel ), 3 );
+ m_levelStats[ STAT_STREET_RACES ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%d / %d", GetCardGallery()->GetCollectedCards( currentLevel )->m_numCards, 7 );
+ m_levelStats[ STAT_CARDS ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%d / %d", GetCharacterSheetManager()->QueryNumSkinsUnlocked( currentLevel ), 3 );
+ m_levelStats[ STAT_CLOTHING ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%d / %d", GetCharacterSheetManager()->QueryNumCarUnlocked( currentLevel ), 5 );
+ m_levelStats[ STAT_VEHICLES ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%d / %d", GetCharacterSheetManager()->QueryNumWaspsDestroyed( currentLevel ),
+ GetRewardsManager()->GetTotalWasps( currentLevel ) );
+ m_levelStats[ STAT_WASPS ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%d / %d", GetCharacterSheetManager()->QueryNumGagsViewed( currentLevel ),
+ GetRewardsManager()->GetTotalGags( currentLevel ) );
+ m_levelStats[ STAT_GAGS ]->SetString( 0, buffer );
+
+ sprintf( buffer, "%.1f %%", GetCharacterSheetManager()->QueryPercentLevelCompleted( currentLevel ) );
+ m_levelStats[ STAT_LEVEL_COMPLETE ]->SetString( 0, buffer );
+
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/ingame/guiscreenlevelstats.h b/game/code/presentation/gui/ingame/guiscreenlevelstats.h
new file mode 100644
index 0000000..8c1051d
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenlevelstats.h
@@ -0,0 +1,71 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenLevelStats
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/10 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENLEVELSTATS_H
+#define GUISCREENLEVELSTATS_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenLevelStats : public CGuiScreen
+{
+public:
+ CGuiScreenLevelStats( Scrooby::Screen* pScreen, CGuiEntity* pParent,
+ eGuiWindowID windowID = GUI_SCREEN_ID_LEVEL_STATS );
+ virtual ~CGuiScreenLevelStats();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+ void UpdateLevelStats();
+
+ enum eLevelStats
+ {
+ STAT_STORY_MISSIONS,
+ STAT_BONUS_MISSIONS,
+ STAT_STREET_RACES,
+ STAT_CARDS,
+ STAT_CLOTHING,
+ STAT_VEHICLES,
+ STAT_WASPS,
+ STAT_GAGS,
+ STAT_LEVEL_COMPLETE,
+
+ NUM_LEVEL_STATS
+ };
+
+ Scrooby::Text* m_levelStatsHeading;
+ Scrooby::Text* m_levelStats[ NUM_LEVEL_STATS ];
+
+ Scrooby::Text* m_useMissionSelect;
+
+};
+
+#endif // GUISCREENLEVELSTATS_H
diff --git a/game/code/presentation/gui/ingame/guiscreenmissionbase.cpp b/game/code/presentation/gui/ingame/guiscreenmissionbase.cpp
new file mode 100644
index 0000000..bfdcf48
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenmissionbase.cpp
@@ -0,0 +1,1419 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMissionLoad
+//
+// Description: Implementation of the CGuiScreenMissionSuccess class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/04/07 ian gipson Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <camera/animatedcam.h>
+#include <camera/supercammanager.h>
+#include <events/eventmanager.h>
+#include <gameflow/gameflow.h>
+#include <memory/classsizetracker.h>
+#include <mission/gameplaymanager.h>
+#include <mission/objectives/coinobjective.h>
+#include <mission/objectives/raceobjective.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <mission/missionmanager.h>
+#include <p3d/imagefactory.hpp>
+#include <p3d/sprite.hpp>
+#include <presentation/gui/ingame/guiscreenmissionbase.h>
+#include <presentation/gui/ingame/guiscreenmissionselect.h>
+#include <presentation/gui/utility/transitions.h>
+#include <sound/soundmanager.h>
+#include <worldsim/redbrick/vehicle.h>
+#include <worldsim/coins/coinmanager.h>
+#include <worldsim/worldphysicsmanager.h>
+#include <worldsim/character/charactermanager.h>
+
+#include <ai/actor/actormanager.h>
+
+#include <group.h>
+#include <layer.h>
+#include <page.h>
+#include <polygon.h>
+#include <pure3dobject.h>
+#include <screen.h>
+#include <sprite.h>
+#include <text.h>
+
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+#define CLIP_PAUSE_TIME 300.0f
+#define CLIP_MOVE_TIME 300.0f
+
+
+//Chuck
+//Intialize the special case patty and selma screen pointer
+tSprite* CGuiScreenMissionBase::sp_PattyAndSelmaScreenPNG = NULL;
+
+char CGuiScreenMissionBase::s_AnimatedBitmapName[ 256 ] = "";
+char CGuiScreenMissionBase::s_AnimatedBitmapShortName[ 32 ] = "";
+tSprite* CGuiScreenMissionBase::s_AnimatedBitmapSprite = NULL;
+bool CGuiScreenMissionBase::s_BitmapLoadPending = false;
+
+static tColour g_BackgroundColorLeft( 255, 255, 255, 255 );
+static tColour g_BackgroundColorRight( 255, 255, 255, 255 );
+
+const tColour g_BackgroundBlue ( 59, 76, 129 );
+const tColour g_BackgroundRed ( 100, 6, 6 );
+const tColour g_BackgroundGreen( 7, 73, 30 );
+
+const tColour g_ColorNormalLeft ( 255, 255, 255, 255 );
+const tColour g_ColorNormalRight( 255, 255, 255, 255 );
+const tColour g_ColorBonusLeft ( 255, 255, 255, 255 );
+const tColour g_ColorBonusRight ( 255, 255, 255, 255 );
+const tColour g_ColorRaceLeft ( 255, 255, 255, 255 );
+const tColour g_ColorRaceRight ( 255, 255, 255, 255 );
+const tColour g_ColorWagerLeft ( 255, 255, 255, 255 );
+const tColour g_ColorWagerRight ( 255, 255, 255, 255 );
+
+GuiSFX::Dummy g_IntroStart( "IntroStart" );
+GuiSFX::Junction3 g_IntroJunction;
+GuiSFX::Show g_ForegroundShow( "ForeGroundShow" );
+GuiSFX::Show g_ClipLeftShow( "ClipLeftShow" );
+GuiSFX::PauseInFrames g_IntroPause( "Pause" );
+GuiSFX::Translator g_ScreenSlideIn( "ScreenSlideIn" );
+GuiSFX::Pause g_ClipLeftPause( "ClipLeftPause" );
+GuiSFX::Translator g_ClipLeftSlideOut( "ClipLeftSlideOut" );
+GuiSFX::Hide g_ClipLeftHide( "ClipLeftHide" );
+GuiSFX::Show g_BackgroundShow( "BackgroundShow" );
+GuiSFX::ColorChange g_DarkenPolyFade( "DarkenPolyFade" );
+
+GuiSFX::Dummy g_OutroStart( "OutroStart" );
+GuiSFX::Junction3 g_OutroJunction;
+GuiSFX::Translator g_OutroBottomOut( "OutroBottomOut" );
+GuiSFX::Translator g_OutroTopOut( "OutroTopOut" );
+GuiSFX::Show g_ClipRightShow( "ClipRightShow" );
+GuiSFX::Pause g_ClipRightPause( "ClipRightPause" );
+GuiSFX::Translator g_ClipRightSlideIn( "ClipRightSlideIn" );
+GuiSFX::Translator g_ScreenSlideOut( "ScreenSlideOut" );
+GuiSFX::Hide g_OutroHideEverything( "OutroHideEverything" );
+GuiSFX::Dummy g_OutroDone( "OutroDone" );
+
+GuiSFX::IrisWipeOpen g_IrisOpen( "IrisOpen" );
+GuiSFX::IrisWipeOpen g_IrisClose( "IrisClose" );
+
+GuiSFX::PulseScale g_TitlePulse( "TitlePulse" );
+
+const float VEHICLE_ODDS_HARD_THRESHOLD = 3.0f;
+const float VEHICLE_ODDS_MEDIUM_THRESHOLD = 2.0f;
+
+#ifdef RAD_WIN32
+const float MISSION_BITMAP_CORRECTION_SCALE = 0.67f;
+#endif
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenMissionSuccess::CGuiScreenMissionSuccess
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMissionBase::CGuiScreenMissionBase( Scrooby::Screen* pScreen, CGuiEntity* pParent, eGuiWindowID id ):
+ CGuiScreen( pScreen, pParent, id ),
+ m_missionTitle( NULL ),
+ m_loadCompleted( NULL ),
+ m_PlayAnimatedCamera( false ),
+ m_gamblingInfo( NULL ),
+ m_gamblingEntryFee( NULL ),
+ m_gamblingTimeToBeat( NULL ),
+ m_gamblingBestTime( NULL ),
+ m_gamblingVehicleOdds( NULL ),
+ m_gamblingPayout( NULL ),
+ m_ReadyToExitScreen( false )
+{
+ CLASSTRACKER_CREATE( CGuiScreenMissionBase );
+
+ unsigned char* leftChar = reinterpret_cast< unsigned char* >( &g_BackgroundColorLeft );
+ radDbgWatchAddUnsignedChar( leftChar + 2, "Red", "gui\\missionloading\\left" );
+ radDbgWatchAddUnsignedChar( leftChar + 1, "Green", "gui\\missionloading\\left" );
+ radDbgWatchAddUnsignedChar( leftChar + 0, "Blue", "gui\\missionloading\\left" );
+ //radDbgWatchAddUnsignedChar( leftChar + 3, "Alpha", "gui\\missionloading\\left" );
+
+ unsigned char* rightChar = reinterpret_cast< unsigned char* >( &g_BackgroundColorRight );
+ radDbgWatchAddUnsignedChar( rightChar + 2, "Red", "gui\\missionloading\\right" );
+ radDbgWatchAddUnsignedChar( rightChar + 1, "Green", "gui\\missionloading\\right" );
+ radDbgWatchAddUnsignedChar( rightChar + 0, "Blue", "gui\\missionloading\\right" );
+ //radDbgWatchAddUnsignedChar( rightChar + 3, "Alpha", "gui\\missionloading\\right" );
+
+
+
+
+ //
+ // Add All the transitions to the screen
+ //
+ AddTransition( g_DarkenPolyFade );
+ AddTransition( g_TitlePulse );
+ AddTransition( g_ScreenSlideIn );
+ AddTransition( g_ScreenSlideOut );
+ AddTransition( g_ClipLeftSlideOut );
+ AddTransition( g_ClipRightSlideIn );
+ AddTransition( g_OutroBottomOut );
+ AddTransition( g_OutroTopOut );
+ AddTransition( g_IntroPause );
+ AddTransition( g_ClipLeftPause );
+ AddTransition( g_ClipRightPause );
+ DoneAddingTransitions();
+
+ //
+ // Retrieve the Scrooby drawing elements.
+ //
+
+ //
+ // Iris wipe stuff
+ //
+ Scrooby::Page* irisPage;
+ irisPage = m_pScroobyScreen->GetPage( "3dIris" );
+ rAssert( irisPage != NULL );
+
+ m_Iris = irisPage->GetPure3dObject( "p3d_iris" );
+ rAssert( m_Iris != NULL );
+
+ m_MultiController = p3d::find< tMultiController >( "IrisController" );
+ rAssert( m_MultiController );
+ m_irisWipeNumFrames = m_MultiController->GetNumFrames();
+
+ //
+ // Functional page stuff
+ //
+
+ Scrooby::Layer* overlay;
+
+ //
+ // Get the elements out of scrooby
+ //
+ m_Page = m_pScroobyScreen->GetPage( "MissionLoad" ); rAssert( m_Page != NULL );
+ m_LetterboxPage = m_pScroobyScreen->GetPage( "LetterBox" ); rAssert( m_LetterboxPage != NULL );
+ m_FgLayer = m_Page-> GetGroup( "foreground" ); rAssert( m_FgLayer != NULL );
+ m_loadCompleted = m_Page->GetGroup( "LoadCompleted" ); rAssert( m_loadCompleted != NULL );
+ m_Line0 = m_FgLayer->GetText( "MissionInfo" ); rAssert( m_Line0 != NULL );
+ m_missionTitle = m_FgLayer->GetText( "MissionTitle" ); rAssert( m_missionTitle != NULL );
+ m_BgLayer = m_Page->GetLayer( "Background" ); rAssert( m_BgLayer != NULL );
+ m_missionStartBitmap = m_Page->GetSprite( "MissionStartBitmap" ); rAssert( m_missionStartBitmap != NULL);
+ overlay = m_Page->GetLayer( "Overlay" ); rAssert( overlay != NULL );
+ m_darkenPolys = overlay->GetGroup( "dark_polys" ); rAssert( m_darkenPolys != NULL );
+ m_darkenTop = m_LetterboxPage->GetGroup( "TopBar" ); rAssert( m_darkenTop != NULL );
+ m_darkenBottom = m_LetterboxPage->GetGroup( "BottomBar" ); rAssert( m_darkenBottom != NULL );
+ m_backgroundPoly = m_Page->GetPolygon( "background" ); rAssert( m_backgroundPoly!= NULL );
+ m_textOverlays = m_Page->GetGroup( "Text" ); rAssert( m_textOverlays != NULL );
+ m_Flag = m_Page->GetSprite( "flag" ); rAssert( m_Flag != NULL );
+ m_ClipLeftGroup = m_Page->GetGroup( "ClipLeftGroup"); rAssert( m_ClipLeftGroup != NULL );
+ m_ClipRightGroup= m_Page->GetGroup( "ClipRightGroup"); rAssert( m_ClipRightGroup!= NULL );
+ m_ClipLeft = m_Page->GetSprite( "clipLeft" ); rAssert( m_ClipLeft != NULL );
+ m_ClipRight = m_Page->GetSprite( "clipRight1"); rAssert( m_ClipRight != NULL );
+ m_ClipLeftArm = m_Page->GetSprite( "clipArmLeft1" ); rAssert( m_ClipLeftArm != NULL );
+ m_ClipRightArm = m_Page->GetSprite( "clipArmRight1" ); rAssert( m_ClipRightArm != NULL );
+ m_Foreground = m_Page->GetLayer( "Background" ); rAssert( m_Foreground != NULL );
+ m_LetterboxLayer=m_LetterboxPage->GetLayer( "Background" ); rAssert( m_LetterboxLayer!= NULL );
+
+ if( IsWideScreenDisplay() )
+ {
+ m_Page->ResetTransformation();
+ ApplyWideScreenCorrectionScale( m_Page );
+ }
+
+
+ m_buttonIcons[ BUTTON_ICON_ACCEPT ] = m_loadCompleted->GetGroup( "Continue" );
+ m_buttonIcons[ BUTTON_ICON_BACK ] = m_loadCompleted->GetGroup( "Abort" );
+
+ //
+ // add some scrooby elements to the watcher
+ //
+ const char* screenName = GetWatcherName();
+
+ #ifdef DEBUGWATCH
+ m_missionStartBitmap-> WatchAll( screenName );
+ m_missionTitle-> WatchAll( screenName );
+ m_Line0-> WatchAll( screenName );
+ m_LetterboxPage-> WatchAll( screenName );
+ m_LetterboxLayer-> WatchAll( screenName );
+ m_darkenTop-> WatchAll( screenName );
+ m_darkenBottom-> WatchAll( screenName );
+ m_Flag-> WatchAll( screenName );
+ m_ClipLeft-> WatchAll( screenName );
+ m_ClipRight-> WatchAll( screenName );
+ m_ClipLeftArm-> WatchAll( screenName );
+ m_ClipRightArm-> WatchAll( screenName );
+ m_ClipLeftGroup-> WatchAll( screenName );
+ m_ClipRightGroup-> WatchAll( screenName );
+ #endif
+
+ this->SetFadingEnabled( false );
+ m_ClipRight->Scale( -1.0f, 1.0f, 1.0f );
+
+ // Get gambling info group and text
+ //
+ m_gamblingInfo = m_Page->GetGroup( "GamblingInfo" );
+ rAssert( m_gamblingInfo != NULL );
+
+ m_gamblingEntryFee = m_gamblingInfo->GetText( "EntryFee_Value" );
+ m_gamblingTimeToBeat = m_gamblingInfo->GetText( "TimeToBeat_Value" );
+ m_gamblingBestTime = m_gamblingInfo->GetText( "BestTime_Value" );
+ m_gamblingVehicleOdds = m_gamblingInfo->GetText( "VehicleOdds_Value" );
+ m_gamblingPayout = m_gamblingInfo->GetText( "Payout_Value" );
+
+ g_BackgroundColorLeft = m_backgroundPoly->GetVertexColour( 0 );
+ g_BackgroundColorRight = m_backgroundPoly->GetVertexColour( 2 );
+
+ m_Flag->ResizeToBoundingBox();
+
+ //
+ // Set Up Transitions
+ //
+
+ // Continuous
+ g_TitlePulse.SetDrawable( m_textOverlays );
+ g_TitlePulse.Activate();
+ g_TitlePulse.SetAmplitude( 0.05f );
+ g_TitlePulse.SetFrequency( 2.0f );
+ WATCH( g_TitlePulse, GetWatcherName() );
+
+ // Intro
+ WATCH( g_IntroStart, GetWatcherName() );
+
+ g_ForegroundShow.SetDrawable( m_Foreground );
+
+ g_ClipLeftShow.SetDrawable( m_ClipLeftGroup );
+
+ g_IntroPause.SetNumberOfFrames( 1 );
+
+ g_ScreenSlideIn.SetDrawable( m_Foreground );
+ g_ScreenSlideIn.SetStartOffscreenLeft( m_Foreground );
+ g_ScreenSlideIn.SetTimeInterval( 400.0f );
+ WATCH( g_ScreenSlideIn, GetWatcherName() );
+
+ g_ClipLeftPause.SetTimeInterval( CLIP_PAUSE_TIME );
+ WATCH( g_ClipLeftPause, GetWatcherName() );
+
+ g_ClipLeftSlideOut.SetDrawable( m_ClipLeftGroup );
+ g_ClipLeftSlideOut.SetEndOffscreenLeft( m_ClipLeftGroup );
+ g_ClipLeftSlideOut.SetTimeInterval( CLIP_MOVE_TIME );
+ WATCH( g_ClipLeftSlideOut, GetWatcherName() );
+
+ g_ClipLeftHide.SetDrawable( m_ClipLeftGroup );
+
+ // Outro
+ WATCH( g_OutroStart, GetWatcherName() );
+
+ g_ClipRightShow.SetDrawable( m_ClipRightGroup );
+
+ g_OutroTopOut.SetDrawable( m_darkenTop );
+ g_OutroTopOut.SetEndOffscreenTop( m_darkenTop );
+ g_OutroTopOut.SetTimeInterval( 1000.0f );
+ WATCH( g_OutroTopOut, GetWatcherName() );
+
+ g_OutroBottomOut.SetDrawable( m_darkenBottom );
+ g_OutroBottomOut.SetEndOffscreenBottom( m_darkenBottom );
+ g_OutroBottomOut.SetTimeInterval( 1000.0f );
+ WATCH( g_OutroBottomOut, GetWatcherName() );
+
+ g_ClipRightSlideIn.SetDrawable( m_ClipRightGroup );
+ g_ClipRightSlideIn.SetStartOffscreenRight( m_ClipRightGroup );
+ g_ClipRightSlideIn.SetTimeInterval( CLIP_MOVE_TIME );
+ WATCH( g_ClipRightSlideIn, GetWatcherName() );
+
+ g_ClipRightPause.SetTimeInterval( CLIP_PAUSE_TIME );
+ WATCH( g_ClipRightPause, GetWatcherName() );
+
+ g_ScreenSlideOut.SetDrawable( m_Foreground );
+ g_ScreenSlideOut.SetEndOffscreenRight( m_Foreground );
+ g_ScreenSlideOut.SetTimeInterval( 400.0f );
+ WATCH( g_ScreenSlideOut, GetWatcherName() );
+
+ g_BackgroundShow.SetDrawable( m_BgLayer );
+
+ g_DarkenPolyFade.SetDrawable( m_darkenPolys );
+ g_DarkenPolyFade.SetStartColour( tColour( 255, 255, 255, 255 ) );
+ g_DarkenPolyFade.SetEndColour( tColour( 255, 255, 255, 0 ) );
+ g_DarkenPolyFade.SetTimeInterval( 100.0f );
+
+ g_OutroHideEverything.SetDrawable( m_Foreground );
+
+ m_missionStartBitmap->SetRawSprite( NULL );
+#ifdef RAD_WIN32
+ m_missionStartBitmap->ResetTransformation();
+ m_missionStartBitmap->ScaleAboutCenter( MISSION_BITMAP_CORRECTION_SCALE );
+ m_missionStartBitmap->Translate( -71, -32 ); // These are trial & error numbers that hopefully work.
+#endif
+
+ // text wrap mission info title and description
+ //
+ m_missionTitle->SetTextMode( Scrooby::TEXT_WRAP );
+ m_Line0->SetTextMode( Scrooby::TEXT_WRAP );
+
+ //
+ // Set up transitions for lines of text
+ //
+
+ //
+ // Transition sequencing
+ //
+ g_IntroStart. SetNextTransition( g_IntroJunction );
+ g_IntroJunction. SetNextTransition( 0, g_IntroPause );
+ g_IntroJunction. SetNextTransition( 1, g_ClipLeftShow );
+ g_IntroJunction. SetNextTransition( 2, g_ScreenSlideIn );
+ g_ForegroundShow. SetNextTransition( NULL );
+ g_ClipLeftShow. SetNextTransition( NULL );
+ g_IntroPause. SetNextTransition( g_ForegroundShow );
+ g_ScreenSlideIn. SetNextTransition( g_ClipLeftPause );
+ g_ClipLeftPause. SetNextTransition( g_ClipLeftSlideOut );
+ g_ClipLeftSlideOut. SetNextTransition( g_ClipLeftHide );
+ g_ClipLeftHide. SetNextTransition( g_BackgroundShow );
+ g_BackgroundShow. SetNextTransition( g_DarkenPolyFade );
+ g_DarkenPolyFade. SetNextTransition( NULL );
+
+ g_OutroStart. SetNextTransition( g_OutroJunction );
+ g_OutroJunction. SetNextTransition( 0, g_ClipRightShow );
+ g_OutroJunction. SetNextTransition( 1, g_OutroBottomOut );
+ g_OutroJunction. SetNextTransition( 2, g_OutroTopOut );
+ g_OutroBottomOut. SetNextTransition( NULL );
+ g_OutroTopOut. SetNextTransition( NULL );
+ g_ClipRightShow. SetNextTransition( g_ClipRightSlideIn );
+ g_ClipRightSlideIn. SetNextTransition( g_ClipRightPause );
+ g_ClipRightPause. SetNextTransition( g_ScreenSlideOut );
+ g_ScreenSlideOut. SetNextTransition( g_OutroHideEverything );
+ g_OutroHideEverything. SetNextTransition( g_OutroDone );
+ g_OutroDone. SetNextTransition( NULL );
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::~CGuiScreenMissionBase
+//===========================================================================
+// Description: destructor
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMissionBase::~CGuiScreenMissionBase()
+{
+ CLASSTRACKER_DESTROY( CGuiScreenMissionBase );
+ if( s_AnimatedBitmapSprite)
+ {
+ tRefCounted::Release(s_AnimatedBitmapSprite);
+ }
+
+ //Chuck release the special patty and selma screen if we are still holding on to it.
+ if(sp_PattyAndSelmaScreenPNG)
+ {
+ tRefCounted::Release(sp_PattyAndSelmaScreenPNG);
+ sp_PattyAndSelmaScreenPNG = NULL;
+ }
+ s_BitmapLoadPending = false;
+ p3d::inventory->RemoveSectionElements( tEntity::MakeUID( "DynamicHud" ) );
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::ClearBitmap
+//===========================================================================
+// Description: clears the currently loaded animated bitmap
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: pointer to the abort bitmap group
+//
+//===========================================================================
+void CGuiScreenMissionBase::ClearBitmap()
+{
+ s_AnimatedBitmapSprite = NULL;
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::GetAbortBitmap
+//===========================================================================
+// Description: Allows access to the stored group pointer
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: pointer to the abort bitmap group
+//
+//===========================================================================
+Scrooby::Group* CGuiScreenMissionBase::GetAbortBitmap()
+{
+ return m_buttonIcons[ BUTTON_ICON_BACK ];
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::GetBitmapName
+//===========================================================================
+// Description: Allows access to the name of the mission briefing pic
+//
+// Constraints: None.
+//
+// Parameters: buffer - filled in with the name
+//
+// Return: pointer to the flag
+//
+//===========================================================================
+void CGuiScreenMissionBase::GetBitmapName( char* buffer )
+{
+ if( buffer != NULL )
+ {
+ ::strcpy( buffer, s_AnimatedBitmapName );
+ }
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::GetFlag
+//===========================================================================
+// Description: Allows access to the flag bitmap
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: pointer to the flag
+//
+//===========================================================================
+Scrooby::Drawable* CGuiScreenMissionBase::GetFlag()
+{
+ return m_Flag;
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::GetLoadCompletedGroup
+//===========================================================================
+// Description: Allows access to the stored group pointer
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: pointer to the pace
+//
+//===========================================================================
+Scrooby::Group* CGuiScreenMissionBase::GetLoadCompletedGroup()
+{
+ return m_loadCompleted;
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::GetMissionInfoText
+//===========================================================================
+// Description: Allows access to the stored text pointer
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: pointer to the text
+//
+//===========================================================================
+Scrooby::Text* CGuiScreenMissionBase::GetMissionInfoText()
+{
+ return m_Line0;
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::GetMissionStartBitmap
+//===========================================================================
+// Description: Allows access to the stored mission start bitmap
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: pointer to the drawable
+//
+//===========================================================================
+Scrooby::BoundedDrawable* CGuiScreenMissionBase::GetMissionStartBitmap()
+{
+ return m_missionStartBitmap;
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::GetPage
+//===========================================================================
+// Description: Allows access to the stored page pointer
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: pointer to the pace
+//
+//===========================================================================
+Scrooby::Page* CGuiScreenMissionBase::GetPage()
+{
+ return m_Page;
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::GetPage
+//===========================================================================
+// Description: Allows access to the stored page pointer
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: pointer to the pace
+//
+//===========================================================================
+Scrooby::Text* CGuiScreenMissionBase::GetTitleText()
+{
+ return m_missionTitle;
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::GetWatcherName
+//===========================================================================
+// Description: Allows access to the stored page pointer
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: pointer to the pace
+//
+//===========================================================================
+const char* CGuiScreenMissionBase::GetWatcherName() const
+{
+ return "GuiScreenMissionBase";
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionBase::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( message == GUI_MSG_UPDATE )
+ {
+ float deltaT = static_cast< float >( param1 );
+ ResetMovableObjects();
+ m_ClipLeftArm->ResizeToBoundingBox();
+ m_ClipRightArm->ResizeToBoundingBox();
+ m_ClipLeftGroup->ResetTransformation();
+ UpdateTransitions( deltaT );
+ m_FgLayer->SetColour( tColour( 255, 255, 255, 255 ) );
+ m_missionStartBitmap->SetColour( tColour( 255, 255, 255, 255 ) );
+ m_backgroundPoly->SetVertexColour( 0, g_BackgroundColorLeft );
+ m_backgroundPoly->SetVertexColour( 1, g_BackgroundColorLeft );
+ m_backgroundPoly->SetVertexColour( 2, g_BackgroundColorRight );
+ m_backgroundPoly->SetVertexColour( 3, g_BackgroundColorRight );
+ }
+
+ if( message == GUI_MSG_WINDOW_EXIT )
+ {
+ }
+
+ if( m_state == GUI_WINDOW_STATE_INTRO )
+ {
+ if( message == GUI_MSG_UPDATE )
+ {
+// --m_numTransitionsPending; //get us out of the intro state
+ float deltaT = static_cast< float >( param1 );
+ UpdateAnimatedBitmap( deltaT );
+ }
+ }
+
+ if( m_state == GUI_WINDOW_STATE_OUTRO )
+ {
+ if( message == GUI_MSG_UPDATE )
+ {
+ if( g_OutroDone.IsDone() )
+ {
+ --m_numTransitionsPending;
+ OutroDone();
+ }
+ }
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ UpdateAnimatedBitmap( static_cast< float >( param1 ) );
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ };
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionBase::InitIntro()
+{
+ m_ReadyToExitScreen = false;
+ if( ( !s_BitmapLoadPending ) && ( s_AnimatedBitmapSprite == NULL) )
+ {
+ ReplaceBitmap();
+ }
+
+ //
+ // Need to reset all the transitions
+ //
+ this->SetButtonVisible( BUTTON_ICON_BACK, true );
+ m_LetterboxPage->SetVisible( true );
+ m_Page-> SetVisible( true );
+ m_Line0-> SetVisible( false );
+ m_BgLayer-> SetVisible( true );
+ m_FgLayer-> SetVisible( true );
+ m_Iris-> SetVisible( false );
+ m_missionTitle-> SetVisible( false );
+ m_Flag-> SetVisible( false );
+ m_ClipLeftGroup->SetVisible( true );
+ m_ClipRightGroup->SetVisible( false );
+ m_Foreground-> SetVisible( false );
+ m_darkenPolys-> SetColour( tColour( 255, 255, 255, 255 ) );
+ m_darkenBottom-> ResetTransformation();
+ m_darkenTop-> ResetTransformation();
+ m_ClipLeft-> ResetTransformation();
+
+
+ m_MultiController->Reset();
+ m_MultiController->SetRelativeSpeed( 1.0f );
+ m_MultiController->SetFrameRange( 0.0f, m_irisWipeNumFrames );
+ m_MultiController->SetFrame( 0.0f );
+ unsigned int size = m_textOverlays->Size();
+ unsigned int i;
+ for( i = 0; i < size; ++i )
+ {
+ Scrooby::Drawable* drawable = m_textOverlays->GetChildDrawable( i );
+ drawable->SetVisible( false );
+ }
+
+ ResetTransitions();
+
+ g_IntroStart.Activate();
+ g_OutroStart.DeactivateChain();
+
+ const int currentLevelIndex = GetGameplayManager()->GetCurrentLevelIndex();
+ int currentMissionIndex = GetGameplayManager()->GetCurrentMissionIndex();
+
+ int currentMissionNum = GetGameplayManager()->GetCurrentMissionNum();
+ if( currentMissionNum >= GameplayManager::MAX_MISSIONS )
+ {
+ // current mission must be either a street race or a bonus mission
+ //
+ currentMissionIndex = currentMissionNum - GameplayManager::MAX_MISSIONS +
+ MAX_NUM_REGULAR_MISSIONS;
+ }
+ else
+ {
+ // special case for level 1 due to tutorial mission
+ //
+ if( currentLevelIndex == RenderEnums::L1 )
+ {
+ currentMissionIndex--;
+ }
+
+#ifdef RAD_E3
+ // TC: *** quick and dirty E3 hack!
+ //
+ if( currentLevelIndex == RenderEnums::L2 )
+ {
+ currentMissionIndex = RenderEnums::M5;
+ }
+#endif
+ }
+
+ int textIndex = currentLevelIndex * MAX_NUM_MISSIONS_PER_LEVEL + currentMissionIndex;
+ int missionNumber = textIndex % MAX_NUM_MISSIONS_PER_LEVEL ;
+
+ // special case for level 1 due to tutorial mission
+ //
+ if( currentLevelIndex == 0 )
+ {
+ if( textIndex < 0 ) // meaning it must be the tutorial mission
+ {
+ const int NUM_LEVELS = 7;
+ textIndex = MAX_NUM_MISSIONS_PER_LEVEL * NUM_LEVELS;
+ missionNumber = MAX_NUM_MISSIONS_PER_LEVEL;
+ }
+ }
+
+ m_missionTitle->SetIndex( textIndex );
+ m_Line0->SetIndex( textIndex );
+
+ //
+ // Set the Background Color of the screen
+ //
+ bool bonusMission = GetGameplayManager()->GetCurrentMission()->IsBonusMission();
+ bool raceMission = GetGameplayManager()->GetCurrentMission()->IsRaceMission();
+ bool wagerMission = GetGameplayManager()->GetCurrentMission()->IsWagerMission();
+
+ if( wagerMission )
+ {
+ m_backgroundPoly->SetColour( g_BackgroundGreen );
+ g_BackgroundColorLeft = g_ColorWagerLeft;
+ g_BackgroundColorRight = g_ColorWagerRight;
+ }
+ else if( bonusMission )
+ {
+ m_backgroundPoly->SetColour( g_BackgroundRed );
+ g_BackgroundColorLeft = g_ColorBonusLeft;
+ g_BackgroundColorRight = g_ColorBonusRight;
+ }
+ else if( raceMission )
+ {
+ m_backgroundPoly->SetColour( g_BackgroundBlue );
+ g_BackgroundColorLeft = g_ColorRaceLeft;
+ g_BackgroundColorRight = g_ColorRaceRight;
+ }
+ else
+ {
+ m_backgroundPoly->SetColour( g_BackgroundBlue );
+ g_BackgroundColorLeft = g_ColorNormalLeft;
+ g_BackgroundColorRight = g_ColorNormalRight;
+ }
+
+ if( wagerMission || bonusMission || raceMission )
+ {
+ s_AnimatedBitmapSprite = NULL;
+ //SetBitmapName( NULL );
+ }
+
+ rAssert( m_gamblingInfo != NULL );
+ m_gamblingInfo->SetVisible( false ); // hide by default
+
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, true ); // show by default
+
+ //
+ // Inform the sound manager that it's time to turn the sound down a bit
+ //
+ GetSoundManager()->OnMissionBriefingStart();
+}
+
+//===========================================================================
+// CGuiScreenMissionLoad::InitIntroWagerMission
+//===========================================================================
+// Description: sets up stuff for the wager mission screen
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionBase::InitIntroWagerMission()
+{
+ int textIndex = m_Line0->GetNumOfStrings() - 2;
+ int entryFee = 0; // in coins
+ Mission* currentMission = GetGameplayManager()->GetCurrentMission();
+ rAssert( currentMission != NULL );
+ MissionStage* ms = currentMission->GetStage( 0 );
+ rAssert( ms != NULL );
+ CoinObjective* coinObjective = dynamic_cast<CoinObjective*>( ms->GetObjective() );
+ rAssertMsg( coinObjective != NULL, "No coin objective in first stage!" );
+ entryFee = coinObjective->GetCoinAmount();
+
+ if( entryFee > GetCoinManager()->GetBankValue() )
+ {
+ //
+ // Disable accept button
+ //
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, false );
+
+ //
+ // Change the info text to the "You need (x) coins to continue" message
+ //
+ m_Line0->SetIndex( textIndex );
+ UnicodeString us = m_Line0->GetString( textIndex );
+ char number[ 256 ] = "";
+ sprintf( number, "%d", entryFee );
+ us.Replace( "%D", number );
+
+ m_Line0->SetString( textIndex + 1, us );
+ m_Line0->SetIndex ( textIndex + 1 );
+ }
+}
+
+//===========================================================================
+// CGuiScreenMissionLoad::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionBase::InitOutro()
+{
+ //This is a hack to get the stage setup before we start showing the world after
+ //the mission briefing screen. This simulates a one frame step that sets up and
+ //"starts" the mission before we leave the pause context. NOTE: There may be
+ //seom other managers that need to be run here.
+ GetMissionManager()->Update( 16 );
+ GetSuperCamManager()->GetSCC( 0 )->NoTransition();
+ GetSuperCamManager()->Update( 16, true );
+ GetCharacterManager()->PreSimUpdate( 0.0001f );
+ GetCharacterManager()->PreSubstepUpdate( 0.0001f );
+ GetCharacterManager()->Update( 0.0001f );
+ GetCharacterManager()->PostSubstepUpdate( 0.0001f );
+ GetCharacterManager()->PostSimUpdate( 0.0001f );
+
+ g_OutroDone.Reset();
+ g_OutroStart.Activate();
+ ++m_numTransitionsPending;
+
+ //
+ // Turn the sound back up
+ //
+ GetSoundManager()->OnMissionBriefingEnd();
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionBase::InitRunning()
+{
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::IsCurrentBitmap
+//===========================================================================
+// Description: deetermines if the current bitmap loaded corresponds to this
+// name
+//
+// Constraints: None.
+//
+// Parameters: name - the string name to check.
+//
+// Return: N/A.
+//
+//===========================================================================
+bool CGuiScreenMissionBase::IsCurrentBitmap( const char* name )
+{
+ bool returnMe = ( strcmp( name, s_AnimatedBitmapName ) == 0 );
+ return returnMe;
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::OutroDone
+//===========================================================================
+// Description: called when the outro is done and we're ready to leave this
+// screen
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionBase::OutroDone()
+{
+ UnloadBitmap();
+
+ //
+ // If this is a race, we need to play a camera
+ //
+ if( m_PlayAnimatedCamera )
+ {
+ //
+ // If it's a race mission, don't allow skipping of the animated cam
+ //
+ bool raceMission = GetGameplayManager()->GetCurrentMission()->IsRaceMission();
+ if( raceMission )
+ {
+ AnimatedCam::AllowSkipping( false );
+ AnimatedCam::CheckPendingCameraSwitch();
+
+ //
+ // we need to go to the gameplay context. This is so not cool it almost makes me sick - IAN
+ //
+ GetGameFlow()->SetContext( CONTEXT_GAMEPLAY );
+ }
+ m_PlayAnimatedCamera = false;
+ }
+ else
+ {
+ AnimatedCam::SetCamera( "" );
+ AnimatedCam::SetMulticontroller( "" );
+ }
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::RemoveAnimatedBitmap
+//===========================================================================
+// Description: gets rid of the animated bitmap
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionBase::RemoveAnimatedBitmap()
+{
+ if( s_AnimatedBitmapSprite != NULL )
+ {
+ s_AnimatedBitmapSprite->Release();
+ s_AnimatedBitmapSprite = NULL;
+ }
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::ReplaceBitmap
+//===========================================================================
+// Description: replaces the bitmap with a sprite from a file
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionBase::ReplaceBitmap()
+{
+ p3d::pddi->DrawSync();
+ p3d::inventory->RemoveSectionElements( tEntity::MakeUID( "DynamicHud" ) );
+ RemoveAnimatedBitmap();
+
+ rWarning( s_BitmapLoadPending != true );
+ s_BitmapLoadPending = true;
+ rAssert( strlen( s_AnimatedBitmapName ) != 0 );
+ if( strlen( s_AnimatedBitmapName ) != 0 )
+ {
+ tRefCounted::Release( s_AnimatedBitmapSprite );
+ tFileHandler* fileHandler = p3d::loadManager->GetHandler( "png" );
+ rAssert( fileHandler != NULL );
+ tImageHandler* pngHandler = dynamic_cast< tImageHandler* >( fileHandler );
+ rAssert( pngHandler != NULL );
+ pngHandler->SetLoadType( tImageHandler::SPRITE );
+ LoadingManager::GetInstance()->AddRequest
+ (
+ FILEHANDLER_PURE3D,
+ s_AnimatedBitmapName,
+ GMA_LEVEL_OTHER,
+ "DynamicHud"
+ );
+ }
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::SetBitmapName
+//===========================================================================
+// Description: sets up the name of the animated bitmap that will be loaded
+// for this mission
+//
+// Constraints: None.
+//
+// Parameters: name - string representing the name of this bitmap on disk
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionBase::SetBitmapName( const char* name )
+{
+ //
+ // If we're erasing the bitmap
+ //
+ if( name == NULL )
+ {
+ strcpy( s_AnimatedBitmapName, "" );
+ strcpy( s_AnimatedBitmapShortName, "" );
+ return;
+ }
+
+ //
+ // If we're not really changing anything, early out
+ //
+ if( strcmp( name, s_AnimatedBitmapName ) == 0 )
+ {
+ return;
+ }
+
+ //save the whole filename
+
+ //chuck: we need to somehow release the sprite or
+ //not set the s_AnimatedBitmapSprite = NULL because it
+ //will leak the the patty and selma screen.
+ //tRefCounted::Release(s_AnimatedBitmapSprite);
+
+ //check if our static pointer is to the patty and selma screen
+ if (s_AnimatedBitmapSprite != NULL)
+ {
+// s_AnimatedBitmapSprite->Release();
+
+ if (
+ s_AnimatedBitmapSprite->GetUID() == tName::MakeUID("misXX_PS.png")
+ ||
+ s_AnimatedBitmapSprite->GetUID() == tName::MakeUID("misXX_HW.png")
+ )
+ {
+ //if it is then we make a switch
+ //tRefCounted::Assign(sp_PattyAndSelmaScreenPNG,s_AnimatedBitmapSprite);
+ rAssert(sp_PattyAndSelmaScreenPNG == NULL);
+ sp_PattyAndSelmaScreenPNG = s_AnimatedBitmapSprite;
+ }
+ }
+
+ s_AnimatedBitmapSprite = NULL;
+ size_t length = strlen( name );
+ rAssert( length < sizeof( s_AnimatedBitmapName ) );
+
+ //
+ // If there's no text just return
+ //
+ if( length == 0 )
+ {
+ return;
+ }
+
+ //
+ // if we're not actually changing anything, return
+ //
+ if( strcmp( s_AnimatedBitmapName, name ) == 0 )
+ {
+ return;
+ }
+ strcpy( s_AnimatedBitmapName, name );
+
+ //figure out and save the name of the sprite from the filename
+ if( length >= 12 )
+ {
+ const char* spriteName = name + length - 12;
+ strcpy( s_AnimatedBitmapShortName, spriteName );
+ //s_AnimatedBitmapShortName[ 09 ] = 'p';
+ s_AnimatedBitmapShortName[ 10 ] = 'n';
+ s_AnimatedBitmapShortName[ 11 ] = 'g';
+ }
+ else
+ {
+ strcpy( s_AnimatedBitmapShortName, "" );
+ }
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::SetPlayAnimatedCamera
+//===========================================================================
+// Description: sets a flag to tell us whether or not to play the animated
+// camera after we exit this screen
+//
+// Constraints: None.
+//
+// Parameters: None
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionBase::SetPlayAnimatedCamera( bool play )
+{
+ m_PlayAnimatedCamera = play;
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::StartIrisWipeClose
+//===========================================================================
+// Description: starts the transition to close the iris
+//
+// Constraints: None.
+//
+// Parameters: None
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionBase::StartIrisWipeClose()
+{
+// ++m_numTransitionsPending;
+ m_MultiController->Reset();
+ float frames = m_MultiController->GetNumFrames();
+ m_MultiController->SetFrameRange( 0.0f, frames * 0.5f );
+ m_MultiController->SetFrame( 0.0f );
+}
+//===========================================================================
+// CGuiScreenMissionBase::StartIrisWipeOpen
+//===========================================================================
+// Description: starts the transition to open the iris
+//
+// Constraints: None.
+//
+// Parameters: None
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionBase::StartIrisWipeOpen()
+{
+// ++m_numTransitionsPending;
+ m_MultiController->Reset();
+ float frames = m_MultiController->GetNumFrames();
+ m_MultiController->SetFrameRange( frames * 0.5f, frames );
+ m_MultiController->SetFrame( frames * 0.5f );
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::UnloadBitmap
+//===========================================================================
+// Description: unloads the bitmap, and reclaims all lost memory
+//
+// Constraints: None.
+//
+// Parameters: None
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionBase::UnloadBitmap()
+{
+ p3d::pddi->DrawSync();
+ //::radThreadSleep (500); // Hmmmm, this shouldn't be required
+ tRefCounted::Release( s_AnimatedBitmapSprite );
+ m_missionStartBitmap->SetRawSprite( NULL );
+ m_missionStartBitmap->SetVisible( false );
+}
+
+//===========================================================================
+// CGuiScreenMissionBase::UpdateAnimatedBitmap
+//===========================================================================
+// Description: Updates animation of the bitmap
+//
+// Constraints: None.
+//
+// Parameters: deltaT - how much time has elapsed
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionBase::UpdateAnimatedBitmap( const float deltaT )
+{
+ if( s_AnimatedBitmapSprite == NULL )
+ {
+ p3d::inventory->PushSection();
+
+ p3d::pddi->DrawSync();
+ p3d::inventory->SelectSection( "DynamicHud" );
+ p3d::inventory->SetCurrentSectionOnly( false );
+ tEntityTable* currentSection = p3d::inventory->GetSection( "DynamicHud" );
+
+ HeapMgr()->PushHeap( GMA_TEMP );
+ tInventory::Iterator< tEntity > it( p3d::inventory );
+ HeapMgr()->PopHeap( GMA_TEMP );
+
+ tEntity* entity = it.First();
+ while( entity != NULL )
+ {
+ if( entity->GetNameObject() == s_AnimatedBitmapShortName )
+ {
+ tSprite* sprite = dynamic_cast< tSprite* >( entity );
+ tRefCounted::Assign( s_AnimatedBitmapSprite, sprite );
+ }
+ entity = it.Next();
+ }
+
+ if( s_AnimatedBitmapSprite == NULL )
+ {
+ tRefCounted::Assign( s_AnimatedBitmapSprite, p3d::find< tSprite >( s_AnimatedBitmapShortName ) );
+ }
+ if( s_AnimatedBitmapSprite == NULL )
+ {
+ //loading is not yet complete
+ m_missionStartBitmap->SetVisible( false );
+ }
+ else
+ {
+ p3d::inventory->RemoveSectionElements( tEntity::MakeUID( "DynamicHud" ) );
+ #ifdef RAD_DEBUG
+ tSprite* stillThere = p3d::find< tSprite >( s_AnimatedBitmapShortName );
+ rWarningMsg( stillThere == NULL, "We're leaking memory if we can't remove this" );
+ #endif
+ m_missionStartBitmap->SetVisible( true );
+ s_BitmapLoadPending = false;
+ }
+
+ p3d::inventory->PopSection();
+
+ }
+ m_missionStartBitmap->SetRawSprite( s_AnimatedBitmapSprite );
+
+ //Chuck I hope this a safe place to release the patty and selma screen
+ if (sp_PattyAndSelmaScreenPNG != NULL)
+ {
+ tRefCounted::Release(sp_PattyAndSelmaScreenPNG);
+ sp_PattyAndSelmaScreenPNG= NULL;
+ }
+}
+
+void
+CGuiScreenMissionBase::UpdateGamblingInfo()
+{
+ rAssert( m_gamblingInfo != NULL );
+ m_gamblingInfo->SetVisible( true );
+
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ char buffer[ 32 ];
+
+ Mission* currentMission = GetGameplayManager()->GetCurrentMission();
+ rAssert( currentMission != NULL );
+
+ // set entry fee
+ //
+ int entryFee = 0; // in coins
+
+ CoinObjective* coinObjective = dynamic_cast<CoinObjective*>( currentMission->GetStage( 0 )->GetObjective() );
+ if( coinObjective != NULL )
+ {
+ entryFee = coinObjective->GetCoinAmount();
+ }
+ else
+ {
+ rAssertMsg( false, "No coin objective in first stage!" );
+ }
+
+ sprintf( buffer, "%d", entryFee );
+ rAssert( m_gamblingEntryFee != NULL );
+ m_gamblingEntryFee->SetString( 0, buffer );
+
+ // if not enough coins to gamble, disable 'accept button'\
+ //
+ InitIntroWagerMission();
+
+ // set time to beat
+ //
+ int timeToBeat = 0; // in seconds
+
+ RaceObjective* raceObjective = dynamic_cast<RaceObjective*>( currentMission->GetStage( 1 )->GetObjective() );
+ if( raceObjective != NULL )
+ {
+ timeToBeat = raceObjective->GetParTime();
+ }
+ else
+ {
+ rAssertMsg( false, "No race objective in second stage!" );
+ }
+
+ sprintf( buffer, "%d:%02d", timeToBeat / 60, timeToBeat % 60 );
+ rAssert( m_gamblingTimeToBeat != NULL );
+ m_gamblingTimeToBeat->SetString( 0, buffer );
+
+ // set best time
+ //
+ RenderEnums::LevelEnum currentLevel = GetGameplayManager()->GetCurrentLevelIndex();
+ int bestTime = GetCharacterSheetManager()->GetGambleRaceBestTime( currentLevel );
+ if( bestTime < 0 )
+ {
+ // if no best time set yet, just set it to the time to beat
+ //
+ bestTime = timeToBeat;
+ }
+
+ sprintf( buffer, "%d:%02d", bestTime / 60, bestTime % 60 );
+ rAssert( m_gamblingBestTime != NULL );
+ m_gamblingBestTime->SetString( 0, buffer );
+
+ // set vehicle odds
+ //
+ float oddsRatio = 1.0f;
+
+ Vehicle* currentVehicle = GetGameplayManager()->GetCurrentVehicle();
+ if( currentVehicle != NULL )
+ {
+ oddsRatio = currentVehicle->GetGamblingOdds();
+ }
+ else
+ {
+ rAssertMsg( false, "What? How do you expect to race w/out a vehicle??" );
+ }
+
+ rAssert( m_gamblingVehicleOdds != NULL );
+ if( oddsRatio >= VEHICLE_ODDS_HARD_THRESHOLD ) // hard
+ {
+ m_gamblingVehicleOdds->SetIndex( VEHICLE_ODDS_HARD );
+ }
+ else if( oddsRatio >= VEHICLE_ODDS_MEDIUM_THRESHOLD ) // medium
+ {
+ m_gamblingVehicleOdds->SetIndex( VEHICLE_ODDS_MEDIUM );
+ }
+ else // easy
+ {
+ m_gamblingVehicleOdds->SetIndex( VEHICLE_ODDS_EASY );
+ }
+/*
+ sprintf( buffer, "%.1f : 1", oddsRatio );
+ rAssert( m_gamblingVehicleOdds != NULL );
+ m_gamblingVehicleOdds->SetString( 0, buffer );
+*/
+
+ // set payout amount
+ //
+ int payoutAmount = entryFee + (int)( entryFee * oddsRatio );
+
+ sprintf( buffer, "%d", payoutAmount );
+ rAssert( m_gamblingPayout != NULL );
+ m_gamblingPayout->SetString( 0, buffer );
+
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+}
+
diff --git a/game/code/presentation/gui/ingame/guiscreenmissionbase.h b/game/code/presentation/gui/ingame/guiscreenmissionbase.h
new file mode 100644
index 0000000..3ff6ec6
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenmissionbase.h
@@ -0,0 +1,132 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMissionSuccess
+//
+// Description:
+//
+//
+// Authors: Ian Gipson
+//
+// Revisions Date Author Revision
+// 2003/04/07 igipson Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMISSIONBASE_H
+#define GUISCREENMISSIONBASE_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <events/eventlistener.h>
+#include <presentation/gui/guiscreen.h>
+#include <presentation/gui/ingame/guiscreenhastransitions.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class tSprite;
+namespace Scrooby
+{
+ class BoundedDrawable;
+ class Drawable;
+}
+
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMissionBase:
+ public CGuiScreen,
+ public CGuiScreenHasTransitions
+{
+public:
+ CGuiScreenMissionBase( Scrooby::Screen* pScreen, CGuiEntity* pParent, eGuiWindowID id );
+ ~CGuiScreenMissionBase();
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+ virtual void InitIntro();
+ virtual void InitRunning();
+ virtual void InitOutro();
+ static void ClearBitmap();
+ static void GetBitmapName( char* buffer );
+ static bool IsCurrentBitmap( const char* name );
+ static void ReplaceBitmap();
+ static void SetBitmapName( const char* name );
+
+protected:
+ Scrooby::Group* GetAbortBitmap();
+ Scrooby::Drawable* GetFlag();
+ Scrooby::Group* GetLoadCompletedGroup();
+ Scrooby::Text* GetMissionInfoText();
+ Scrooby::BoundedDrawable* GetMissionStartBitmap();
+ Scrooby::Page* GetPage();
+ Scrooby::Text* GetTitleText();
+ void InitIntroWagerMission();
+ virtual void OutroDone();
+ static void RemoveAnimatedBitmap();
+ void StartIrisWipeClose();
+ void StartIrisWipeOpen();
+ void UpdateAnimatedBitmap( const float deltaT );
+ void UnloadBitmap();
+ void UpdateGamblingInfo();
+ void SetPlayAnimatedCamera( bool play );
+ const char* GetWatcherName() const;
+
+private:
+ Scrooby::Text* m_missionTitle;
+ Scrooby::Page* m_Page;
+ Scrooby::Page* m_LetterboxPage;
+ Scrooby::Sprite* m_missionStartBitmap;
+ Scrooby::Sprite* m_background;
+ Scrooby::Sprite* m_Flag;
+ Scrooby::Drawable* m_ClipLeftGroup;
+ Scrooby::Drawable* m_ClipRightGroup;
+ Scrooby::Drawable* m_ClipLeft;
+ Scrooby::Drawable* m_ClipRight;
+ Scrooby::Sprite* m_ClipLeftArm;
+ Scrooby::Sprite* m_ClipRightArm;
+ Scrooby::Drawable* m_Foreground;
+ Scrooby::Group* m_darkenPolys;
+ Scrooby::Group* m_loadCompleted;
+ Scrooby::Group* m_textOverlays;
+ Scrooby::Group* m_darkenTop;
+ Scrooby::Group* m_darkenBottom;
+ Scrooby::Polygon* m_backgroundPoly;
+ Scrooby::Layer* m_LetterboxLayer;
+ Scrooby::Layer* m_BgLayer;
+ Scrooby::Group* m_FgLayer;
+ Scrooby::Pure3dObject* m_Iris;
+ tMultiController* m_MultiController;
+ float m_irisWipeNumFrames;
+ Scrooby::Text* m_Line0;
+ static tSprite* s_AnimatedBitmapSprite;
+ static char s_AnimatedBitmapName[ 256 ];
+ static char s_AnimatedBitmapShortName[ 32 ];
+ static bool s_BitmapLoadPending;
+ static tSprite* sp_PattyAndSelmaScreenPNG;
+ bool m_PlayAnimatedCamera;
+
+ enum eGamblingVehicleOdds
+ {
+ VEHICLE_ODDS_EASY,
+ VEHICLE_ODDS_MEDIUM,
+ VEHICLE_ODDS_HARD,
+
+ NUM_VEHICLE_ODDS
+ };
+
+ Scrooby::Group* m_gamblingInfo;
+ Scrooby::Text* m_gamblingEntryFee;
+ Scrooby::Text* m_gamblingTimeToBeat;
+ Scrooby::Text* m_gamblingBestTime;
+ Scrooby::Text* m_gamblingVehicleOdds;
+ Scrooby::Text* m_gamblingPayout;
+
+ bool m_ReadyToExitScreen : 1;
+
+};
+
+#endif // GUISCREENMISSIONBASE_H
diff --git a/game/code/presentation/gui/ingame/guiscreenmissionload.cpp b/game/code/presentation/gui/ingame/guiscreenmissionload.cpp
new file mode 100644
index 0000000..2a6c4e2
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenmissionload.cpp
@@ -0,0 +1,511 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMissionLoad
+//
+// Description: Implementation of the CGuiScreenMissionLoad class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <camera/animatedcam.h>
+#include <events/eventmanager.h>
+#include <mission/gameplaymanager.h>
+#include <presentation/gui/ingame/guimanageringame.h>
+#include <presentation/gui/ingame/guiscreenmissionload.h>
+#include <presentation/gui/ingame/guiscreenmissionselect.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <p3d/utility.hpp>
+#include <raddebug.hpp> // Foundation
+#include <radmath/matrix.hpp>
+#include <radmath/util.hpp>
+#include <loading/loadingmanager.h>
+#include <strings/unicodestring.h>
+
+#include <screen.h>
+#include <page.h>
+
+#include <p3d/unicode.hpp>
+#include <string.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+#ifndef PAL
+ // convert mission title string to all caps
+ //
+ #define MISSION_TITLE_ALL_CAPS
+#endif
+
+#define TRANSITION_IN_TIME 250.0f
+
+const UnicodeChar EMPTY_MISSION_HINT = '*';
+const float startDelayTimeMs = 500.0f;
+const float DARKEN_ANIMATION_DELAY_BEFORE_STARTING = startDelayTimeMs;
+const float DARKEN_ANIMATION_INTRO_TIME = 1000.0f;
+int g_BitmapPositionX;
+int g_BitmapPositionY;
+int g_BitmapSizeX;
+int g_BitmapSizeY;
+int g_TitlePositionX;
+int g_TitlePositionY;
+
+int g_BitmapPositionWagerX = 0;
+int g_BitmapPositionWagerY = 200;
+int g_BitmapSizeWagerX = 20;
+int g_BitmapSizeWagerY = 20;
+int g_TitlePositionWagerX = 200;
+int g_TitlePositionWagerY = 370;
+
+GuiSFX::Show g_LoadCompletedShow( "LoadCompletedShow" );
+GuiSFX::ColorChange g_LoadCompletedTransitionIn( "LoadCompletedTransitionIn" );
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenMissionLoad::CGuiScreenMissionLoad
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMissionLoad::CGuiScreenMissionLoad
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+):
+ CGuiScreenMissionBase( pScreen, pParent, GUI_SCREEN_ID_MISSION_LOAD ),
+ m_LoadIsDone( true ),
+ m_loadingText( NULL ),
+ m_elapsedIdleTime( 0 )
+{
+ ExtractNormalPositions();
+ Scrooby::Group* loadCompleted = GetLoadCompletedGroup();
+ g_LoadCompletedShow.SetDrawable( loadCompleted );
+
+ g_LoadCompletedTransitionIn.SetDrawable( loadCompleted );
+ g_LoadCompletedTransitionIn.SetStartColour( tColour( 255, 255, 255, 0 ) );
+ g_LoadCompletedTransitionIn.SetEndColour ( tColour( 255, 255, 255, 255 ) );
+ g_LoadCompletedTransitionIn.SetTimeInterval( TRANSITION_IN_TIME );
+ g_LoadCompletedTransitionIn.Deactivate();
+ WATCH( g_LoadCompletedTransitionIn, GetWatcherName() );
+
+ g_LoadCompletedShow. SetNextTransition( g_LoadCompletedTransitionIn );
+ g_LoadCompletedTransitionIn.SetNextTransition( NULL );
+
+ AddTransition( g_LoadCompletedTransitionIn );
+
+ AddListeners();
+
+ // get loading text
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "LoadingText" );
+ if( pPage != NULL )
+ {
+ m_loadingText = pPage->GetText( "Loading" );
+ rAssert( m_loadingText != NULL );
+ m_loadingText->SetVisible( false ); // hide by default
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMissionLoad::~CGuiScreenMissionLoad
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMissionLoad::~CGuiScreenMissionLoad()
+{
+ RemoveListeners();
+ p3d::pddi->DrawSync();
+}
+
+//===========================================================================
+// CGuiScreenMissionLoad::AddListeners
+//===========================================================================
+// Description: Adds all the listeners this class is ever going to need
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionLoad::AddListeners()
+{
+ GetEventManager()->AddListener( this, EVENT_GUI_MISSION_LOAD_COMPLETE );
+}
+
+//===========================================================================
+// CGuiScreenMissionLoad::ExtractNormalPositions
+//===========================================================================
+// Description: the default positions of the objects are taken out of scrooby
+// this function actually goes and gets them
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionLoad::ExtractNormalPositions()
+{
+ // extract the position of the mission loading bitmap
+ Scrooby::Drawable* missionStartBitmap = GetMissionStartBitmap();
+ missionStartBitmap->GetOriginPosition( g_BitmapPositionX, g_BitmapPositionY );
+ missionStartBitmap->GetBoundingBoxSize( g_BitmapSizeX, g_BitmapSizeY );
+
+ // extract the position of the title
+ Scrooby::Text* text = GetTitleText();
+ text->GetOriginPosition( g_TitlePositionX, g_TitlePositionY );
+}
+
+//===========================================================================
+// CGuiScreenMissionLoad::HandleEvent
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void
+CGuiScreenMissionLoad::HandleEvent( EventEnum id, void* pEventData )
+{
+ if( id == EVENT_GUI_MISSION_LOAD_COMPLETE )
+ {
+ // mission load completed, show "Press Start" message
+ //
+ m_LoadIsDone = true;
+ g_LoadCompletedShow.Activate();
+
+ Mission* currentMission = GetGameplayManager()->GetCurrentMission();
+ rAssert( currentMission != NULL );
+ if( currentMission->IsWagerMission() )
+ {
+ this->UpdateGamblingInfo();
+ }
+
+ // hide loading text
+ //
+ if( m_loadingText != NULL )
+ {
+ m_loadingText->SetVisible( false );
+ }
+ }
+}
+
+//===========================================================================
+// CGuiScreenMissionSuccess::HandleMessage
+//===========================================================================
+// Description: Handles messages, and passes them up the hierarchy when done
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionLoad::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ m_elapsedIdleTime += param1;
+
+ if( m_loadingText != NULL && !m_LoadIsDone )
+ {
+ // blink loading text if idling here on this screen to satisfy
+ // TRC/TCR requirements
+ //
+ const unsigned int BLINKING_PERIOD = 250;
+ bool isBlinked = GuiSFX::Blink( m_loadingText,
+ static_cast<float>( m_elapsedIdleTime ),
+ static_cast<float>( BLINKING_PERIOD ) );
+ if( isBlinked )
+ {
+ m_elapsedIdleTime %= BLINKING_PERIOD;
+ }
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ if( m_LoadIsDone && this->IsButtonVisible( BUTTON_ICON_ACCEPT ) )
+ {
+ SetPlayAnimatedCamera( true );
+
+ // resume game and start mission
+ //
+ m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME );
+
+ // trigger this event ONLY for wager race missions
+ //
+ Mission* currentMission = GetGameplayManager()->GetCurrentMission();
+ rAssert( currentMission != NULL );
+ if( currentMission->IsWagerMission() )
+ {
+ GetEventManager()->TriggerEvent( EVENT_ATTEMPT_TO_ENTER_GAMBLERACE );
+ }
+
+ GetEventManager()->TriggerEvent( EVENT_FE_CONTINUE );
+ GetEventManager()->TriggerEvent( EVENT_MISSION_BRIEFING_ACCEPTED );
+ }
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ if( m_LoadIsDone && this->IsButtonVisible( BUTTON_ICON_BACK ) )
+ {
+ // resume game and abort mission
+ //
+ SetPlayAnimatedCamera( false );
+ AnimatedCam::SetCamera( "" );
+ m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME, ON_HUD_ENTER_ABORT_MISSION );
+
+ GetEventManager()->TriggerEvent(EVENT_USER_CANCEL_MISSION_BRIEFING);
+ GetEventManager()->TriggerEvent( EVENT_FE_CANCEL );
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ CGuiScreenMissionBase::HandleMessage( message, param1, param2 );
+}
+
+//===========================================================================
+// CGuiScreenMissionLoad::InitializePermanentVariables
+//===========================================================================
+// Description: Stuff that goes into permanent memory gets initialized in
+// here
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionLoad::InitializePermanentVariables()
+{
+ p3d::inventory->AddSection( "DynamicHud" );
+}
+
+//===========================================================================
+// CGuiScreenMissionLoad::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionLoad::InitIntro()
+{
+ CGuiScreenMissionBase::InitIntro();
+
+ Scrooby::Text* missionTitle = GetTitleText();
+ rAssert( missionTitle != NULL );
+
+#ifdef MISSION_TITLE_ALL_CAPS
+ // convert mission title to all caps
+ //
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ UnicodeString unicodeString;
+ unicodeString.ReadUnicode( missionTitle->GetStringBuffer() );
+ p3d::UnicodeStrUpr( unicodeString.GetBuffer() );
+
+ missionTitle->SetString( missionTitle->GetIndex(), unicodeString );
+
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+#endif // MISSION_TITLE_ALL_CAPS
+
+ //
+ // Turn on the titles
+ //
+ missionTitle->SetVisible( true );
+ GetMissionInfoText()->SetVisible( true );
+
+ Scrooby::Group* loadCompleted = GetLoadCompletedGroup();
+ loadCompleted->SetVisible( false );
+ m_LoadIsDone = false;
+
+ if( m_loadingText != NULL )
+ {
+ // hide loading text
+ //
+ m_loadingText->SetVisible( false );
+
+ this->SetAlphaForLayers( 1.0f, m_foregroundLayers, m_numForegroundLayers );
+ }
+
+ m_elapsedIdleTime = 0;
+
+ //
+ // is this a normal mission or a wager mission
+ //
+ Mission* currentMission = GetGameplayManager()->GetCurrentMission();
+ rAssert( currentMission != NULL );
+ if( currentMission->IsWagerMission() )
+ {
+ InitPositionsWager();
+ }
+ else
+ {
+ InitPositionsNormal();
+ }
+
+ // only show "cancel" button for wager missions
+ //
+ this->SetButtonVisible( BUTTON_ICON_BACK, currentMission->IsWagerMission() );
+}
+
+//===========================================================================
+// CGuiScreenMissionLoad::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionLoad::InitOutro()
+{
+ CGuiScreenMissionBase::InitOutro();
+ rWarning( m_LoadIsDone );
+ m_LoadIsDone = false;
+
+ if( m_loadingText != NULL )
+ {
+ // hide loading text
+ //
+ m_loadingText->SetVisible( false );
+ }
+}
+
+//===========================================================================
+// CGuiScreenMissionLoad::InitPositionsNormal
+//===========================================================================
+// Description: Move scroobyelements to where they need to be for normal
+// missions
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionLoad::InitPositionsNormal()
+{
+ Scrooby::BoundedDrawable* missionStart = GetMissionStartBitmap();
+ missionStart->SetPosition ( g_BitmapPositionX, g_BitmapPositionY );
+ missionStart->SetBoundingBoxSize( g_BitmapSizeX, g_BitmapSizeY );
+
+ Scrooby::Text* title = GetTitleText();
+#ifndef RAD_WIN32 // temp fix.
+ title->SetPosition( g_TitlePositionX, g_TitlePositionY );
+#endif
+
+ Scrooby::Text* info = GetMissionInfoText();
+ info->SetHorizontalJustification( Scrooby::Center );
+}
+
+//===========================================================================
+// CGuiScreenMissionLoad::InitPositionsWager
+//===========================================================================
+// Description: Move scrooby elements to where they need to be for wager
+// missions
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionLoad::InitPositionsWager()
+{
+ Scrooby::BoundedDrawable* missionStart = GetMissionStartBitmap();
+ missionStart->SetPosition( g_BitmapPositionWagerX, g_BitmapPositionWagerY );
+ missionStart->SetBoundingBoxSize( g_BitmapSizeWagerX, g_BitmapSizeWagerY );
+
+ Scrooby::Text* title = GetTitleText();
+ title->SetPosition( g_TitlePositionWagerX, g_TitlePositionWagerY );
+
+ // turn on the flag bitmap
+ Scrooby::Drawable* flag = GetFlag();
+ flag->SetVisible( true );
+
+ Scrooby::Text* info = GetMissionInfoText();
+ info->SetHorizontalJustification( Scrooby::Left );
+}
+
+//===========================================================================
+// CGuiScreenMissionLoad::RemoveListeners
+//===========================================================================
+// Description: removes all the listeners that have been set up in this class
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionLoad::RemoveListeners()
+{
+}
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/ingame/guiscreenmissionload.h b/game/code/presentation/gui/ingame/guiscreenmissionload.h
new file mode 100644
index 0000000..8193b3c
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenmissionload.h
@@ -0,0 +1,73 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMissionLoad
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMISSIONLOAD_H
+#define GUISCREENMISSIONLOAD_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenmissionbase.h>
+#include <presentation/gui/utility/transitions.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class CGuiMenu;
+class tSprite;
+namespace Scrooby
+{
+ class Group;
+}
+
+const int MAX_NUM_BULLETS = 2;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMissionLoad :
+ public CGuiScreenMissionBase,
+ public EventListener
+{
+public:
+ CGuiScreenMissionLoad( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenMissionLoad();
+
+ // Implements EventListener
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+ virtual void HandleEvent( EventEnum id, void* pEventData );
+ static void InitializePermanentVariables();
+ virtual void InitIntro();
+ virtual void InitOutro();
+
+protected:
+ virtual void AddListeners();
+ void ExtractNormalPositions();
+ void InitPositionsNormal();
+ void InitPositionsWager();
+ virtual void RemoveListeners();
+
+private:
+ bool m_LoadIsDone : 1; //the mission load is done
+
+ Scrooby::Text* m_loadingText;
+ unsigned int m_elapsedIdleTime;
+
+};
+
+#endif // GUISCREENMISSIONLOAD_H
diff --git a/game/code/presentation/gui/ingame/guiscreenmissionover.cpp b/game/code/presentation/gui/ingame/guiscreenmissionover.cpp
new file mode 100644
index 0000000..64ad4f4
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenmissionover.cpp
@@ -0,0 +1,450 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMissionOver
+//
+// Description: Implementation of the CGuiScreenMissionOver class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenmissionover.h>
+#include <presentation/gui/ingame/guimanageringame.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guitextbible.h>
+
+#include <events/eventmanager.h>
+#include <memory/srrmemory.h>
+#include <mission/gameplaymanager.h>
+#include <mission/mission.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <sound/soundmanager.h>
+
+#include <p3d/unicode.hpp>
+#include <raddebug.hpp> // Foundation
+#include <layer.h>
+#include <page.h>
+#include <screen.h>
+#include <text.h>
+
+#include <stdlib.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const int NUM_ATTEMPTS_REQUIRED_FOR_SKIPPING = 7;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenMissionOver::CGuiScreenMissionOver
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMissionOver::CGuiScreenMissionOver
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MISSION_OVER ),
+ m_pMenu( NULL ),
+ m_failureReason( NULL ),
+ m_failureHint( NULL )
+{
+MEMTRACK_PUSH_GROUP( "CGUIScreenMissionOver" );
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage;
+ pPage = m_pScroobyScreen->GetPage( "MissionOver" );
+ rAssert( pPage );
+
+ Scrooby::Layer* foreground = pPage->GetLayer( "Foreground" );
+ rAssert( foreground != NULL );
+
+ // get 'mission failed' text bible string
+ //
+ P3D_UNICODE* text = GetTextBibleString( "MISSION_FAILED" );
+ rAssert( text != NULL );
+ int textLength = p3d::UnicodeStrLen( text ) + 1;
+
+ Scrooby::Sprite* missionFailedText = foreground->GetSprite( "MissionFailed" );
+ if( missionFailedText != NULL )
+ {
+ missionFailedText->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT );
+ missionFailedText->CreateBitmapTextBuffer( textLength );
+ missionFailedText->SetBitmapText( text );
+ missionFailedText->SetBitmapTextLineSpacing( 10 );
+#ifdef RAD_WIN32
+ missionFailedText->ResetTransformation();
+ missionFailedText->ScaleAboutCenter( 0.5f );
+#endif
+ }
+
+ m_failureReason = foreground->GetText( "MissionFailureReason" );
+ rAssert( m_failureReason != NULL );
+ m_failureReason->SetTextMode( Scrooby::TEXT_WRAP );
+
+ m_failureHint = foreground->GetText( "MissionFailureHint" );
+ rAssert( m_failureHint != NULL );
+ m_failureHint->SetTextMode( Scrooby::TEXT_WRAP );
+
+ // Create a menu.
+ //
+ m_pMenu = new CGuiMenuPrompt( this, pPage, 3 );
+ rAssert( m_pMenu != NULL );
+
+ // register events to listen for
+ //
+ GetEventManager()->AddListener( this, EVENT_MISSION_FAILURE );
+
+MEMTRACK_POP_GROUP("CGUIScreenMissionOver");
+}
+
+
+//===========================================================================
+// CGuiScreenMissionOver::~CGuiScreenMissionOver
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMissionOver::~CGuiScreenMissionOver()
+{
+ // unregister events
+ //
+ GetEventManager()->RemoveListener( this, EVENT_MISSION_FAILURE );
+
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMissionOver::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionOver::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ if( param1 == 0 ) // 'yes' response
+ {
+ // restart mission
+ //
+ m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME,
+ ON_HUD_ENTER_RESTART_MISSION );
+ }
+ else if( param1 == 1 ) // 'no' response
+ {
+ // abort mission
+ //
+ m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME,
+ ON_HUD_ENTER_ABORT_MISSION );
+ }
+ else if( param1 == 2 ) // 'skip' response
+ {
+ // skip to next mission
+ //
+ m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME,
+ ON_HUD_ENTER_SKIP_MISSION );
+/*
+ CurrentMissionStruct currentMission = GetCharacterSheetManager()->QueryCurrentMission();
+
+ unsigned int nextLevel = currentMission.mLevel;
+ unsigned int nextMission = currentMission.mMissionNumber + 1;
+
+ if( currentMission.mMissionNumber == RenderEnums::M7 ) // last mission
+ {
+ // go to next level's first mission
+ //
+ nextLevel++;
+ nextMission = RenderEnums::M1;
+
+ rAssert( nextLevel < RenderEnums::numLevels );
+ }
+*/
+ }
+ else
+ {
+ rAssertMsg( 0, "WARNING: *** Unexpected response!\n" );
+ }
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+void
+CGuiScreenMissionOver::HandleEvent( EventEnum id, void* pEventData )
+{
+ switch( id )
+ {
+ case EVENT_MISSION_FAILURE:
+ {
+ MissionCondition* failureCondition = reinterpret_cast<MissionCondition*>( pEventData );
+ rAssert( failureCondition != NULL );
+
+ this->SetFailureMessage( failureCondition->GetType() );
+
+ break;
+ }
+ default:
+ {
+ rWarningMsg( false, "Unhandled event ID!" );
+
+ break;
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMissionOver::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionOver::InitIntro()
+{
+ rAssert( m_pMenu != NULL );
+
+ // reset menu to "Yes" selection
+ //
+ m_pMenu->Reset();
+
+ // show/hide 'skip' menu response
+ //
+ CurrentMissionStruct currentMission = GetCharacterSheetManager()->QueryCurrentMission();
+ int numAttemps = GetCharacterSheetManager()->QueryNumberOfAttempts( currentMission.mLevel, currentMission.mMissionNumber );
+ bool isSkipAllowed = (numAttemps >= NUM_ATTEMPTS_REQUIRED_FOR_SKIPPING);
+
+ if( currentMission.mLevel == RenderEnums::L7 && static_cast<int>( currentMission.mMissionNumber ) >= RenderEnums::M5 )
+ {
+ // can't skip the last mission of the game
+ //
+ isSkipAllowed = false;
+ }
+
+#ifdef RAD_E3
+ // no skipping mission allowed on E3 build
+ //
+ isSkipAllowed = false;
+#endif
+
+ m_pMenu->SetMenuItemEnabled( 2, isSkipAllowed, true );
+
+ GetSoundManager()->OnStoreScreenStart( false );
+}
+
+
+//===========================================================================
+// CGuiScreenMissionOver::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionOver::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenMissionOver::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionOver::InitOutro()
+{
+ GetEventManager()->TriggerEvent( EVENT_DIALOG_SHUTUP );
+ GetSoundManager()->OnStoreScreenEnd();
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenMissionOver::SetFailureMessage( MissionCondition::ConditionTypeEnum conditionType )
+{
+ int failureMessageIndex = 0;
+
+ switch( conditionType )
+ {
+ case MissionCondition::COND_VEHICLE_DAMAGE:
+ {
+ failureMessageIndex = 1;
+
+ break;
+ }
+ case MissionCondition::COND_PLAYER_HIT:
+ {
+ failureMessageIndex = 2;
+
+ break;
+ }
+ case MissionCondition::COND_TIME_OUT:
+ {
+ failureMessageIndex = 3;
+
+ break;
+ }
+ case MissionCondition::COND_PLAYER_OUT_OF_VEHICLE:
+ {
+ failureMessageIndex = 4;
+
+ break;
+ }
+ case MissionCondition::COND_FOLLOW_DISTANCE:
+ {
+ failureMessageIndex = 5;
+
+ break;
+ }
+ case MissionCondition::COND_OUT_OF_BOUNDS:
+ {
+ failureMessageIndex = 6;
+
+ break;
+ }
+ case MissionCondition::COND_RACE:
+ {
+ failureMessageIndex = 7;
+
+ break;
+ }
+ case MissionCondition::COND_NOT_ABDUCTED:
+ {
+ failureMessageIndex = 8;
+
+ break;
+ }
+ case MissionCondition::COND_POSITION:
+ {
+ failureMessageIndex = 9;
+
+ break;
+ }
+ case MissionCondition::COND_HIT_AND_RUN_CAUGHT:
+ {
+ failureMessageIndex = 10;
+
+ break;
+ }
+ case MissionCondition::COND_GET_COLLECTIBLES:
+ {
+ failureMessageIndex = 11;
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Unknown failure reason!" );
+
+ break;
+ }
+ }
+
+ rAssert( m_failureReason != NULL );
+ m_failureReason->SetIndex( failureMessageIndex );
+
+ // set associated mission failure hint (randomly chosen)
+ //
+ int hintMessageIndex = 0;
+
+ if( failureMessageIndex > 0 )
+ {
+ rAssert( GetGameplayManager()->GetCurrentMission() != NULL );
+
+ int numValidFailureHints = GetGameplayManager()->GetCurrentMission()->GetNumValidFailureHints();
+ if( numValidFailureHints < 0 )
+ {
+ numValidFailureHints = MAX_NUM_HINTS_PER_FAILURE;
+ }
+
+ int randomHintIndex = rand() % numValidFailureHints;
+
+ hintMessageIndex = (failureMessageIndex - 1) * MAX_NUM_HINTS_PER_FAILURE + 1 + randomHintIndex;
+ }
+
+ rAssert( m_failureHint != NULL );
+ m_failureHint->SetIndex( hintMessageIndex );
+}
+
diff --git a/game/code/presentation/gui/ingame/guiscreenmissionover.h b/game/code/presentation/gui/ingame/guiscreenmissionover.h
new file mode 100644
index 0000000..82a9ce6
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenmissionover.h
@@ -0,0 +1,72 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMissionOver
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMISSIONOVER_H
+#define GUISCREENMISSIONOVER_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+#include <events/eventlistener.h>
+#include <mission/conditions/missioncondition.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+namespace Scrooby
+{
+ class Screen;
+ class Text;
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMissionOver : public CGuiScreen,
+ public EventListener
+{
+public:
+ CGuiScreenMissionOver( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenMissionOver();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual void HandleEvent( EventEnum id, void* pEventData );
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ static const int MAX_NUM_HINTS_PER_FAILURE = 8;
+
+ void SetFailureMessage( MissionCondition::ConditionTypeEnum conditionType );
+
+ CGuiMenu* m_pMenu;
+
+ Scrooby::Text* m_failureReason;
+ Scrooby::Text* m_failureHint;
+
+};
+
+#endif // GUISCREENMISSIONOVER_H
diff --git a/game/code/presentation/gui/ingame/guiscreenmissionselect.cpp b/game/code/presentation/gui/ingame/guiscreenmissionselect.cpp
new file mode 100644
index 0000000..b043188
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenmissionselect.cpp
@@ -0,0 +1,493 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMissionSelect
+//
+// Description: Implementation of the CGuiScreenMissionSelect class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenmissionselect.h>
+#include <presentation/gui/ingame/guimanageringame.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/guiuserinputhandler.h>
+
+#include <cheats/cheatinputsystem.h>
+#include <events/eventmanager.h>
+#include <memory/srrmemory.h>
+#include <mission/gameplaymanager.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <mission/charactersheet/charactersheet.h>
+#include <render/enums/renderenums.h>
+
+#include <raddebug.hpp> // Foundation
+#include <page.h>
+#include <polygon.h>
+#include <screen.h>
+#include <sprite.h>
+#include <string.h>
+
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+#ifdef RAD_WIN32
+const float LEVEL_BAR_CORRECTION_SCALE = 1.0f;
+#else
+const float LEVEL_BAR_CORRECTION_SCALE = 2.0f;
+#endif
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenMissionSelect::CGuiScreenMissionSelect
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMissionSelect::CGuiScreenMissionSelect
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MISSION_SELECT ),
+ m_pMenuLevel( NULL ),
+ m_pMenu( NULL ),
+ m_numLevelSelections( 0 )
+{
+MEMTRACK_PUSH_GROUP( "CGUIScreenMissionSelect" );
+ HeapMgr()->PushHeap (GMA_LEVEL_HUD);
+
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "MissionSelect" );
+ rAssert( pPage );
+
+ Scrooby::Group* levelBar = pPage->GetGroup( "Level" );
+ rAssert( levelBar != NULL );
+
+#ifdef RAD_WIN32
+ m_leftArrow = levelBar->GetSprite( "LArrowBgd" );
+ rAssert( m_leftArrow != NULL );
+ m_leftArrow->ScaleAboutCenter( 1.7f );
+ m_leftArrow->Translate( -5, 3 );
+
+ m_rightArrow = levelBar->GetSprite( "RArrowBgd" );
+ rAssert( m_rightArrow != NULL );
+ m_rightArrow->ScaleAboutCenter( 1.7f );
+ m_rightArrow->Translate( -6, 3 );
+#endif
+
+ Scrooby::Sprite* levelBarBgd = levelBar->GetSprite( "LevelBar" );
+ if( levelBarBgd != NULL )
+ {
+ levelBarBgd->ResetTransformation();
+ levelBarBgd->ScaleAboutCenter( LEVEL_BAR_CORRECTION_SCALE );
+ }
+
+ // Create menu for level selection.
+ //
+ m_pMenuLevel = new CGuiMenu( this, 1, GUI_TEXT_MENU, MENU_SFX_NONE );
+ rAssert( m_pMenuLevel != NULL );
+ m_pMenuLevel->SetHighlightColour( false, tColour( 0, 0, 0 ) );
+
+ m_pMenuLevel->AddMenuItem( levelBar->GetText( "Level" ),
+ levelBar->GetText( "Level" ),
+ NULL,
+ NULL,
+ levelBar->GetSprite( "LArrowBgd" ),
+ levelBar->GetSprite( "RArrowBgd" ),
+ SELECTION_ENABLED | VALUES_WRAPPED );
+
+ // Create a menu.
+ //
+ m_pMenu = new CGuiMenu( this, MAX_NUM_REGULAR_MISSIONS, GUI_TEXT_MENU, MENU_SFX_NONE );
+ rAssert( m_pMenu != NULL );
+
+ // Add menu items
+ //
+ Scrooby::Group* missions = pPage->GetGroup( "Missions" );
+ Scrooby::Group* missionMenu = pPage->GetGroup( "Menu" );
+ Scrooby::Group* status = pPage->GetGroup( "Status" );
+ Scrooby::Group* initials = pPage->GetGroup( "Initials" );
+ Scrooby::Group* times = pPage->GetGroup( "Times" );
+ rAssert( missions != NULL );
+ rAssert( missionMenu != NULL );
+ rAssert( status != NULL );
+
+ for( int i = 0; i < MAX_NUM_REGULAR_MISSIONS; i++ )
+ {
+ char name[ 32 ];
+
+ // mission number and titles
+ //
+ sprintf( name, "MissionNum%d", i );
+ m_missionInfo[ i ].m_number = missions->GetText( name );
+
+ sprintf( name, "Mission%d", i );
+ Scrooby::Text* pText = missionMenu->GetText( name );
+ if( pText != NULL )
+ {
+ m_pMenu->AddMenuItem( pText );
+ }
+
+ m_missionInfo[ i ].m_title = pText;
+
+ // mission status
+ //
+ sprintf( name, "MissionStatus%d", i );
+ m_missionInfo[ i ].m_status = status->GetSprite( name );
+ }
+
+ Scrooby::Group* highlightBar = pPage->GetGroup( "HighlightBar" );
+ if( highlightBar != NULL )
+ {
+ m_pMenu->SetCursor( highlightBar );
+
+#ifdef PAL
+ highlightBar->ResetTransformation();
+ highlightBar->ScaleAboutCenter( 1.035f, 1.0f, 1.0f );
+#endif // PAL
+ }
+
+ this->AutoScaleFrame( m_pScroobyScreen->GetPage( "BigBoard" ) );
+
+ HeapMgr()->PopHeap (GMA_LEVEL_HUD);
+MEMTRACK_POP_GROUP("CGUIScreenMissionSelect");
+}
+
+
+//===========================================================================
+// CGuiScreenMissionSelect::~CGuiScreenMissionSelect
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMissionSelect::~CGuiScreenMissionSelect()
+{
+ if( m_pMenuLevel != NULL )
+ {
+ delete m_pMenuLevel;
+ m_pMenuLevel = NULL;
+ }
+
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMissionSelect::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionSelect::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_START:
+ {
+ if( !m_pMenu->HasSelectionBeenMade() )
+ {
+ // resume game
+ m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME );
+ }
+
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_VALUE_CHANGED:
+ {
+ rAssert( param1 == 0 );
+
+ this->OnLevelSelectionChange( static_cast<int>( param2 ) );
+
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ rAssert( m_pMenuLevel != NULL );
+ int currentLevel = m_pMenuLevel->GetSelectionValue( 0 );
+
+ // special case for level 1: all missions are offset by 1
+ // due to the tutorial mission treated as mission 0
+ //
+ unsigned int selectedMission = currentLevel == 0 ? param1 + 1 : param1;
+
+ m_pParent->HandleMessage( GUI_MSG_QUIT_INGAME_FOR_RELOAD,
+ currentLevel,
+ selectedMission );
+
+ // stop any dialog that may still be in progress
+ //
+ GetEventManager()->TriggerEvent( EVENT_DIALOG_SHUTUP );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+#ifdef RAD_DEMO
+ // can't change level in demo builds; only missions in current level
+ // are selectable
+ //
+ if( message == GUI_MSG_CONTROLLER_LEFT || message == GUI_MSG_CONTROLLER_RIGHT )
+ {
+ // ignore left/right controller inputs
+ //
+ return;
+ }
+#endif
+
+ // relay message to level menu
+ //
+ if( m_pMenuLevel != NULL )
+ {
+ m_pMenuLevel->HandleMessage( message, param1, param2 );
+ }
+
+ // relay message to menu
+ //
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+#ifdef RAD_WIN32
+//===========================================================================
+// CGuiScreenMissionSelect::CheckCursorAgainstHotspots
+//===========================================================================
+// Description: Checks cursor position against its list of hotspots.
+//
+// Constraints: None.
+//
+// Parameters: float x - The x position of cursor in P3D coordinates.
+// float y - The y position of cursor in P3D coordinates.
+//
+// Return: N/A.
+//
+//===========================================================================
+eFEHotspotType CGuiScreenMissionSelect::CheckCursorAgainstHotspots( float x, float y )
+{
+ eFEHotspotType hotSpotType = CGuiScreen::CheckCursorAgainstHotspots( x, y );
+ if( hotSpotType == HOTSPOT_NONE )
+ {
+ if( m_leftArrow )
+ {
+ if( m_leftArrow->IsPointInBoundingRect( x, y ) )
+ {
+ hotSpotType = HOTSPOT_ARROWLEFT;
+ }
+ }
+ if( m_rightArrow )
+ {
+ if( m_rightArrow->IsPointInBoundingRect( x, y ) )
+ {
+ hotSpotType = HOTSPOT_ARROWRIGHT;
+ }
+ }
+
+ }
+ return hotSpotType;
+}
+#endif
+
+//===========================================================================
+// CGuiScreenMissionSelect::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionSelect::InitIntro()
+{
+ m_numLevelSelections = GetCharacterSheetManager()->QueryHighestMission().mLevel + 1;
+ if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_MISSIONS ) )
+ {
+ m_numLevelSelections = RenderEnums::numLevels;
+ }
+
+ rAssert( m_pMenuLevel != NULL );
+ m_pMenuLevel->SetSelectionValueCount( 0, m_numLevelSelections );
+
+ int currentLevel = GetGameplayManager()->GetCurrentLevelIndex();
+ m_pMenuLevel->SetSelectionValue( 0, currentLevel );
+ this->OnLevelSelectionChange( currentLevel );
+}
+
+
+//===========================================================================
+// CGuiScreenMissionSelect::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionSelect::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenMissionSelect::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionSelect::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenMissionSelect::OnLevelSelectionChange( int currentLevel )
+{
+ rAssert( m_pMenu != NULL );
+ m_pMenu->Reset();
+
+ // update mission info for new level
+ //
+ for( int i = 0; i < MAX_NUM_REGULAR_MISSIONS; i++ )
+ {
+ // mission title
+ //
+ Scrooby::Text* missionTitle = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( i )->GetItem() );
+ rAssert( missionTitle != NULL );
+ missionTitle->SetIndex( currentLevel );
+
+ // mission info (status, best time, initials)
+ //
+ MissionRecord* missionRecord = GetCharacterSheetManager()->QueryMissionStatus( static_cast<RenderEnums::LevelEnum>( currentLevel ),
+ currentLevel == 0 ? i + 1 : i );
+ rAssert( missionRecord != NULL );
+
+ bool isMissionUnlocked = true;
+ if( currentLevel == (m_numLevelSelections - 1) )
+ {
+ int highestMissionPlayed = GetCharacterSheetManager()->QueryHighestMission().mMissionNumber;
+ if( currentLevel == 0 )
+ {
+ highestMissionPlayed--;
+ }
+
+ if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_MISSIONS ) )
+ {
+ highestMissionPlayed = RenderEnums::M7;
+ }
+
+#ifdef RAD_DEMO
+ highestMissionPlayed = (currentLevel == RenderEnums::L7) ? RenderEnums::M4 : RenderEnums::M7;
+#endif // RAD_DEMO
+
+ isMissionUnlocked = ( i <= highestMissionPlayed );
+ }
+
+ if( isMissionUnlocked )
+ {
+ this->UpdateMissionStatus( i, missionRecord );
+ }
+
+ // show unlocked missions only
+ //
+ m_pMenu->SetMenuItemEnabled( i, isMissionUnlocked );
+
+ m_missionInfo[ i ].m_number->SetVisible( isMissionUnlocked );
+ m_missionInfo[ i ].m_title->SetVisible( isMissionUnlocked );
+ m_missionInfo[ i ].m_status->SetVisible( isMissionUnlocked );
+ }
+}
+
+void
+CGuiScreenMissionSelect::UpdateMissionStatus( int index,
+ MissionRecord* missionRecord )
+{
+ rAssert( missionRecord != NULL );
+ rAssert( m_missionInfo[ index ].m_status );
+
+ if( missionRecord->mCompleted )
+ {
+ m_missionInfo[ index ].m_status->SetIndex( 2 ); // 2 = green check
+ }
+ else
+ {
+ if( missionRecord->mNumAttempts > 0 &&
+ !missionRecord->mSkippedMission )
+ {
+ m_missionInfo[ index ].m_status->SetIndex( 1 ); // 1 = red cross
+ }
+ else
+ {
+ m_missionInfo[ index ].m_status->SetIndex( 0 ); // 0 = yellow dash
+ }
+ }
+}
+
diff --git a/game/code/presentation/gui/ingame/guiscreenmissionselect.h b/game/code/presentation/gui/ingame/guiscreenmissionselect.h
new file mode 100644
index 0000000..9db8041
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenmissionselect.h
@@ -0,0 +1,83 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMissionSelect
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/09/20 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMISSIONSELECT_H
+#define GUISCREENMISSIONSELECT_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <presentation/gui/utility/numerictext.h>
+
+const int MAX_NUM_REGULAR_MISSIONS = 7;
+const int MAX_NUM_MISSIONS_PER_LEVEL = MAX_NUM_REGULAR_MISSIONS + 4 + 1; // +4 street races, +1 bonus
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+struct MissionRecord;
+
+struct MissionDisplayInfo
+{
+ static const unsigned int MAX_NUM_INITIALS = 3;
+
+ Scrooby::Text* m_number;
+ Scrooby::Text* m_title;
+ Scrooby::Sprite* m_status;
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMissionSelect : public CGuiScreen
+{
+public:
+ CGuiScreenMissionSelect( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenMissionSelect();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+#ifdef RAD_WIN32
+ virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y );
+#endif
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ void OnLevelSelectionChange( int currentLevel );
+ void UpdateMissionStatus( int index, MissionRecord* missionRecord );
+
+ CGuiMenu* m_pMenuLevel;
+ CGuiMenu* m_pMenu;
+ int m_numLevelSelections;
+
+#ifdef RAD_WIN32
+ Scrooby::Sprite* m_leftArrow;
+ Scrooby::Sprite* m_rightArrow;
+#endif
+
+ MissionDisplayInfo m_missionInfo[ MAX_NUM_REGULAR_MISSIONS ];
+
+};
+
+#endif // GUISCREENMISSIONSELECT_H
diff --git a/game/code/presentation/gui/ingame/guiscreenmissionsuccess.cpp b/game/code/presentation/gui/ingame/guiscreenmissionsuccess.cpp
new file mode 100644
index 0000000..a7879ee
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenmissionsuccess.cpp
@@ -0,0 +1,211 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMissionLoad
+//
+// Description: Implementation of the CGuiScreenMissionSuccess class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/04/07 ian gipson Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <mission/charactersheet/charactersheet.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <mission/gameplaymanager.h>
+#include <presentation/gui/ingame/guimanageringame.h>
+#include <presentation/gui/ingame/guiscreenmissionsuccess.h>
+#include <group.h>
+#include <page.h>
+#include <screen.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenMissionSuccess::CGuiScreenMissionSuccess
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMissionSuccess::CGuiScreenMissionSuccess
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+):
+ CGuiScreenMissionBase( pScreen, pParent, GUI_SCREEN_ID_MISSION_SUCCESS )
+{
+ Scrooby::Page* page = pScreen->GetPage( "MissionLoad" ); rAssert( page != NULL );
+ m_PattyAndSelmaTitle = page->GetText( "PattyAndSelmaTitle" ); rAssert( m_PattyAndSelmaTitle != NULL );
+ m_PattyAndSelmaTitle->SetTextMode( Scrooby::TEXT_WRAP );
+ m_PattyAndSelmaInfo = page->GetText( "PattyAndSelmaInfo" ); rAssert( m_PattyAndSelmaInfo != NULL );
+ m_PattyAndSelmaInfo->SetTextMode( Scrooby::TEXT_WRAP );
+ m_PattyAndSelmaTitle->SetVisible( false );
+ m_PattyAndSelmaInfo->SetVisible( false );
+}
+
+//===========================================================================
+// CGuiScreenMissionSuccess::HandleMessage
+//===========================================================================
+// Description: Handles messages, and passes them up the hierarchy when done
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionSuccess::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ // resume game and start mission
+ //
+ m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME );
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ // resume game and abort mission
+ //
+ //m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME, ON_HUD_ENTER_ABORT_MISSION );
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ CGuiScreenMissionBase::HandleMessage( message, param1, param2 );
+}
+
+//===========================================================================
+// CGuiScreenMissionSuccess::InitIntro
+//===========================================================================
+// Description: sets up the screen when you enter it
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionSuccess::InitIntro()
+{
+ //
+ // Check the level - level 7 rerquires the zombie picture
+ //
+ int level = GetGameplayManager()->GetCurrentLevelIndex();
+ if( level == 6 )
+ {
+ SetBitmapName( "art/frontend/dynaload/images/misXX_HW.p3d" );
+ }
+ else
+ {
+ SetBitmapName( "art/frontend/dynaload/images/misXX_PS.p3d" );
+ }
+ ReplaceBitmap();
+
+ //
+ // Call the parent's initIntro function
+ //
+ CGuiScreenMissionBase::InitIntro();
+
+ //
+ // Hide the "cancel bitmap"
+ //
+ Scrooby::Group* abortBitmap = GetAbortBitmap();
+ abortBitmap->SetVisible( false );
+
+ //
+ // Show the correct titles
+ //
+ m_PattyAndSelmaTitle->SetVisible( true );
+ m_PattyAndSelmaInfo->SetVisible( true );
+
+ //
+ // Figure out how many races have been completed, and display it
+ //
+ CurrentMissionStruct mission = GetCharacterSheetManager()->QueryCurrentMission();
+ int racesComplete = GetCharacterSheetManager()->QueryNumStreetRacesCompleted( mission.mLevel );
+ char outputString[ 256 ] = "";
+ if( racesComplete < 3 )
+ {
+ m_PattyAndSelmaTitle->SetIndex( 0 );
+ m_PattyAndSelmaInfo->SetIndex( 0 );
+ UnicodeString title = m_PattyAndSelmaTitle->GetString();
+ char numberString[ 256 ] = "";
+ sprintf( numberString, "%d", racesComplete );
+ title.Replace( "%d", numberString );
+ title.Replace( "%d", "3" );
+ m_PattyAndSelmaTitle->SetString( 2, title );
+ m_PattyAndSelmaTitle->SetIndex( 2 );
+
+ //
+ // Check if the info just says "*" if so, then hide it
+ //
+ UnicodeChar* uc = m_PattyAndSelmaInfo->GetStringBuffer();
+ if( uc[ 0 ] == '*' )
+ {
+ m_PattyAndSelmaInfo->SetVisible( false );
+ }
+ else
+ {
+ m_PattyAndSelmaInfo->SetVisible( true );
+ }
+ }
+ else
+ {
+ int level = GetGameplayManager()->GetCurrentLevelIndex();
+ m_PattyAndSelmaTitle->SetIndex( 1 );
+ m_PattyAndSelmaInfo->SetIndex( 1 + level );
+ }
+}
+
+//===========================================================================
+// CGuiScreenMissionSuccess::OutroDone
+//===========================================================================
+// Description: sets up the screen when you enter it
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMissionSuccess::OutroDone()
+{
+ m_PattyAndSelmaTitle->SetVisible( false );
+ m_PattyAndSelmaInfo->SetVisible( false );
+}
diff --git a/game/code/presentation/gui/ingame/guiscreenmissionsuccess.h b/game/code/presentation/gui/ingame/guiscreenmissionsuccess.h
new file mode 100644
index 0000000..fd79194
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenmissionsuccess.h
@@ -0,0 +1,47 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMissionSuccess
+//
+// Description:
+//
+//
+// Authors: Ian Gipson
+//
+// Revisions Date Author Revision
+// 2003/04/07 igipson Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMISSIONSUCCESS_H
+#define GUISCREENMISSIONSUCCESS_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenmissionload.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMissionSuccess :
+ public CGuiScreenMissionBase
+{
+public:
+ CGuiScreenMissionSuccess( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+ virtual void InitIntro();
+protected:
+ virtual void OutroDone();
+private:
+ Scrooby::Text* m_PattyAndSelmaTitle;
+ Scrooby::Text* m_PattyAndSelmaInfo;
+};
+
+#endif // GUISCREENMISSIONSUCCESS_H
diff --git a/game/code/presentation/gui/ingame/guiscreenmultihud.cpp b/game/code/presentation/gui/ingame/guiscreenmultihud.cpp
new file mode 100644
index 0000000..3f76788
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenmultihud.cpp
@@ -0,0 +1,825 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMultiHud
+//
+// Description: Implementation of the CGuiScreenMultiHud class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/11/20 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/tutorialmanager.h>
+#include <presentation/gui/ingame/guiscreenmultihud.h>
+#include <presentation/gui/utility/hudmap.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <presentation/gui/utility/transitions.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/presentation.h>
+#include <contexts/gameplay/gameplaycontext.h>
+#include <input/inputmanager.h>
+#include <gameflow/gameflow.h>
+#include <main/commandlineoptions.h>
+#include <memory/srrmemory.h>
+#include <mission/gameplaymanager.h>
+#include <worldsim/avatarmanager.h>
+#include <worldsim/character/character.h>
+#include <worldsim/character/charactertarget.h>
+#include <worldsim/redbrick/vehicle.h>
+
+#include <raddebug.hpp> // Foundation
+
+#include <group.h>
+#include <screen.h>
+#include <page.h>
+#include <layer.h>
+#include <polygon.h>
+#include <sprite.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+#define SRR2_SHOW_SPEEDOMETER
+#define WHITE_WASH_IN_TIME 1000.0f
+
+const float ENTER_INGAME_FADE_IN_TIME = 500.0f; // in milliseconds
+const float transitionIn = 250.0f;
+const float minDisplayTime = 3000.0f;
+const float maxDisplayTime = 50000.0f;
+const float transitionOut = transitionIn;
+Scrooby::Polygon* g_WhiteWash = NULL;
+GuiSFX::Show g_WhiteWashShow( "WhiteWashShow" );
+GuiSFX::ColorChange g_WhiteWashIn( "WhiteWashIn" );
+GuiSFX::Pause g_WhiteWashPause( "WhiteWashPause" );
+GuiSFX::Hide g_WhiteWashHide( "WhiteWashHide" );
+GuiSFX::ResumeGame g_WhiteWashResumeGame( "WhiteWashResumeGame" );
+GuiSFX::PulseScale g_TutorialPulse( "TutorialPulse" );
+float g_TimeSinceLastDeathVolume = 0.0f;
+Vehicle* g_Vehicle = NULL;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+class ResetCar : public GuiSFX::SendEvent
+{
+public:
+ ResetCar();
+ void Activate();
+ void SetVehicle( Vehicle* vehicle );
+
+protected:
+ Vehicle* m_Vehicle;
+};
+ResetCar g_ResetCar;
+
+//===========================================================================
+// CGuiScreenMultiHud::CGuiScreenMultiHud
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMultiHud::CGuiScreenMultiHud
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent,
+ eGuiWindowID id,
+ int numActivePlayers
+)
+:
+ CGuiScreen( pScreen, pParent, id ),
+ m_numActivePlayers( numActivePlayers ),
+ m_tutorialWalkie( NULL ),
+ m_tutorialMessage( NULL ),
+ m_isStartButtonPressed( false ),
+ m_TutorialBitmapTimeShown( 0.0f )
+{
+ for( unsigned int i = 0; i < sizeof( m_hudMap ) /
+ sizeof( m_hudMap[ 0 ] ); i++ )
+ {
+ m_hudMap[ i ] = NULL;
+ }
+
+ Scrooby::Page* pPage;
+ pPage = m_pScroobyScreen->GetPage( "Hud" );
+ rAssert( pPage );
+
+ m_LetterboxPage = m_pScroobyScreen->GetPage( "LetterBox" );
+ m_LetterboxPage->SetVisible( false );
+ rAssert( m_LetterboxPage != NULL );
+
+ m_tutorialWalkie = pPage->GetGroup( "walkietalkie" );
+ rAssert( m_tutorialWalkie != NULL );
+ m_tutorialWalkie->SetVisible( false );
+
+ Scrooby::Sprite* bartImage = m_tutorialWalkie->GetSprite( "walkietalkie" );
+ if( bartImage != NULL )
+ {
+ bartImage->ResetTransformation();
+ bartImage->ScaleAboutCenter( 0.75f );
+ }
+
+ m_tutorialMessage = m_tutorialWalkie->GetSprite( "TutorialMessage" );
+ rAssert( m_tutorialMessage != NULL );
+ m_tutorialMessage->ScaleAboutCenter( 0.4f );
+ m_tutorialMessage->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT );
+ m_tutorialMessage->CreateBitmapTextBuffer( MAX_TUTORIAL_MESSAGE_LENGTH );
+
+ pPage = m_pScroobyScreen->GetPage( "WhiteCover" );
+ rAssert( pPage != NULL );
+
+ Scrooby::Layer* whiteOverlay = pPage->GetLayer( "WhiteOverlay" );
+ rAssert( whiteOverlay != NULL );
+ whiteOverlay->SetVisible( true );
+
+ g_WhiteWash = pPage->GetPolygon( "WhiteOverlay" );
+ rAssert( g_WhiteWash != NULL );
+ g_WhiteWash->SetVisible( false );
+
+ g_TutorialPulse.SetDrawable( m_tutorialWalkie );
+ g_TutorialPulse.SetAmplitude( 0.1f );
+ g_TutorialPulse.SetFrequency( 2.5f );
+ g_TutorialPulse.Activate();
+ g_WhiteWashShow.SetDrawable( g_WhiteWash );
+ g_WhiteWashShow.SetNextTransition( g_WhiteWashIn );
+ g_WhiteWashIn.SetDrawable( g_WhiteWash );
+ g_WhiteWashIn.SetTimeInterval( WHITE_WASH_IN_TIME );
+ g_WhiteWashIn.SetStartColour( tColour( 255, 255, 255, 0 ) );
+ g_WhiteWashIn.SetEndColour( tColour( 255, 255, 255, 255 ) );
+ g_ResetCar.SetEvent( EVENT_DEATH_VOLUME_SCREEN_BLANK );
+ g_ResetCar.SetEventData( NULL );
+
+
+
+ g_WhiteWashIn.SetNextTransition( g_ResetCar );
+ g_ResetCar.SetNextTransition( g_WhiteWashResumeGame );
+ g_WhiteWashResumeGame.SetNextTransition( g_WhiteWashPause );
+ g_WhiteWashPause.SetTimeInterval( 250.0f );
+ g_WhiteWashPause.SetNextTransition( g_WhiteWashHide );
+ g_WhiteWashHide.SetDrawable( g_WhiteWash );
+ g_WhiteWashHide.SetNextTransition( NULL );
+
+ int xMin;
+ int xMax;
+ int yMin;
+ int yMax;
+ m_tutorialWalkie->GetBoundingBox( xMin, yMin, xMax, yMax );
+ int height = yMax - yMin;
+
+ //
+ // Set up transitions for the tutorial bitmap
+ //
+ m_TutorialBitmapTransitionIn.SetDrawable( m_tutorialWalkie );
+ m_TutorialBitmapTransitionIn.SetFrequency( 5.0f );
+ m_TutorialBitmapTransitionIn.SetTimeInterval( transitionIn * 2.0f );
+ m_TutorialBitmapTransitionIn.SetStartOffscreenTop( m_tutorialWalkie );
+ m_TutorialBitmapTransitionIn.SetCoordsEnd( 0, 0 );
+
+ m_TutorialBitmapSteadyState.SetDrawable( m_tutorialWalkie );
+ m_TutorialBitmapSteadyState.SetTimeInterval( maxDisplayTime );
+ m_TutorialBitmapSteadyState.SetCoordsStart( 0, 0 );
+ m_TutorialBitmapSteadyState.SetCoordsEnd( 0, 0 );
+
+ m_TutorialBitmapTransitionOut.SetDrawable( m_tutorialWalkie );
+ m_TutorialBitmapTransitionOut.SetTimeInterval( transitionOut );
+ m_TutorialBitmapTransitionOut.SetCoordsStart( 0, 0 );
+ m_TutorialBitmapTransitionOut.SetEndOffscreenTop( m_tutorialWalkie );
+
+ m_TurorialBitmapStayOut.SetDrawable( m_tutorialWalkie );
+ m_TurorialBitmapStayOut.SetTimeInterval( FLT_MAX );
+ m_TurorialBitmapStayOut.SetCoordsStart( 0, -height * 2 - yMin );
+ m_TurorialBitmapStayOut.SetCoordsEnd( 0, -height * 2 - yMin );
+
+ //
+ // Chain the transitions together
+ //
+ m_TutorialBitmapTransitionIn.SetNextTransition( m_TutorialBitmapSteadyState );
+ m_TutorialBitmapSteadyState.SetNextTransition( m_TutorialBitmapTransitionOut );
+ m_TutorialBitmapTransitionOut.SetNextTransition( m_TurorialBitmapStayOut );
+
+ // override default fade time
+ this->SetFadeTime( ENTER_INGAME_FADE_IN_TIME );
+}
+
+CGuiScreenMultiHud::CGuiScreenMultiHud
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+:
+ CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MULTI_HUD ),
+ m_numActivePlayers( MAX_PLAYERS )
+{
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage;
+ pPage = m_pScroobyScreen->GetPage( "MultiHud" );
+ rAssert( pPage );
+
+ // Get dynamic elements
+ this->RetrieveElements( pPage );
+}
+
+
+//===========================================================================
+// CGuiScreenMultiHud::~CGuiScreenMultiHud
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMultiHud::~CGuiScreenMultiHud()
+{
+ for( unsigned int i = 0; i < sizeof( m_hudMap ) /
+ sizeof( m_hudMap[ 0 ] ); i++ )
+ {
+ if( m_hudMap[ i ] != NULL )
+ {
+ delete m_hudMap[ i ];
+ m_hudMap[ i ] = NULL;
+ }
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMultiHud::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiHud::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ // update HUD elements for all players
+ this->UpdateElements( param1 );
+
+ if( m_isStartButtonPressed )
+ {
+ m_isStartButtonPressed = false;
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ m_pParent->HandleMessage( GUI_MSG_PAUSE_INGAME );
+ }
+ }
+
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_START:
+ {
+ // queue this up to be processed in the next update frame
+ //
+ m_isStartButtonPressed = true;
+
+ break;
+ }
+
+#ifdef RAD_WIN32
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ // This is our start button for PC.
+ if( GetInputManager()->GetValue( 0, InputManager::KeyboardEsc ) > 0.0f )
+ {
+ m_isStartButtonPressed = true;
+ }
+ break;
+ }
+#endif
+
+ case GUI_MSG_DEATH_VOLUME_START:
+ {
+ //
+ // Need to start the transition for the death volume
+ //
+ if( g_TimeSinceLastDeathVolume > WHITE_WASH_IN_TIME + 1000.0 && GetGameFlow()->GetCurrentContext() != CONTEXT_PAUSE && GetGameFlow()->GetNextContext() != CONTEXT_PAUSE)
+ {
+ g_ResetCar.SetEventData( reinterpret_cast< void* >( param1 ) );
+ GameplayContext::GetInstance()->PauseAllButPresentation( true );
+ g_WhiteWashShow.Reset();
+ g_WhiteWashIn.Reset();
+ g_WhiteWashHide.Reset();
+ g_WhiteWashPause.Reset();
+ g_WhiteWashShow.Activate();
+ g_TimeSinceLastDeathVolume = 0.0f;
+ }
+ break;
+ }
+
+ case GUI_MSG_MANUAL_RESET:
+ {
+ //
+ // Need to start the transition for the death volume
+ //
+ if( g_TimeSinceLastDeathVolume > WHITE_WASH_IN_TIME + 1000.0 && GetGameFlow()->GetCurrentContext() != CONTEXT_PAUSE && GetGameFlow()->GetNextContext() != CONTEXT_PAUSE)
+ {
+ g_ResetCar.SetVehicle( reinterpret_cast< Vehicle* >( param1 ) );
+ g_ResetCar.SetEventData( NULL );
+ GameplayContext::GetInstance()->PauseAllButPresentation( true );
+ g_WhiteWashShow.Reset();
+ g_WhiteWashIn.Reset();
+ g_WhiteWashHide.Reset();
+ g_WhiteWashPause.Reset();
+ g_WhiteWashShow.Activate();
+ g_TimeSinceLastDeathVolume = 0.0f;
+ }
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenMultiHud::GetHudMap
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CHudMap*
+CGuiScreenMultiHud::GetHudMap( unsigned int playerID ) const
+{
+ rAssert( playerID < static_cast<unsigned int>( m_numActivePlayers ) );
+
+ return m_hudMap[ playerID ];
+}
+
+
+//===========================================================================
+// CGuiScreenMultiHud::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiHud::InitIntro()
+{
+ for( int i = 0; i < m_numActivePlayers; i++ )
+ {
+ Avatar* pAvatar = GetAvatarManager()->GetAvatarForPlayer( i );
+ rAssert( pAvatar );
+
+ rAssert( m_hudMap[ i ] );
+ m_hudMap[ i ]->SetCameraTarget( pAvatar->GetCharacter()->GetTarget() );
+ m_hudMap[ i ]->Reset();
+/*
+ m_hudMap[ i ]->RegisterIcon( HudMapIcon::ICON_PLAYER,
+ rmt::Vector( 0, 0, 0 ),
+ pAvatar->GetCharacter()->GetTarget() );
+*/
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMultiHud::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiHud::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenMultiHud::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiHud::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenMultiHud::RetrieveElements( Scrooby::Page* pPage )
+{
+MEMTRACK_PUSH_GROUP( "CGUIScreenMultiHud" );
+ char objectName[ 32 ];
+ for( int i = 0; i < m_numActivePlayers; i++ )
+ {
+#ifdef SRR2_SHOW_SPEEDOMETER
+ sprintf( objectName, "Speed%d", i );
+ Scrooby::Group* speedGroup = pPage->GetGroup( objectName );
+
+ rAssert( speedGroup != NULL );
+ m_speedDigital[ i ].SetScroobyText( speedGroup, objectName );
+// m_speedDigital[ i ].SetColour( tColour( 255, 255, 255 ) );
+
+ // speedometer is turned on w/ commandline option "speedometer"
+ //
+ m_speedDigital[ i ].SetVisible( CommandLineOptions::Get( CLO_SHOW_SPEED ) );
+
+ // hide speed units in final build
+ #ifdef FINAL
+ sprintf( objectName, "SpeedUnit%d", i );
+ Scrooby::Text* speedUnit = speedGroup->GetText( objectName );
+ if( speedUnit != NULL )
+ {
+ speedUnit->SetVisible( false );
+ }
+ #endif
+#endif
+
+ char p3dFile[ 16 ];
+ sprintf( p3dFile, "l%dhudmap", GetGameplayManager()->GetCurrentLevelIndex() + 1 );
+ m_hudMap[ i ] = new CHudMap( pPage, i, p3dFile );
+ rAssert( m_hudMap[ i ] != NULL );
+
+ // Get Hud Map Icons
+ //
+ Scrooby::Group* playerCars = pPage->GetGroup( "PlayerCars" );
+ Scrooby::Group* aiCarsGroup = pPage->GetGroup( "AICars" );
+ Scrooby::Group* aiHarassCars = pPage->GetGroup( "AIHarassCars" );
+ Scrooby::Group* waypointFlags = pPage->GetGroup( "WaypointFlags" );
+ Scrooby::Group* checkeredFlags = pPage->GetGroup( "CheckeredFlags" );
+ Scrooby::Group* collectables = pPage->GetGroup( "Collectibles" );
+ Scrooby::Group* icons0 = pPage->GetGroup( "Icons0" );
+ Scrooby::Group* missions = pPage->GetGroup( "Missions" );
+ Scrooby::Group* bonusMissions = pPage->GetGroup( "BonusMissions" );
+ Scrooby::Group* streetRaces = pPage->GetGroup( "StreetRaces" );
+ Scrooby::Group* wagerRaces = pPage->GetGroup( "WagerRaces" );
+ Scrooby::Group* purchaseCentres = pPage->GetGroup( "PurchaseCentres" );
+ Scrooby::Group* phoneBooths = pPage->GetGroup( "PhoneBooths" );
+ rAssert( playerCars != NULL );
+ rAssert( aiCarsGroup != NULL );
+ rAssert( aiHarassCars != NULL );
+ rAssert( waypointFlags != NULL );
+ rAssert( checkeredFlags != NULL );
+ rAssert( collectables != NULL );
+ rAssert( icons0 != NULL );
+ rAssert( missions != NULL );
+ rAssert( bonusMissions != NULL );
+ rAssert( streetRaces != NULL );
+ rAssert( wagerRaces != NULL );
+ rAssert( purchaseCentres != NULL );
+ rAssert( phoneBooths != NULL );
+
+ sprintf( objectName, "IconPlayer%d", i );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_PLAYER, icons0->GetSprite( objectName ) );
+
+ for( unsigned int j = 0; j < MAX_NUM_ICONS_PER_TYPE; j++ )
+ {
+ sprintf( objectName, "IconMission%d_%d", i, j );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_MISSION, missions->GetSprite( objectName ) );
+
+ sprintf( objectName, "IconCollectible%d_%d", i, j );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_COLLECTIBLE, collectables->GetSprite( objectName ) );
+
+ sprintf( objectName, "IconPlayerCar%d_%d", i, j );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_PLAYER_CAR, playerCars->GetSprite( objectName ) );
+
+ sprintf( objectName, "IconAICar%d_%d", i, j );
+ Scrooby::Sprite* aiCarIcon = aiCarsGroup->GetSprite( objectName );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_AI_CHASE, aiCarIcon );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_AI_RACE, aiCarIcon );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_AI_EVADE, aiCarIcon );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_AI_TARGET, aiCarIcon );
+
+ sprintf( objectName, "IconHarass%d_%d", i, j );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_AI_HIT_N_RUN, aiHarassCars->GetSprite( objectName ) );
+
+ sprintf( objectName, "IconWaypoint%d_%d", i, j );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_FLAG_WAYPOINT, waypointFlags->GetSprite( objectName ) );
+
+ sprintf( objectName, "IconChecker%d_%d", i, j );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_FLAG_CHECKERED, checkeredFlags->GetSprite( objectName ) );
+
+ sprintf( objectName, "BonusMission%d_%d", i, j );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_BONUS_MISSION, bonusMissions->GetSprite( objectName ) );
+
+ sprintf( objectName, "StreetRace%d_%d", i, j );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_STREET_RACE, streetRaces->GetSprite( objectName ) );
+
+ sprintf( objectName, "WagerRace%d_%d", i, j );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_WAGER_RACE, wagerRaces->GetSprite( objectName ) );
+
+ sprintf( objectName, "PhoneBooth%d_%d", i, j );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_PHONE_BOOTH, phoneBooths->GetSprite( objectName ) );
+
+ sprintf( objectName, "PurchaseCentre%d_%d", i, j );
+ m_hudMap[ i ]->AddIconToInventory( HudMapIcon::ICON_PURCHASE_CENTRE, purchaseCentres->GetSprite( objectName ) );
+ }
+
+ m_hudMap[ i ]->RestoreAllRegisteredIcons();
+ }
+MEMTRACK_POP_GROUP("CGUIScreenMultiHud");
+}
+
+void
+CGuiScreenMultiHud::UpdateElements( unsigned int elapsedTime )
+{
+ float elapsedTimeFloat = static_cast< float >( elapsedTime );
+ g_TimeSinceLastDeathVolume += elapsedTimeFloat;
+ g_WhiteWashIn.Update( elapsedTimeFloat );
+ g_WhiteWashPause.Update( elapsedTimeFloat );
+ g_TutorialPulse.Update( elapsedTimeFloat );
+
+ for( int i = 0; i < m_numActivePlayers; i++ )
+ {
+#ifdef SRR2_SHOW_SPEEDOMETER
+ // update speedometer
+ //
+ if( CommandLineOptions::Get( CLO_SHOW_SPEED ) ||
+ GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_SHOW_SPEEDOMETER ) )
+ {
+ unsigned int speed = 0;
+
+ Avatar* pAvatar = GetAvatarManager()->GetAvatarForPlayer( i );
+ rAssert( pAvatar );
+ if( pAvatar->IsInCar() )
+ {
+ Vehicle* vehicle = pAvatar->GetVehicle();
+ rAssert( vehicle );
+
+ speed = (unsigned int)vehicle->GetSpeedKmh();
+ }
+ else
+ {
+ Character* pCharacter = pAvatar->GetCharacter();
+ rAssert( pCharacter );
+
+ speed = (unsigned int)pCharacter->GetSpeed();
+ }
+
+ m_speedDigital[ i ].SetVisible( true );
+ m_speedDigital[ i ].SetValue( speed );
+ }
+ else
+ {
+ m_speedDigital[ i ].SetVisible( false );
+ }
+#endif // SRR2_SHOW_SPEEDOMETER
+
+ // update hud map
+ //
+ rAssert( m_hudMap[ i ] );
+ m_hudMap[ i ]->Update( elapsedTime );
+ }
+}
+
+//===========================================================================
+// CGuiScreenHud::TutorialBitmapHide
+//===========================================================================
+// Description: hides the tutorial mode bitmap
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiHud::TutorialBitmapHide()
+{
+ m_tutorialWalkie->SetVisible( false );
+ m_TutorialBitmapVisible = false;
+}
+
+//===========================================================================
+// CGuiScreenHud::TutorialBitmapInitOutro
+//===========================================================================
+// Description: starts the outro transition of the tutorial bitmap
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiHud::TutorialBitmapInitOutro()
+{
+ m_TutorialBitmapTransitionIn.Deactivate();
+ m_TutorialBitmapSteadyState.Deactivate();
+ m_TutorialBitmapTransitionOut.Activate();
+ m_TurorialBitmapStayOut.Deactivate();
+ m_TutorialBitmapTimeShown = maxDisplayTime;
+}
+//===========================================================================
+// CGuiScreenHud::TutorialBitmapShow
+//===========================================================================
+// Description: shows the tutorial mode bitmap.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiHud::TutorialBitmapShow()
+{
+ m_tutorialWalkie->SetVisible( true );
+ m_TutorialBitmapVisible = true;
+ m_TutorialBitmapTimeShown = 0.0f;
+ m_TutorialBitmapTransitionIn.Reset();
+ m_TutorialBitmapTransitionOut.Reset();
+ m_TutorialBitmapSteadyState.Reset();
+ m_TutorialBitmapTransitionIn.Activate();
+ m_TutorialBitmapTransitionOut.Deactivate();
+ m_TutorialBitmapSteadyState.Deactivate();
+ m_TurorialBitmapStayOut.Deactivate();
+}
+
+//===========================================================================
+// CGuiScreenHud::TutorialBitmapHide
+//===========================================================================
+// Description: hides the tutorial mode bitmap
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiHud::UpdateTutorialMode( const float deltaT )
+{
+ m_tutorialWalkie->ResetTransformation();
+ m_TutorialBitmapTransitionIn.Update( deltaT );
+ m_TutorialBitmapSteadyState.Update( deltaT );
+ if( m_TutorialBitmapTransitionOut.IsActive() )
+ {
+ m_TutorialBitmapTransitionOut.Update( deltaT );
+ if( m_TutorialBitmapTransitionOut.IsDone() )
+ {
+ this->TutorialBitmapHide();
+ }
+ }
+ m_TurorialBitmapStayOut.Update( deltaT );
+}
+
+//===========================================================================
+// CGuiScreenMultiHud::SetTutorialMessage
+//===========================================================================
+// Description: hides the tutorial mode bitmap
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiHud::SetTutorialMessage( int index )
+{
+ char textBibleID[ 32 ];
+ sprintf( textBibleID, "TUTORIAL_%03d", index );
+
+ rAssert( m_tutorialMessage != NULL );
+ m_tutorialMessage->SetBitmapText( GetTextBibleString( textBibleID ) );
+}
+
+//===========================================================================
+// CGuiScreenMultiHud::ShowLetterBox
+//===========================================================================
+// Description: shows the letterbox
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMultiHud::ShowLetterBox()
+{
+ m_LetterboxPage->SetVisible( true );
+}
+
+//===========================================================================
+// ResetCar::ResetCar
+//===========================================================================
+// Description: constructor for the reset car transition
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+ResetCar::ResetCar()
+{
+}
+
+//===========================================================================
+// ResetCar::Activate
+//===========================================================================
+// Description: Activate - does the work of the reset car trasntition
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void ResetCar::Activate()
+{
+ if( this->mEventData == NULL )
+ {
+ bool manualDamageReset = CommandLineOptions::Get( CLO_MANUAL_RESET_DAMAGE );
+ rAssert( m_Vehicle != NULL );
+ if( m_Vehicle != NULL )
+ {
+ m_Vehicle->ResetOnSpot( manualDamageReset );
+ m_Vehicle = NULL;
+ }
+ }
+ else
+ {
+ SendEvent::Activate();
+ }
+ ContinueChain();
+}
+
+//===========================================================================
+// ResetCar::SetVehicle
+//===========================================================================
+// Description: sets the vehicle that's going to get reset
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void ResetCar::SetVehicle( Vehicle* vehicle )
+{
+ m_Vehicle = vehicle;
+}
diff --git a/game/code/presentation/gui/ingame/guiscreenmultihud.h b/game/code/presentation/gui/ingame/guiscreenmultihud.h
new file mode 100644
index 0000000..b6aff7c
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenmultihud.h
@@ -0,0 +1,91 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMultiHud
+//
+// Description:
+//
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/11/20 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMULTIHUD_H
+#define GUISCREENMULTIHUD_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <presentation/gui/utility/numerictext.h>
+#include <presentation/gui/utility/slider.h>
+#include <presentation/gui/utility/transitions.h>
+#include <constants/maxplayers.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class CHudMap;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMultiHud : public CGuiScreen
+{
+public:
+ CGuiScreenMultiHud( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenMultiHud();
+
+ CGuiScreenMultiHud( Scrooby::Screen* pScreen, CGuiEntity* pParent,
+ eGuiWindowID id, int numActivePlayers );
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CHudMap* GetHudMap( unsigned int playerID ) const;
+
+ void TutorialBitmapShow();
+ void TutorialBitmapHide();
+ void TutorialBitmapInitOutro();
+ void SetTutorialMessage( int index );
+ void ShowLetterBox();
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+ void RetrieveElements( Scrooby::Page* pPage );
+ void UpdateElements( unsigned int elapsedTime );
+ void UpdateTutorialMode( const float deltaT );
+
+ int m_numActivePlayers;
+
+ NumericText<Scrooby::Text> m_speedDigital[ MAX_PLAYERS ];
+
+ static const int MAX_TUTORIAL_MESSAGE_LENGTH = 256;
+
+ ImageSlider m_gasMeter[ MAX_PLAYERS ];
+ CHudMap* m_hudMap[ MAX_PLAYERS ];
+ Scrooby::Group* m_tutorialWalkie;
+ Scrooby::Sprite* m_tutorialMessage;
+ bool m_TutorialBitmapVisible : 1;
+ bool m_isStartButtonPressed : 1;
+ float m_TutorialBitmapTimeShown;
+ GuiSFX::UnderdampedTranslator m_TutorialBitmapTransitionIn;
+ GuiSFX::Translator m_TutorialBitmapSteadyState;
+ GuiSFX::Translator m_TutorialBitmapTransitionOut;
+ GuiSFX::Translator m_TurorialBitmapStayOut;
+ Scrooby::Page* m_LetterboxPage;
+
+};
+
+
+#endif // GUISCREENMULTIHUD_H
diff --git a/game/code/presentation/gui/ingame/guiscreenpause.cpp b/game/code/presentation/gui/ingame/guiscreenpause.cpp
new file mode 100644
index 0000000..1962dbc
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpause.cpp
@@ -0,0 +1,646 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPause
+//
+// Description: Implementation of the CGuiScreenPause class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/11/20 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenpause.h>
+#include <presentation/gui/ingame/guiscreenhud.h>
+#include <presentation/gui/ingame/guihudtextbox.h>
+#include <presentation/gui/ingame/hudevents/hudmissionobjective.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guiscreenprompt.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/ingame/guimanageringame.h>
+#include <data/memcard/memorycardmanager.h>
+
+#include <cards/card.h>
+#include <memory/srrmemory.h>
+#include <mission/gameplaymanager.h>
+#include <worldsim/coins/coinmanager.h>
+
+// Pure3D
+#include <p3d/utility.hpp>
+#include <p3d/sprite.hpp>
+
+#include <raddebug.hpp> // Foundation
+#include <radtime.hpp>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <app.h>
+#include <group.h>
+#include <layer.h>
+#include <page.h>
+#include <screen.h>
+#include <sprite.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenPause::CGuiScreenPause
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPause::CGuiScreenPause
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent,
+ eGuiWindowID id
+)
+: CGuiScreen( pScreen, pParent, id ),
+ m_pMenu( NULL ),
+ m_MissionObjectiveBox( NULL ),
+ m_pressStart( NULL ),
+ m_missionObjective( NULL ),
+ m_objectiveIcon( NULL ),
+ m_numVisibleCards( NUM_CARDS_PER_LEVEL ),
+ m_elapsedTime( 0 )
+{
+ memset( m_collectedCards, 0, sizeof( m_collectedCards ) );
+/*
+ // Retrieve the Scrooby drawing elements (from Pause Cards page).
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "PauseCards" );
+ rAssert( pPage );
+
+ Scrooby::Group* collectableCards = pPage->GetGroup( "CollectedCards" );
+ rAssert( collectableCards != NULL );
+
+ char cardName[ 32 ];
+ for( unsigned int i = 0; i < sizeof( m_collectedCards ) /
+ sizeof( m_collectedCards[ 0 ] ); i++ )
+ {
+ sprintf( cardName, "Card%d", i );
+ m_collectedCards[ i ] = collectableCards->GetSprite( cardName );
+ rAssert( m_collectedCards[ i ] );
+ }
+*/
+ // Retrieve the Scrooby drawing elements (from Coins page).
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Coins" );
+ rAssert( pPage != NULL );
+ CGuiScreenHud::SetNumCoinsDisplay( pPage->GetSprite( "NumCoins" ) );
+
+ // Retrieve the Scrooby drawing elements (from PauseMissionObjective page).
+ //
+ pPage = m_pScroobyScreen->GetPage( "PauseMissionObjective" );
+ rAssert( pPage != NULL );
+
+ Scrooby::Group* pGroup = pPage->GetGroup( "MissionObjective" );
+ m_MissionObjectiveBox = pGroup;
+ rAssert( pGroup != NULL );
+
+ m_missionObjective = pGroup->GetText( "MissionObjective" );
+ rAssert( m_missionObjective != NULL );
+ m_missionObjective->SetTextMode( Scrooby::TEXT_WRAP );
+ m_missionObjective->ResetTransformation();
+ m_missionObjective->Translate( 0, MESSAGE_TEXT_VERTICAL_TRANSLATION );
+ m_missionObjective->ScaleAboutPoint( MESSAGE_TEXT_SCALE * MESSGAE_TEXT_HORIZONTAL_STRETCH,
+ MESSAGE_TEXT_SCALE,
+ 1.0f, 0, 0 );
+
+ m_objectiveIcon = pGroup->GetSprite( "ObjectiveIcon" );
+ rAssert( m_objectiveIcon != NULL );
+ m_objectiveIcon->SetVisible( false );
+ m_objectiveIcon->ResetTransformation();
+ m_objectiveIcon->ScaleAboutCenter( MISSION_ICON_SCALE );
+
+ // apply correction scale to message box
+ //
+ Scrooby::Sprite* messageBox = pGroup->GetSprite( "MessageBox" );
+ rAssert( messageBox != NULL );
+ messageBox->ResetTransformation();
+ messageBox->ScaleAboutCenter( MESSAGE_BOX_CORRECTION_SCALE * MESSAGE_BOX_HORIZONTAL_STRETCH,
+ MESSAGE_BOX_CORRECTION_SCALE * MESSAGE_BOX_VERTICAL_STRETCH,
+ 1.0f );
+
+ // Retrieve the Scrooby drawing elements (from Pause Foreground page).
+ //
+ pPage = m_pScroobyScreen->GetPage( "PauseFgd" );
+ if( pPage != NULL )
+ {
+#ifdef RAD_WIN32
+ pPage->SetVisible( false );
+#endif
+
+ // Wrap "Press Start" help text
+ //
+ m_pressStart = pPage->GetText( "PressStartResumePlay" );
+ if( m_pressStart != NULL )
+ {
+ m_pressStart->SetTextMode( Scrooby::TEXT_WRAP );
+
+ // add text outline
+ //
+ m_pressStart->SetDisplayOutline( true );
+
+ // set platform-specific text
+ //
+ m_pressStart->SetIndex( PLATFORM_TEXT_INDEX );
+ }
+ }
+
+ this->AutoScaleFrame( m_pScroobyScreen->GetPage( "XSmallBoard" ) );
+
+ this->SetZoomingEnabled( true );
+
+ #ifdef DEBUGWATCH
+ const char* screenName = GetWatcherName();
+ m_MissionObjectiveBox->WatchAll( screenName );
+ m_objectiveIcon-> WatchAll( screenName );
+ m_missionObjective-> WatchAll( screenName );
+ m_pressStart-> WatchAll( screenName );
+ #endif
+}
+
+
+//===========================================================================
+// CGuiScreenPause::~CGuiScreenPause
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPause::~CGuiScreenPause()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenPause::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPause::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+#ifdef RAD_WIN32
+ if( message == GUI_MSG_MENU_PROMPT_RESPONSE &&
+ param1 == PROMPT_CONFIRM_QUIT_TO_SYSTEM )
+ {
+ switch( param2 )
+ {
+ case (CGuiMenuPrompt::RESPONSE_YES):
+ {
+ // Tell the current screen to shut down.
+ //
+ m_pParent->HandleMessage( GUI_MSG_QUIT_TO_SYSTEM );
+
+ break;
+ }
+
+ case (CGuiMenuPrompt::RESPONSE_NO):
+ {
+ this->ReloadScreen();
+
+ break;
+ }
+
+ default:
+ {
+ rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" );
+
+ break;
+ }
+ }
+ }
+#endif
+
+ if( message == GUI_MSG_MENU_PROMPT_RESPONSE &&
+ param1 == PROMPT_CONFIRM_QUIT )
+ {
+ switch( param2 )
+ {
+ case (CGuiMenuPrompt::RESPONSE_YES):
+ {
+ m_pParent->HandleMessage( GUI_MSG_QUIT_INGAME );
+
+ break;
+ }
+
+ case (CGuiMenuPrompt::RESPONSE_NO):
+ {
+ this->ReloadScreen();
+
+ break;
+ }
+
+ default:
+ {
+ rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" );
+
+ break;
+ }
+ }
+ }
+
+ if ( message==GUI_MSG_PROMPT_START_RESPONSE )
+ {
+ m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME );
+ }
+
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+
+ case GUI_MSG_UPDATE:
+ {
+ GetMemoryCardManager()->Update( param1 );
+ HudMissionObjective* hudMissionObjective = static_cast<HudMissionObjective*>( GetCurrentHud()->GetEventHandler( CGuiScreenHud::HUD_EVENT_HANDLER_MISSION_OBJECTIVE ) );
+ hudMissionObjective->UpdateIcon();
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_START:
+ {
+ if( !m_pMenu->HasSelectionBeenMade() )
+ {
+ this->HandleResumeGame();
+ }
+
+ break;
+ }
+
+#ifdef RAD_WIN32
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ // This is our start button for PC.
+ this->HandleResumeGame();
+ break;
+ }
+#endif
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ //
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+ else if( m_state == GUI_WINDOW_STATE_OUTRO )
+ {
+ if( m_numTransitionsPending <= 0 )
+ {
+ // restore press start text
+ //
+ if( m_pressStart != NULL )
+ {
+ m_pressStart->ResetTransformation();
+ m_pressStart->SetHorizontalJustification( Scrooby::Left );
+ }
+
+ rAssert( m_objectiveIcon != NULL );
+ m_objectiveIcon->SetRawSprite( NULL );
+ m_objectiveIcon->SetVisible( false );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenPause::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPause::InitIntro()
+{
+/*
+ // update collect cards display for current level
+ //
+ unsigned int currentLevel = GetGameplayManager()->GetCurrentLevelIndex();
+ const CardList* collectedCards = GetCardGallery()->GetCollectedCards( currentLevel );
+ rAssert( collectedCards );
+
+ for( unsigned int i = 0; i < sizeof( m_collectedCards ) /
+ sizeof( m_collectedCards[ 0 ] ); i++ )
+ {
+ rAssert( m_collectedCards[ i ] );
+
+ if( collectedCards->m_cards[ i ] != NULL )
+ {
+ unsigned int cardID = collectedCards->m_cards[ i ]->GetID();
+ rAssert( cardID < static_cast<unsigned int>( m_collectedCards[ i ]->GetNumOfImages() ) );
+ m_collectedCards[ i ]->SetIndex( cardID + 1 );
+ }
+ else
+ {
+ m_collectedCards[ i ]->SetIndex( 0 );
+ }
+ }
+
+ this->HideCards();
+*/
+ Mission* currentMission = GetGameplayManager()->GetCurrentMission();
+ if( currentMission != NULL )
+ {
+ MissionStage* currentStage = currentMission->GetCurrentStage();
+ if( currentStage != NULL )
+ {
+ // update mission objective text
+ //
+ rAssert( m_missionObjective != NULL );
+
+ int currentMissionObjective = currentStage->GetStartMessageIndex();
+ if( currentMissionObjective >= 0 ) // && currentStage->GetMissionLocked() )
+ {
+ rAssert( currentMissionObjective < m_missionObjective->GetNumOfStrings() );
+ m_missionObjective->SetIndex( currentMissionObjective );
+ m_missionObjective->SetVisible( true );
+ m_MissionObjectiveBox->SetVisible( true );
+ }
+ else
+ {
+ rWarningMsg( false, "Invalid mission objective message index!" );
+ m_missionObjective->SetVisible( false );
+ m_MissionObjectiveBox->SetVisible( false );
+ }
+
+ // update mission objective icon
+ //
+ tSprite* pSprite = NULL;
+ const char* iconName = currentStage->GetHUDIcon();
+ if( iconName[ 0 ] != '\0' )
+ {
+ pSprite = p3d::find<tSprite>( iconName );
+ rTuneWarningMsg( pSprite != NULL, "Can't find mission objective icon!" );
+ }
+
+ rAssert( m_objectiveIcon != NULL );
+ m_objectiveIcon->SetVisible( pSprite != NULL );
+ m_objectiveIcon->SetRawSprite( pSprite, true );
+ }
+ else
+ {
+ m_MissionObjectiveBox->SetVisible( false );
+ }
+ }
+ else
+ {
+ m_MissionObjectiveBox->SetVisible( false );
+ }
+
+ // move press start text to bottom center of pause menu box
+ //
+ if( m_pressStart != NULL )
+ {
+ int centerX, centerY;
+ m_pressStart->GetBoundingBoxCenter( centerX, centerY );
+
+ int screenCenterX = static_cast<int>( Scrooby::App::GetInstance()->GetScreenWidth() / 2 );
+
+ m_pressStart->ResetTransformation();
+ m_pressStart->Translate( screenCenterX - centerX, 85 );
+ m_pressStart->SetHorizontalJustification( Scrooby::Centre );
+ }
+
+ // reset pause menu to default selection
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->Reset();
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenPause::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPause::InitRunning()
+{
+ // show coins
+ //
+ CGuiScreenHud::UpdateNumCoinsDisplay( GetCoinManager()->GetBankValue() );
+
+ // disable screen zooming
+ //
+ this->SetZoomingEnabled( false );
+}
+
+
+//===========================================================================
+// CGuiScreenPause::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPause::InitOutro()
+{
+ // hide coins
+ //
+ CGuiScreenHud::UpdateNumCoinsDisplay( 0, false );
+}
+
+
+//===========================================================================
+// CGuiScreenPause::HandleResumeGame
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPause::HandleResumeGame( unsigned int param1,
+ unsigned int param2 )
+{
+ // enable zoom-out when returning to game
+ //
+ this->SetZoomingEnabled( true );
+
+ // resume game
+ m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenPause::HandleQuitGame
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPause::HandleQuitGame()
+{
+ rAssert( m_guiManager );
+ m_guiManager->DisplayPrompt( PROMPT_CONFIRM_QUIT, this );
+}
+
+#ifdef RAD_WIN32
+//===========================================================================
+// CGuiScreenPause::HandleQuitToSystem
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPause::HandleQuitToSystem()
+{
+ rAssert( m_guiManager );
+ m_guiManager->DisplayPrompt( PROMPT_CONFIRM_QUIT_TO_SYSTEM, this );
+}
+#endif
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+/*
+void
+CGuiScreenPause::HideCards()
+{
+ // hide all cards
+ //
+ for( unsigned int i = 0; i < NUM_CARDS_PER_LEVEL; i++ )
+ {
+ rAssert( m_collectedCards[ i ] );
+ m_collectedCards[ i ]->SetVisible( false );
+ }
+
+ // set num visible cards to zero
+ //
+ m_numVisibleCards = 0;
+}
+
+void
+CGuiScreenPause::ShowNextCard()
+{
+ // randomize next card to show
+ //
+ int nextCard = 0;
+
+ int numHiddenCards = NUM_CARDS_PER_LEVEL - m_numVisibleCards;
+ if( numHiddenCards > 1 )
+ {
+ nextCard = rand() % numHiddenCards;
+ }
+
+ // show next card
+ //
+ for( unsigned int i = 0; i < NUM_CARDS_PER_LEVEL; i++ )
+ {
+ rAssert( m_collectedCards[ i ] );
+
+ if( m_collectedCards[ i ]->IsVisible() )
+ {
+ continue;
+ }
+ else
+ {
+ if( nextCard == 0 )
+ {
+ m_collectedCards[ i ]->SetVisible( true );
+ break;
+ }
+ else
+ {
+ nextCard--;
+ }
+ }
+ }
+
+ m_numVisibleCards++;
+}
+*/
+
+#ifdef DEBUGWATCH
+const char* CGuiScreenPause::GetWatcherName() const
+{
+ return "GuiScreenPause";
+}
+#endif
diff --git a/game/code/presentation/gui/ingame/guiscreenpause.h b/game/code/presentation/gui/ingame/guiscreenpause.h
new file mode 100644
index 0000000..1082f23
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpause.h
@@ -0,0 +1,83 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPause
+//
+// Description:
+//
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/11/20 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENPAUSE_H
+#define GUISCREENPAUSE_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <cards/cardgallery.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenPause : public CGuiScreen
+{
+public:
+ CGuiScreenPause( Scrooby::Screen* pScreen,
+ CGuiEntity* pParent,
+ eGuiWindowID id );
+ virtual ~CGuiScreenPause();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+ void HandleResumeGame( unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+ void HandleQuitGame();
+#ifdef RAD_WIN32
+ void HandleQuitToSystem();
+#endif
+ #ifdef DEBUGWATCH
+ virtual const char* GetWatcherName() const;
+ #endif
+
+
+ CGuiMenu* m_pMenu;
+ Scrooby::Group* m_MissionObjectiveBox;
+ Scrooby::Text* m_pressStart;
+ Scrooby::Text* m_missionObjective;
+ Scrooby::Sprite* m_objectiveIcon;
+
+private:
+/*
+ void HideCards();
+ void ShowNextCard();
+*/
+
+ Scrooby::Sprite* m_collectedCards[ NUM_CARDS_PER_LEVEL ];
+ int m_numVisibleCards;
+ unsigned int m_elapsedTime;
+
+};
+
+#endif // GUISCREENPAUSE_H
diff --git a/game/code/presentation/gui/ingame/guiscreenpausecontroller.cpp b/game/code/presentation/gui/ingame/guiscreenpausecontroller.cpp
new file mode 100644
index 0000000..b175d81
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpausecontroller.cpp
@@ -0,0 +1,224 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPauseController
+//
+// Description: Implementation of the CGuiScreenPauseController class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenpausecontroller.h>
+
+#include <input/inputmanager.h>
+#include <memory/srrmemory.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <mission/gameplaymanager.h>
+#include <worldsim/avatarmanager.h>
+#include <worldsim/avatar.h>
+
+#include <raddebug.hpp> // Foundation
+
+#include <screen.h>
+#include <layer.h>
+#include <page.h>
+#include <sprite.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const float CONTROLLER_IMAGE_CORRECTION_SCALE = 2.0f;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenPauseController::CGuiScreenPauseController
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPauseController::CGuiScreenPauseController
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreenController( pScreen, pParent )
+{
+#ifndef RAD_WIN32
+ rAssert( pScreen != NULL );
+ Scrooby::Page* pPage = pScreen->GetPage( "ControllerImageS" );
+ rAssert( pPage != NULL );
+ Scrooby::Layer* foreground = pPage->GetLayer( "Foreground" );
+ rAssert( foreground != NULL );
+
+ Scrooby::Sprite* controllerImage = foreground->GetSprite( "Controller" );
+ if( controllerImage != NULL )
+ {
+ controllerImage->ScaleAboutCenter( CONTROLLER_IMAGE_CORRECTION_SCALE );
+ }
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenPauseController::~CGuiScreenPauseController
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPauseController::~CGuiScreenPauseController()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenPauseController::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseController::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_START:
+ {
+ // resume game
+ m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME );
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreenController::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenPauseController::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseController::InitIntro()
+{
+ CGuiScreenController::InitIntro();
+}
+
+
+//===========================================================================
+// CGuiScreenPauseController::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseController::InitRunning()
+{
+ CGuiScreenController::InitRunning();
+}
+
+
+//===========================================================================
+// CGuiScreenPauseController::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseController::InitOutro()
+{
+ CGuiScreenController::InitOutro();
+
+ // apply vibration/rumble setting right away
+ //
+ int controllerID = GetInputManager()->GetControllerIDforPlayer( 0 );
+ bool vibrationOn = GetInputManager()->IsRumbleEnabled();
+
+ if ( GetGameplayManager()->GetGameType() == GameplayManager::GT_NORMAL &&
+ GetAvatarManager()->GetAvatarForPlayer( 0 )->GetVehicle() )
+ {
+#ifdef RAD_PS2
+ if ( GetInputManager()->GetController( Input::USB0 )->IsConnected() )
+ {
+ GetInputManager()->SetRumbleForDevice( Input::USB0, vibrationOn );
+ }
+ else if ( GetInputManager()->GetController( Input::USB1 )->IsConnected() )
+ {
+ GetInputManager()->SetRumbleForDevice( Input::USB1, vibrationOn );
+ }
+ else
+ {
+ GetInputManager()->SetRumbleForDevice( controllerID, vibrationOn );
+ }
+#else
+ GetInputManager()->SetRumbleForDevice( controllerID, vibrationOn );
+#endif
+
+ }
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/ingame/guiscreenpausecontroller.h b/game/code/presentation/gui/ingame/guiscreenpausecontroller.h
new file mode 100644
index 0000000..e1b46bf
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpausecontroller.h
@@ -0,0 +1,52 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPauseController
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENPAUSECONTROLLER_H
+#define GUISCREENPAUSECONTROLLER_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#ifdef RAD_WIN32
+#include <presentation/gui/frontend/guiscreencontrollerWin32.h>
+#else
+#include <presentation/gui/frontend/guiscreencontroller.h>
+#endif
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenPauseController : public CGuiScreenController
+{
+public:
+ CGuiScreenPauseController( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenPauseController();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+};
+
+#endif // GUISCREENPAUSECONTROLLER_H
diff --git a/game/code/presentation/gui/ingame/guiscreenpausedisplay.cpp b/game/code/presentation/gui/ingame/guiscreenpausedisplay.cpp
new file mode 100644
index 0000000..a6cd844
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpausedisplay.cpp
@@ -0,0 +1,164 @@
+/******************************************************************************
+ File: CGuiScreenPauseDisplay.cpp
+ Desc: Defines the CGuiScreenPauseDisplay class.
+ Authors: Tony Chu, Neil Haran
+ Date: August 14, 2003
+ History:
+*****************************************************************************/
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenpausedisplay.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const float CONTROLLER_IMAGE_CORRECTION_SCALE = 2.0f;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenPauseDisplay::CGuiScreenPauseDisplay
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPauseDisplay::CGuiScreenPauseDisplay
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreenDisplay( pScreen, pParent )
+{
+}
+
+
+//===========================================================================
+// CGuiScreenPauseDisplay::~CGuiScreenPauseDisplay
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPauseDisplay::~CGuiScreenPauseDisplay()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenPauseDisplay::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseDisplay::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_START:
+ {
+ // resume game
+ m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME );
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreenDisplay::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenPauseDisplay::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseDisplay::InitIntro()
+{
+ CGuiScreenDisplay::InitIntro();
+}
+
+
+//===========================================================================
+// CGuiScreenPauseDisplay::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseDisplay::InitRunning()
+{
+ CGuiScreenDisplay::InitRunning();
+}
+
+
+//===========================================================================
+// CGuiScreenPauseDisplay::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseDisplay::InitOutro()
+{
+ CGuiScreenDisplay::InitOutro();
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/ingame/guiscreenpausedisplay.h b/game/code/presentation/gui/ingame/guiscreenpausedisplay.h
new file mode 100644
index 0000000..200be24
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpausedisplay.h
@@ -0,0 +1,44 @@
+/******************************************************************************
+
+ File: CGuiScreenPauseDisplay.h
+ Desc: Interface for the CGuiScreenController class.
+
+ Date: August 14, 2003
+ Authors: Tony Chu, Neil Haran
+ History:
+
+*****************************************************************************/
+
+#ifndef GUISCREENPAUSEDISPLAY_H
+#define GUISCREENPAUSEDISPLAY_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreendisplay.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenPauseDisplay : public CGuiScreenDisplay
+{
+public:
+ CGuiScreenPauseDisplay( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenPauseDisplay();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+};
+
+#endif // GUISCREENPAUSEDISPLAY_H
diff --git a/game/code/presentation/gui/ingame/guiscreenpausemission.cpp b/game/code/presentation/gui/ingame/guiscreenpausemission.cpp
new file mode 100644
index 0000000..368c83b
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpausemission.cpp
@@ -0,0 +1,366 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPauseMission
+//
+// Description: Implementation of the CGuiScreenPauseMission class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/11/20 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenmissionload.h>
+#include <presentation/gui/ingame/guiscreenpausemission.h>
+#include <presentation/gui/ingame/guimanageringame.h>
+#include <presentation/gui/ingame/guiscreenhud.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guiscreenprompt.h>
+#include <presentation/gui/guisystem.h>
+#include <events/eventmanager.h>
+#include <memory/srrmemory.h>
+#include <mission/gameplaymanager.h>
+#include <mission/mission.h>
+#include <worldsim/hitnrunmanager.h>
+#include <worldsim/avatarmanager.h>
+#include <raddebug.hpp> // Foundation
+#include <group.h>
+#include <page.h>
+#include <screen.h>
+#include <text.h>
+#include <sprite.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+enum eMenuItem
+{
+ MENU_ITEM_CONTINUE,
+// MENU_ITEM_VIEW_MAP,
+ MENU_ITEM_RESTART_MISSION,
+ MENU_ITEM_ABORT_MISSION,
+ MENU_ITEM_OPTIONS,
+ MENU_ITEM_QUIT_GAME,
+
+ NUM_MENU_ITEMS
+};
+
+static const char* MENU_ITEMS[] =
+{
+ "Continue",
+// "ViewMap",
+ "RestartMission",
+ "AbortMission",
+ "Options",
+ "QuitGame"
+};
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenPauseMission::CGuiScreenPauseMission
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPauseMission::CGuiScreenPauseMission
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+:
+ CGuiScreenPause( pScreen, pParent, GUI_SCREEN_ID_PAUSE_MISSION )
+{
+MEMTRACK_PUSH_GROUP( "CGUIScreenPauseMission" );
+ // Create a menu.
+ //
+ m_pMenu = new(GMA_LEVEL_HUD) CGuiMenu( this, NUM_MENU_ITEMS );
+ rAssert( m_pMenu != NULL );
+
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "PauseMission" );
+ rAssert( pPage != NULL );
+
+ // Add menu items
+ //
+ Scrooby::Group* menu = pPage->GetGroup( "Menu" );
+ rAssert( menu != NULL );
+ Scrooby::Text* pText = NULL;
+ for( int i = 0; i < NUM_MENU_ITEMS; i++ )
+ {
+ pText = menu->GetText( MENU_ITEMS[ i ] );
+ rAssert( pText );
+
+ m_pMenu->AddMenuItem( pText );
+ }
+MEMTRACK_POP_GROUP("CGUIScreenPauseMission" );
+}
+
+
+//===========================================================================
+// CGuiScreenPauseMission::~CGuiScreenPauseMission
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPauseMission::~CGuiScreenPauseMission()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenPauseMission::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseMission::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( message == GUI_MSG_MENU_PROMPT_RESPONSE )
+ {
+ if( param1 == PROMPT_CONFIRM_RESTART )
+ {
+ switch( param2 )
+ {
+ case (CGuiMenuPrompt::RESPONSE_YES):
+ {
+ CGuiScreenMissionLoad::ReplaceBitmap();
+ this->HandleResumeGame( ON_HUD_ENTER_RESTART_MISSION );
+ break;
+ }
+
+ case (CGuiMenuPrompt::RESPONSE_NO):
+ {
+ this->ReloadScreen();
+
+ break;
+ }
+
+ default:
+ {
+ rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" );
+
+ break;
+ }
+ }
+ }
+ else if( param1 == PROMPT_CONFIRM_ABORT )
+ {
+ switch( param2 )
+ {
+ case (CGuiMenuPrompt::RESPONSE_YES):
+ {
+ this->HandleResumeGame( ON_HUD_ENTER_ABORT_MISSION );
+ GetEventManager()->TriggerEvent(EVENT_USER_CANCEL_PAUSE_MENU);
+
+ break;
+ }
+
+ case (CGuiMenuPrompt::RESPONSE_NO):
+ {
+ this->ReloadScreen();
+
+ break;
+ }
+
+ default:
+ {
+ rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" );
+
+ break;
+ }
+ }
+ }
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ switch( param1 )
+ {
+ case MENU_ITEM_CONTINUE:
+ {
+ this->HandleResumeGame();
+
+ break;
+ }
+/*
+ case MENU_ITEM_VIEW_MAP:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_HUD_MAP );
+
+ break;
+ }
+*/
+ case MENU_ITEM_RESTART_MISSION:
+ {
+ rAssert( m_guiManager );
+ m_guiManager->DisplayPrompt( PROMPT_CONFIRM_RESTART, this );
+
+// this->HandleResumeGame( ON_HUD_ENTER_RESTART_MISSION );
+
+ break;
+ }
+ case MENU_ITEM_ABORT_MISSION:
+ {
+ rAssert( m_guiManager );
+ m_guiManager->DisplayPrompt( PROMPT_CONFIRM_ABORT, this );
+
+// this->HandleResumeGame( ON_HUD_ENTER_ABORT_MISSION );
+
+ break;
+ }
+ case MENU_ITEM_OPTIONS:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_OPTIONS );
+
+ break;
+ }
+ case MENU_ITEM_QUIT_GAME:
+ {
+ this->HandleQuitGame();
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( 0, "WARNING: Invalid case for switch statement!\n" );
+ break;
+ }
+ }
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreenPause::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenPauseMission::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseMission::InitIntro()
+{
+ CGuiScreenPause::InitIntro();
+
+ // enable 'restart mission' and 'abort mission' only if current mission
+ // isn't completed yet; otherwise, disable these selections
+ //
+ Mission* currentMission = GetGameplayManager()->GetCurrentMission();
+ rAssert( currentMission != NULL );
+
+ HitnRunManager* hnrm = GetHitnRunManager();
+ rAssert( hnrm != NULL );
+
+ AvatarManager* pAvatarManager= GetAvatarManager();
+ rAssert( pAvatarManager != NULL );
+
+ CGuiManagerInGame* guiManagerIngame = static_cast<CGuiManagerInGame*>( m_pParent );
+ rAssert( guiManagerIngame != NULL );
+
+ bool isRestartAndAbortAllowed = !currentMission->IsSundayDrive() &&
+ !currentMission->IsComplete() &&
+ !hnrm->BustingPlayer() &&
+ !pAvatarManager->IsAvatarGettingInOrOutOfCar(0) &&
+ (guiManagerIngame->GetResumeGameScreenID() != GUI_SCREEN_ID_TUTORIAL);
+
+ rAssert( m_pMenu != NULL );
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_RESTART_MISSION, isRestartAndAbortAllowed );
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_ABORT_MISSION, isRestartAndAbortAllowed );
+}
+
+
+//===========================================================================
+// CGuiScreenPauseMission::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseMission::InitRunning()
+{
+ CGuiScreenPause::InitRunning();
+}
+
+
+//===========================================================================
+// CGuiScreenPauseMission::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseMission::InitOutro()
+{
+ CGuiScreenPause::InitOutro();
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
diff --git a/game/code/presentation/gui/ingame/guiscreenpausemission.h b/game/code/presentation/gui/ingame/guiscreenpausemission.h
new file mode 100644
index 0000000..f19fa6c
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpausemission.h
@@ -0,0 +1,50 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPauseMission
+//
+// Description:
+//
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/11/20 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENPAUSEMISSION_H
+#define GUISCREENPAUSEMISSION_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenpause.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenPauseMission : public CGuiScreenPause
+{
+public:
+ CGuiScreenPauseMission( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenPauseMission();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+};
+
+#endif // GUISCREENPAUSEMISSION_H
diff --git a/game/code/presentation/gui/ingame/guiscreenpauseoptions.cpp b/game/code/presentation/gui/ingame/guiscreenpauseoptions.cpp
new file mode 100644
index 0000000..99f90e4
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpauseoptions.cpp
@@ -0,0 +1,315 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPauseOptions
+//
+// Description: Implementation of the CGuiScreenPauseOptions class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenpauseoptions.h>
+#include <presentation/gui/guimenu.h>
+
+#include <cheats/cheatinputsystem.h>
+#include <memory/srrmemory.h>
+
+#include <raddebug.hpp> // Foundation
+#include <group.h>
+#include <screen.h>
+#include <page.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+enum ePauseMenuItem
+{
+#ifdef RAD_WIN32
+ MENU_ITEM_DISPLAY,
+#endif
+ MENU_ITEM_CONTROLLER,
+ MENU_ITEM_SOUND,
+ MENU_ITEM_SETTINGS,
+// MENU_ITEM_CAMERA,
+
+ NUM_PAUSE_MENU_ITEMS
+};
+
+
+static const char* PAUSE_MENU_ITEMS[] =
+{
+#ifdef RAD_WIN32
+ "Display",
+#endif
+ "Controller",
+ "Sound",
+ "Settings",
+// "Camera",
+
+ ""
+};
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenPauseOptions::CGuiScreenPauseOptions
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPauseOptions::CGuiScreenPauseOptions
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_OPTIONS ),
+ m_pMenu( NULL )
+{
+MEMTRACK_PUSH_GROUP( "CGUIScreenPauseOptions" );
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage;
+ pPage = m_pScroobyScreen->GetPage( "PauseOptions" );
+ rAssert( pPage );
+
+ // Create a menu.
+ //
+ m_pMenu = new(GMA_LEVEL_HUD) CGuiMenu( this, NUM_PAUSE_MENU_ITEMS );
+ rAssert( m_pMenu != NULL );
+
+ // Add menu items
+ //
+ Scrooby::Group* menu = pPage->GetGroup( "Menu" );
+ rAssert( menu != NULL );
+ char itemName[ 32 ];
+ for( int i = 0; i < NUM_PAUSE_MENU_ITEMS; i++ )
+ {
+ sprintf( itemName, "%s_Value", PAUSE_MENU_ITEMS[ i ] );
+ Scrooby::Text* pTextValue = pPage->GetText( itemName );
+
+ sprintf( itemName, "%s_LArrow", PAUSE_MENU_ITEMS[ i ] );
+ Scrooby::Sprite* pLArrow = pPage->GetSprite( itemName );
+
+ sprintf( itemName, "%s_RArrow", PAUSE_MENU_ITEMS[ i ] );
+ Scrooby::Sprite* pRArrow = pPage->GetSprite( itemName );
+
+ m_pMenu->AddMenuItem( menu->GetText( PAUSE_MENU_ITEMS[ i ] ),
+ pTextValue,
+ NULL,
+ NULL,
+ pLArrow,
+ pRArrow );
+ }
+
+ // TC: [TEMP] disable controller screen for now to free up some memory for HUD map
+ //
+#ifndef RAD_WIN32
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_CONTROLLER, false, true );
+#endif
+
+#ifdef RAD_E3
+ // disable pause menu settings for E3 build
+ //
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_SETTINGS, false );
+#endif
+MEMTRACK_POP_GROUP("CGUIScreenPauseOptions");
+}
+
+
+//===========================================================================
+// CGuiScreenPauseOptions::~CGuiScreenPauseOptions
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPauseOptions::~CGuiScreenPauseOptions()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenPauseOptions::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseOptions::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( this->IsControllerMessage( message ) &&
+ GetCheatInputSystem()->IsActivated( param1 ) )
+ {
+ // ignore all controller inputs when cheat input system is activated
+ return;
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_START:
+ {
+ if( !m_pMenu->HasSelectionBeenMade() )
+ {
+ // resume game
+ m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME );
+ }
+
+ break;
+ }
+
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ if( param1 == MENU_ITEM_CONTROLLER )
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_CONTROLLER );
+ }
+ else if( param1 == MENU_ITEM_SOUND )
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SOUND );
+ }
+ else if( param1 == MENU_ITEM_SETTINGS )
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SETTINGS );
+ }
+#ifdef RAD_WIN32
+ else if( param1 == MENU_ITEM_DISPLAY )
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_DISPLAY );
+ }
+#endif
+ else
+ {
+ rAssertMsg( false, "Invalid menu selection!" );
+ }
+
+ break;
+ }
+/*
+ case GUI_MSG_MENU_SELECTION_CHANGED:
+ {
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, (param1 != MENU_ITEM_CAMERA) );
+
+ break;
+ }
+*/
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenPauseOptions::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseOptions::InitIntro()
+{
+// this->SetButtonVisible( BUTTON_ICON_ACCEPT, (m_pMenu->GetSelection() != MENU_ITEM_CAMERA) );
+
+#ifndef RAD_E3
+ GetCheatInputSystem()->SetEnabled( true );
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenPauseOptions::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseOptions::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenPauseOptions::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseOptions::InitOutro()
+{
+#ifndef RAD_E3
+ GetCheatInputSystem()->SetEnabled( false );
+#endif
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/ingame/guiscreenpauseoptions.h b/game/code/presentation/gui/ingame/guiscreenpauseoptions.h
new file mode 100644
index 0000000..49f43b1
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpauseoptions.h
@@ -0,0 +1,59 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPauseOptions
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENPAUSEOPTIONS_H
+#define GUISCREENPAUSEOPTIONS_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+namespace Scrooby
+{
+ class Screen;
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenPauseOptions : public CGuiScreen
+{
+public:
+ CGuiScreenPauseOptions( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenPauseOptions();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ CGuiMenu* m_pMenu;
+
+};
+
+#endif // GUISCREENPAUSEOPTIONS_H
diff --git a/game/code/presentation/gui/ingame/guiscreenpausesettings.cpp b/game/code/presentation/gui/ingame/guiscreenpausesettings.cpp
new file mode 100644
index 0000000..479efb4
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpausesettings.cpp
@@ -0,0 +1,557 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPauseSettings
+//
+// Description: Implementation of the CGuiScreenPauseSettings class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenpausesettings.h>
+#include <presentation/gui/ingame/guimanageringame.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/gui/guisystem.h>
+
+#include <camera/supercammanager.h>
+#include <camera/supercamcentral.h>
+#include <input/inputmanager.h>
+#include <memory/srrmemory.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <presentation/tutorialmanager.h>
+#include <worldsim/avatarmanager.h>
+
+#include <raddebug.hpp> // Foundation
+#include <group.h>
+#include <screen.h>
+#include <page.h>
+#include <text.h>
+#include <strings/unicodestring.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+enum ePauseSettingsMenuItem
+{
+ MENU_ITEM_CAMERA,
+ MENU_ITEM_JUMP_CAMERAS,
+#ifndef RAD_WIN32
+ MENU_ITEM_INVERT_CAM_CONTROL,
+#endif
+ MENU_ITEM_INTERSECT_NAV_SYSTEM,
+ MENU_ITEM_RADAR,
+#ifndef RAD_WIN32
+ MENU_ITEM_VIBRATION,
+#endif
+ MENU_ITEM_TUTORIAL,
+
+ NUM_PAUSE_SETTINGS_MENU_ITEMS
+};
+
+
+const char* PAUSE_SETTINGS_MENU_ITEMS[] =
+{
+ "Camera",
+ "JumpCamera",
+#ifndef RAD_WIN32
+ "InvertCamControl",
+#endif
+ "IntersectNavSystem",
+ "Radar",
+#ifndef RAD_WIN32
+ "Vibration",
+#endif
+ "Tutorial",
+
+ ""
+};
+
+#ifdef RAD_WIN32
+SuperCam::Type PC_CAMERAS_FOR_WALKING[] =
+{
+ SuperCam::WALKER_CAM,
+ SuperCam::DEBUG_CAM,
+ SuperCam::KULL_CAM
+};
+
+const int NUM_PC_CAMERAS_FOR_WALKING = sizeof(PC_CAMERAS_FOR_WALKING)/sizeof(SuperCam::Type);
+const int NUM_PC_CAMERAS_FOR_WALKING_WITHOUT_CHEAT = 1;
+#endif
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenPauseSettings::CGuiScreenPauseSettings
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPauseSettings::CGuiScreenPauseSettings
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SETTINGS ),
+ m_pMenu( NULL ),
+ m_currentCameraSelectionMode( CAMERA_SELECTION_NOT_AVAILABLE )
+{
+MEMTRACK_PUSH_GROUP( "CGuiScreenPauseSettings" );
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "PauseSettings" );
+ rAssert( pPage );
+
+ // Create a menu.
+ //
+ m_pMenu = new CGuiMenu( this, NUM_PAUSE_SETTINGS_MENU_ITEMS, GUI_TEXT_MENU, MENU_SFX_NONE );
+ rAssert( m_pMenu != NULL );
+
+ // Add menu items
+ //
+ char itemName[ 32 ];
+
+ for( int i = 0; i < NUM_PAUSE_SETTINGS_MENU_ITEMS; i++ )
+ {
+ Scrooby::Group* group = pPage->GetGroup( PAUSE_SETTINGS_MENU_ITEMS[ i ] );
+ rAssert( group != NULL );
+
+ Scrooby::Text* pText = group->GetText( PAUSE_SETTINGS_MENU_ITEMS[ i ] );
+ rAssert( pText != NULL );
+ pText->SetTextMode( Scrooby::TEXT_WRAP );
+
+ sprintf( itemName, "%s_Value", PAUSE_SETTINGS_MENU_ITEMS[ i ] );
+ Scrooby::Text* pTextValue = group->GetText( itemName );
+ rAssert( pTextValue != NULL );
+ pTextValue->SetTextMode( Scrooby::TEXT_WRAP );
+
+ sprintf( itemName, "%s_LArrow", PAUSE_SETTINGS_MENU_ITEMS[ i ] );
+ Scrooby::Sprite* pLArrow = group->GetSprite( itemName );
+
+ sprintf( itemName, "%s_RArrow", PAUSE_SETTINGS_MENU_ITEMS[ i ] );
+ Scrooby::Sprite* pRArrow = group->GetSprite( itemName );
+
+ m_pMenu->AddMenuItem( pText,
+ pTextValue,
+ NULL,
+ NULL,
+ pLArrow,
+ pRArrow,
+ SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED );
+ }
+
+#ifdef RAD_GAMECUBE
+ // change "Vibration" text to "Rumble"
+ //
+ Scrooby::Text* vibrationText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( MENU_ITEM_VIBRATION )->GetItem() );
+ rAssert( vibrationText != NULL );
+ vibrationText->SetIndex( 1 );
+#endif // RAD_GAMECUBE
+
+ for( int j = 0; j < NUM_CAMERA_SELECTION_MODES; j++ )
+ {
+ m_cameraSelections[ j ] = NULL;
+ m_numCameraSelections[ j ] = 0;
+ }
+
+ m_cameraSelections[ CAMERA_SELECTION_FOR_DRIVING ] = CAMERAS_FOR_DRIVING;
+#ifdef RAD_WIN32
+ m_cameraSelections[ CAMERA_SELECTION_FOR_WALKING ] = PC_CAMERAS_FOR_WALKING;
+#else
+ m_cameraSelections[ CAMERA_SELECTION_FOR_WALKING ] = CAMERAS_FOR_WALKING;
+#endif
+
+ if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_CAMERAS ) )
+ {
+ m_numCameraSelections[ CAMERA_SELECTION_FOR_DRIVING ] = NUM_CAMERAS_FOR_DRIVING;
+
+#ifdef RAD_WIN32
+ m_numCameraSelections[ CAMERA_SELECTION_FOR_WALKING ] = NUM_PC_CAMERAS_FOR_WALKING;
+#else
+ m_numCameraSelections[ CAMERA_SELECTION_FOR_WALKING ] = NUM_CAMERAS_FOR_WALKING;
+#endif
+ }
+ else
+ {
+ m_numCameraSelections[ CAMERA_SELECTION_FOR_DRIVING ] = NUM_CAMERAS_FOR_DRIVING_WITHOUT_CHEAT;
+#ifdef RAD_WIN32
+ m_numCameraSelections[ CAMERA_SELECTION_FOR_WALKING ] = NUM_PC_CAMERAS_FOR_WALKING_WITHOUT_CHEAT;
+#else
+ m_numCameraSelections[ CAMERA_SELECTION_FOR_WALKING ] = NUM_CAMERAS_FOR_WALKING_WITHOUT_CHEAT;
+#endif
+ }
+
+ GetCheatInputSystem()->RegisterCallback( this );
+MEMTRACK_POP_GROUP("CGuiScreenPauseSettings");
+}
+
+
+//===========================================================================
+// CGuiScreenPauseSettings::~CGuiScreenPauseSettings
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPauseSettings::~CGuiScreenPauseSettings()
+{
+ GetCheatInputSystem()->UnregisterCallback( this );
+
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenPauseSettings::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseSettings::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_START:
+ {
+ // resume game
+ //
+ m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME );
+
+ break;
+ }
+
+ case GUI_MSG_MENU_SELECTION_VALUE_CHANGED:
+ {
+ if( param1 == MENU_ITEM_CAMERA )
+ {
+ // set new super cam
+ //
+ SuperCam::Type superCamType = m_cameraSelections[ m_currentCameraSelectionMode ][ param2 ];
+ GetSuperCamManager()->GetSCC( 0 )->SelectSuperCam( superCamType, SuperCamCentral::CUT, 0 );
+
+ // and apply it right away
+ //
+ GetSuperCamManager()->GetSCC( 0 )->Update( 0 );
+ }
+#ifndef RAD_WIN32
+ else if( param1 == MENU_ITEM_VIBRATION )
+ {
+ if( param2 == 1 ) // vibration turned ON
+ {
+ // send vibration pulse to controller
+ //
+ int controllerID = GetInputManager()->GetControllerIDforPlayer( 0 );
+#ifdef RAD_PS2
+ if ( GetInputManager()->IsControllerInPort( Input::USB0 ) )
+ {
+ GetInputManager()->TriggerRumblePulse( Input::USB0 );
+ }
+ else if ( GetInputManager()->IsControllerInPort( Input::USB1 ) )
+ {
+ GetInputManager()->TriggerRumblePulse( Input::USB1 );
+ }
+ else
+#endif
+ {
+ GetInputManager()->TriggerRumblePulse( controllerID );
+ }
+
+ }
+ }
+#endif
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+void
+CGuiScreenPauseSettings::OnCheatEntered( eCheatID cheatID, bool isEnabled )
+{
+ if( cheatID == CHEAT_ID_UNLOCK_CAMERAS && isEnabled )
+ {
+ m_numCameraSelections[ CAMERA_SELECTION_FOR_DRIVING ] = NUM_CAMERAS_FOR_DRIVING;
+ m_numCameraSelections[ CAMERA_SELECTION_FOR_WALKING ] = NUM_CAMERAS_FOR_WALKING;
+ }
+}
+
+//===========================================================================
+// CGuiScreenPauseSettings::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseSettings::InitIntro()
+{
+ // update camera setting
+ //
+ bool allowCameraToggle = GetSuperCamManager()->GetSCC( 0 )->AllowCameraToggle();
+
+ rAssert( m_pMenu );
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_CAMERA, allowCameraToggle );
+
+ if( allowCameraToggle )
+ {
+ // update camera selections
+ //
+ this->UpdateCameraSelections();
+ }
+ else
+ {
+ m_currentCameraSelectionMode = CAMERA_SELECTION_NOT_AVAILABLE;
+ }
+
+ // update other gameplay settings
+ //
+ bool isSettingOn = false;
+
+#ifndef RAD_WIN32
+ isSettingOn = GetSuperCamManager()->GetSCC( 0 )->IsInvertedCameraEnabled();
+ m_pMenu->SetSelectionValue( MENU_ITEM_INVERT_CAM_CONTROL,
+ isSettingOn ? 1 : 0 );
+#endif
+
+ isSettingOn = GetSuperCamManager()->GetSCC( 0 )->JumpCamsEnabled();
+ m_pMenu->SetSelectionValue( MENU_ITEM_JUMP_CAMERAS,
+ isSettingOn ? 1: 0 );
+
+ isSettingOn = GetCharacterSheetManager()->QueryNavSystemSetting();
+ m_pMenu->SetSelectionValue( MENU_ITEM_INTERSECT_NAV_SYSTEM,
+ isSettingOn ? 1 : 0 );
+
+ isSettingOn = GetGuiSystem()->IsRadarEnabled();
+ m_pMenu->SetSelectionValue( MENU_ITEM_RADAR,
+ isSettingOn ? 1 : 0 );
+#ifndef RAD_WIN32
+ isSettingOn = GetInputManager()->IsRumbleEnabled();
+ m_pMenu->SetSelectionValue( MENU_ITEM_VIBRATION,
+ isSettingOn ? 1 : 0 );
+#endif
+
+ isSettingOn = GetTutorialManager()->IsTutorialEventsEnabled();
+ m_pMenu->SetSelectionValue( MENU_ITEM_TUTORIAL,
+ isSettingOn ? 1 : 0 );
+
+ // show/hide tutorial setting depending on whether or not tutorial mode is enabled
+ //
+ if( GetTutorialManager()->IsTutorialModeEnabled() )
+ {
+ CGuiManagerInGame* guiManagerIngame = static_cast<CGuiManagerInGame*>( m_pParent );
+ rAssert( guiManagerIngame != NULL );
+
+ bool isTutorialToggleAllowed = (guiManagerIngame->GetResumeGameScreenID() != GUI_SCREEN_ID_TUTORIAL);
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_TUTORIAL, isTutorialToggleAllowed );
+ }
+ else
+ {
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_TUTORIAL, false, true );
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenPauseSettings::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseSettings::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenPauseSettings::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseSettings::InitOutro()
+{
+ // apply new gameplay settings
+ //
+ rAssert( m_pMenu != NULL );
+ bool isSettingOn = false;
+
+#ifndef RAD_WIN32
+ isSettingOn = (m_pMenu->GetSelectionValue( MENU_ITEM_INVERT_CAM_CONTROL ) == 1);
+ GetSuperCamManager()->GetSCC( 0 )->EnableInvertedCamera( isSettingOn );
+#endif
+
+ isSettingOn = (m_pMenu->GetSelectionValue( MENU_ITEM_JUMP_CAMERAS ) == 1);
+ GetSuperCamManager()->GetSCC( 0 )->EnableJumpCams( isSettingOn );
+
+ isSettingOn = (m_pMenu->GetSelectionValue( MENU_ITEM_INTERSECT_NAV_SYSTEM ) == 1);
+ GetCharacterSheetManager()->SetNavSystemOn( isSettingOn );
+
+ isSettingOn = (m_pMenu->GetSelectionValue( MENU_ITEM_RADAR ) == 1);
+ GetGuiSystem()->SetRadarEnabled( isSettingOn );
+
+#ifndef RAD_WIN32
+ isSettingOn = (m_pMenu->GetSelectionValue( MENU_ITEM_VIBRATION ) == 1);
+ GetInputManager()->SetRumbleEnabled( isSettingOn );
+#endif
+
+ isSettingOn = (m_pMenu->GetSelectionValue( MENU_ITEM_TUTORIAL ) == 1)
+#ifdef RAD_WIN32
+ && !(GetInputManager()->GetController(0)->IsTutorialDisabled())
+#endif
+ ;
+ GetTutorialManager()->EnableTutorialEvents( isSettingOn );
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenPauseSettings::UpdateCameraSelections()
+{
+ rAssert( m_pMenu );
+
+ // set current camera selection mode
+ //
+ bool isPlayerInCar = GetAvatarManager()->GetAvatarForPlayer( 0 )->IsInCar();
+ m_currentCameraSelectionMode = isPlayerInCar ? CAMERA_SELECTION_FOR_DRIVING : CAMERA_SELECTION_FOR_WALKING;
+
+ // get current active camera
+ //
+ SuperCam* currentSuperCam = GetSuperCamManager()->GetSCC( 0 )->GetActiveSuperCam();
+ rAssert( currentSuperCam );
+ SuperCam::Type currentSuperCamType = currentSuperCam->GetType();
+
+ int currentCameraIndex = -1;
+
+ // check to see if current camera is in the selection list
+ //
+ for( int i = 0; i < m_numCameraSelections[ m_currentCameraSelectionMode ]; i++ )
+ {
+ if( m_cameraSelections[ m_currentCameraSelectionMode ][ i ] == currentSuperCamType )
+ {
+ currentCameraIndex = i;
+
+ break;
+ }
+ }
+
+ if( currentCameraIndex == -1 )
+ {
+ // current camera not found in selection list, disable camera selection
+ //
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_CAMERA, false );
+
+ m_currentCameraSelectionMode = CAMERA_SELECTION_NOT_AVAILABLE;
+
+ return;
+ }
+
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_CAMERA, true );
+
+ // set number of camera selections available
+ //
+ m_pMenu->SetSelectionValueCount( MENU_ITEM_CAMERA,
+ m_numCameraSelections[ m_currentCameraSelectionMode ] );
+
+ // update camera names
+ //
+ for( int i = 0; i < m_numCameraSelections[ m_currentCameraSelectionMode ]; i++ )
+ {
+ GuiMenuItem* menuItemCamera = m_pMenu->GetMenuItem( MENU_ITEM_CAMERA );
+ rAssert( menuItemCamera != NULL );
+
+ SuperCam* superCam = GetSuperCamManager()->GetSCC( 0 )->GetSuperCam( m_cameraSelections[ m_currentCameraSelectionMode ][ i ] );
+ rAssert( superCam );
+
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ P3D_UNICODE* stringBuffer = GetTextBibleString( superCam->GetName() );
+ rAssert( stringBuffer );
+
+ UnicodeString unicodeString;
+ unicodeString.ReadUnicode( static_cast<UnicodeChar*>( stringBuffer ) );
+
+ Scrooby::Text* menuItemValue = dynamic_cast<Scrooby::Text*>( menuItemCamera->GetItemValue() );
+ rAssert( menuItemValue != NULL );
+ menuItemValue->SetString( i, unicodeString );
+
+ HeapMgr()->PopHeap(GMA_LEVEL_HUD);
+ }
+
+ // set current camera selection
+ //
+ m_pMenu->SetSelectionValue( MENU_ITEM_CAMERA, currentCameraIndex );
+}
+
diff --git a/game/code/presentation/gui/ingame/guiscreenpausesettings.h b/game/code/presentation/gui/ingame/guiscreenpausesettings.h
new file mode 100644
index 0000000..9518687
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpausesettings.h
@@ -0,0 +1,81 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPauseSettings
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENPAUSESETTINGS_H
+#define GUISCREENPAUSESETTINGS_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+#include <camera/supercam.h>
+#include <cheats/cheatinputsystem.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+namespace Scrooby
+{
+ class Screen;
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenPauseSettings : public CGuiScreen,
+ public ICheatEnteredCallback
+{
+public:
+ CGuiScreenPauseSettings( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenPauseSettings();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+ virtual void OnCheatEntered( eCheatID cheatID, bool isEnabled );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ void UpdateCameraSelections();
+
+ CGuiMenu* m_pMenu;
+
+ enum eCameraSelectionMode
+ {
+ CAMERA_SELECTION_NOT_AVAILABLE = -1,
+
+ CAMERA_SELECTION_FOR_DRIVING,
+ CAMERA_SELECTION_FOR_WALKING,
+
+ NUM_CAMERA_SELECTION_MODES
+ };
+
+ eCameraSelectionMode m_currentCameraSelectionMode;
+
+ SuperCam::Type* m_cameraSelections[ NUM_CAMERA_SELECTION_MODES ];
+ int m_numCameraSelections[ NUM_CAMERA_SELECTION_MODES ];
+
+};
+
+#endif // GUISCREENPAUSEOPTIONS_H
diff --git a/game/code/presentation/gui/ingame/guiscreenpausesound.cpp b/game/code/presentation/gui/ingame/guiscreenpausesound.cpp
new file mode 100644
index 0000000..92ff581
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpausesound.cpp
@@ -0,0 +1,173 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPauseSound
+//
+// Description: Implementation of the CGuiScreenPauseSound class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenpausesound.h>
+
+#include <memory/srrmemory.h>
+
+#include <raddebug.hpp> // Foundation
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenPauseSound::CGuiScreenPauseSound
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPauseSound::CGuiScreenPauseSound
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+:
+ CGuiScreenSound( pScreen, pParent )
+{
+}
+
+
+//===========================================================================
+// CGuiScreenPauseSound::~CGuiScreenPauseSound
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPauseSound::~CGuiScreenPauseSound()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenPauseSound::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseSound::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_START:
+ {
+ // resume game
+ m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME );
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreenSound::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenPauseSound::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseSound::InitIntro()
+{
+ CGuiScreenSound::InitIntro();
+}
+
+
+//===========================================================================
+// CGuiScreenPauseSound::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseSound::InitRunning()
+{
+ CGuiScreenSound::InitRunning();
+}
+
+
+//===========================================================================
+// CGuiScreenPauseSound::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseSound::InitOutro()
+{
+ CGuiScreenSound::InitOutro();
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/ingame/guiscreenpausesound.h b/game/code/presentation/gui/ingame/guiscreenpausesound.h
new file mode 100644
index 0000000..8215dd2
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpausesound.h
@@ -0,0 +1,48 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPauseSound
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENPAUSESOUND_H
+#define GUISCREENPAUSESOUND_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreensound.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenPauseSound : public CGuiScreenSound
+{
+public:
+ CGuiScreenPauseSound( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenPauseSound();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+};
+
+#endif // GUISCREENPAUSESOUND_H
diff --git a/game/code/presentation/gui/ingame/guiscreenpausesunday.cpp b/game/code/presentation/gui/ingame/guiscreenpausesunday.cpp
new file mode 100644
index 0000000..a817094
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpausesunday.cpp
@@ -0,0 +1,331 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPauseSunday
+//
+// Description: Implementation of the CGuiScreenPauseSunday class.
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/11/20 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenpausesunday.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guiscreenmemorycard.h>
+
+#include <memory/srrmemory.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+
+#include <raddebug.hpp> // Foundation
+#include <group.h>
+#include <page.h>
+#include <screen.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+enum ePauseSundayMenuItem
+{
+ MENU_ITEM_PAUSE_SUNDAY_CONTINUE,
+ MENU_ITEM_MISSION_SELECT,
+ MENU_ITEM_PAUSE_SUNDAY_LEVEL_PROGRESS,
+ MENU_ITEM_PAUSE_SUNDAY_VIEW_CARDS,
+ MENU_ITEM_PAUSE_SUNDAY_OPTIONS,
+ MENU_ITEM_SAVE_GAME,
+ MENU_ITEM_PAUSE_SUNDAY_QUIT_GAME,
+#ifdef RAD_WIN32
+ MENU_ITEM_PAUSE_SUNDAY_EXIT_GAME,
+#endif
+
+ NUM_PAUSE_SUNDAY_MENU_ITEMS
+};
+
+static const char* PAUSE_SUNDAY_MENU_ITEMS[] =
+{
+ "Continue",
+ "MissionSelect",
+ "LevelProgress",
+ "ViewCards",
+ "Options",
+ "SaveGame",
+ "QuitGame"
+#ifdef RAD_WIN32
+ ,"ExitToSystem"
+#endif
+};
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenPauseSunday::CGuiScreenPauseSunday
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPauseSunday::CGuiScreenPauseSunday
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+:
+ CGuiScreenPause( pScreen, pParent, GUI_SCREEN_ID_PAUSE_SUNDAY )
+{
+MEMTRACK_PUSH_GROUP( "CGUIScreenPauseSunday" );
+ // Create a menu.
+ //
+ m_pMenu = new(GMA_LEVEL_HUD) CGuiMenu( this, NUM_PAUSE_SUNDAY_MENU_ITEMS );
+ rAssert( m_pMenu != NULL );
+
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "PauseSunday" );
+ rAssert( pPage != NULL );
+
+ // Add menu items
+ //
+ Scrooby::Group* menu = pPage->GetGroup( "Menu" );
+ rAssert( menu != NULL );
+ Scrooby::Text* pText = NULL;
+ for( int i = 0; i < NUM_PAUSE_SUNDAY_MENU_ITEMS; i++ )
+ {
+ pText = menu->GetText( PAUSE_SUNDAY_MENU_ITEMS[ i ] );
+ rAssert( pText );
+
+ m_pMenu->AddMenuItem( pText );
+ }
+
+#ifdef RAD_DEMO
+ // disable certain menu items for demos
+ //
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_SAVE_GAME, false );
+#endif
+MEMTRACK_POP_GROUP("CGUIScreenPauseSunday");
+}
+
+
+//===========================================================================
+// CGuiScreenPauseSunday::~CGuiScreenPauseSunday
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPauseSunday::~CGuiScreenPauseSunday()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenPauseSunday::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseSunday::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+/*
+ if( !GetMemoryCardManager()->IsMemcardInfoLoaded() )
+ {
+ if( message == GUI_MSG_CONTROLLER_SELECT ||
+ message == GUI_MSG_CONTROLLER_START )
+ {
+ // ignore all menu selection inputs and start input
+ // until memcard info is loaded
+ //
+ return;
+ }
+ }
+*/
+ switch( message )
+ {
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ switch( param1 )
+ {
+ case MENU_ITEM_PAUSE_SUNDAY_CONTINUE:
+ {
+ this->HandleResumeGame();
+
+ break;
+ }
+ case MENU_ITEM_MISSION_SELECT:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MISSION_SELECT );
+
+ break;
+ }
+ case MENU_ITEM_PAUSE_SUNDAY_LEVEL_PROGRESS:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_LEVEL_STATS );
+
+ break;
+ }
+ case MENU_ITEM_PAUSE_SUNDAY_VIEW_CARDS:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_VIEW_CARDS );
+
+ break;
+ }
+ case MENU_ITEM_PAUSE_SUNDAY_OPTIONS:
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_OPTIONS );
+
+ break;
+ }
+ case MENU_ITEM_SAVE_GAME:
+ {
+#ifdef RAD_XBOX
+ // Xbox TCR Requirement: always prompt user to select memory
+ // device before loading/saving
+ //
+ CGuiScreenLoadSave::s_forceGotoMemoryCardScreen = true;
+#endif
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_SAVE_GAME );
+
+ break;
+ }
+ case MENU_ITEM_PAUSE_SUNDAY_QUIT_GAME:
+ {
+ this->HandleQuitGame();
+
+ break;
+ }
+#ifdef RAD_WIN32
+ case MENU_ITEM_PAUSE_SUNDAY_EXIT_GAME:
+ {
+ this->HandleQuitToSystem();
+
+ break;
+ }
+#endif
+ default:
+ {
+ rAssertMsg( 0, "WARNING: Invalid case for switch statement!\n" );
+
+ break;
+ }
+ }
+
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreenPause::HandleMessage( message, param1, param2 );
+}
+
+//===========================================================================
+// CGuiScreenPauseSunday::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseSunday::InitIntro()
+{
+ if( GetCharacterSheetManager()->QueryHighestMission().mLevel > 0 ||
+ GetCharacterSheetManager()->QueryHighestMission().mMissionNumber > 0 ||
+ GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_MISSIONS ) )
+ {
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_MISSION_SELECT, true );
+ }
+ else
+ {
+ // this means the user's just started a new game and is
+ // currently on the level 1 tutorial mission; hence, cannot
+ // select any other missions
+ //
+ m_pMenu->SetMenuItemEnabled( MENU_ITEM_MISSION_SELECT, false );
+ }
+
+ CGuiScreenPause::InitIntro();
+}
+
+
+//===========================================================================
+// CGuiScreenPauseSunday::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseSunday::InitRunning()
+{
+ CGuiScreenPause::InitRunning();
+}
+
+
+//===========================================================================
+// CGuiScreenPauseSunday::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPauseSunday::InitOutro()
+{
+ CGuiScreenPause::InitOutro();
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
diff --git a/game/code/presentation/gui/ingame/guiscreenpausesunday.h b/game/code/presentation/gui/ingame/guiscreenpausesunday.h
new file mode 100644
index 0000000..38ef85b
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpausesunday.h
@@ -0,0 +1,50 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPauseSunday
+//
+// Description:
+//
+//
+// Authors: Darwin Chau
+// Tony Chu
+//
+// Revisions Date Author Revision
+// 2000/11/20 DChau Created
+// 2002/06/06 TChu Modified for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENPAUSESUNDAY_H
+#define GUISCREENPAUSESUNDAY_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenpause.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenPauseSunday : public CGuiScreenPause
+{
+public:
+ CGuiScreenPauseSunday( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenPauseSunday();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+};
+
+#endif // GUISCREENPAUSESUNDAY_H
diff --git a/game/code/presentation/gui/ingame/guiscreenphonebooth.cpp b/game/code/presentation/gui/ingame/guiscreenphonebooth.cpp
new file mode 100644
index 0000000..addef2c
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenphonebooth.cpp
@@ -0,0 +1,1104 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPhoneBooth
+//
+// Description: Implementation of the CGuiScreenPhoneBooth class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/21 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenphonebooth.h>
+#include <presentation/gui/ingame/guiscreenhud.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guitextbible.h>
+
+#include <ai/actionbuttonhandler.h>
+#include <camera/relativeanimatedcam.h>
+#include <camera/supercam.h>
+#include <camera/supercammanager.h>
+#include <cheats/cheatinputsystem.h>
+#include <events/eventmanager.h>
+#include <memory/srrmemory.h>
+#include <mission/gameplaymanager.h>
+#include <mission/missionmanager.h>
+#include <mission/rewards/rewardsmanager.h>
+#include <mission/rewards/reward.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <sound/soundmanager.h>
+#include <worldsim/character/charactermanager.h>
+#include <worldsim/character/character.h>
+#include <worldsim/coins/coinmanager.h>
+#include <worldsim/vehiclecentral.h>
+
+#include <screen.h>
+#include <page.h>
+#include <layer.h>
+#include <group.h>
+#include <sprite.h>
+#include <text.h>
+#include <pure3dobject.h>
+
+#include <p3d/anim/cameraanimation.hpp>
+
+#include <raddebug.hpp> // Foundation
+
+#include <string.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+#ifdef RAD_WIN32
+const float VEHICLE_CORRECTION_SCALE = 0.93f;
+const float VEHICLE_DAMAGED_CORRECTION_SCALE = 0.93f;
+const float HUSK_CORRECTION_SCALE = 1.4f;
+#else
+const float VEHICLE_CORRECTION_SCALE = 1.0f / 0.75f;
+const float VEHICLE_DAMAGED_CORRECTION_SCALE = 1.0f / 0.5f;
+const float HUSK_CORRECTION_SCALE = 1.0f / 0.5f;
+#endif
+
+const float VEHICLE_LOCKED_IMAGE_ALPHA = 0.5f;
+
+const tUID CHARACTER_VEHICLE_NAMES[] =
+{
+ tEntity::MakeUID( "apu_v" ),
+ tEntity::MakeUID( "bart_v" ),
+ tEntity::MakeUID( "comic_v" ),
+ tEntity::MakeUID( "cletu_v" ),
+ tEntity::MakeUID( "frink_v" ),
+ tEntity::MakeUID( "gramp_v" ),
+ tEntity::MakeUID( "homer_v" ),
+ tEntity::MakeUID( "lisa_v" ),
+ tEntity::MakeUID( "marge_v" ),
+ tEntity::MakeUID( "skinn_v" ),
+ tEntity::MakeUID( "smith_v" ),
+ tEntity::MakeUID( "snake_v" ),
+ tEntity::MakeUID( "wiggu_v" ),
+
+ 0 // dummy terminator
+};
+
+const int NUM_CHARACTER_VEHICLE_NAMES =
+ sizeof( CHARACTER_VEHICLE_NAMES ) / sizeof( CHARACTER_VEHICLE_NAMES[ 0 ] ) - 1;
+
+static int GetVehicleIndex( const char* vehicleName )
+{
+ int vehicleIndex = -1;
+
+ tUID vehicleNameUID = tEntity::MakeUID( vehicleName );
+
+ for( int i = 0; i < NUM_CHARACTER_VEHICLE_NAMES; i++ )
+ {
+ if( CHARACTER_VEHICLE_NAMES[ i ] == vehicleNameUID )
+ {
+ // found it!
+ //
+ vehicleIndex = i;
+
+ // stop searching
+ //
+ break;
+ }
+ }
+
+ return vehicleIndex;
+}
+
+#ifdef SRR2_OVERRIDE_CAR_SELECTION
+ const char* OVERRIDE_VEHICLE_NAMES[] =
+ {
+ "snake_v",
+ "bookb_v",
+ "marge_v",
+ "carhom_v",
+ "krust_v",
+ "bbman_v",
+ "elect_v",
+ "famil_v",
+ "bart_v",
+ "scorp_v",
+ "honor_v",
+ "hbike_v",
+ "frink_v",
+ "comic_v",
+ "lisa_v",
+ "smith_v",
+ "mrplo_v",
+ "fone_v",
+ "cletu_v",
+ "apu_v",
+ "plowk_v",
+ "wiggu_v",
+ "otto_v",
+ "moe_v",
+ "skinn_v",
+ "homer_v",
+ "zombi_v",
+ "burns_v",
+ "willi_v",
+ "gramp_v",
+ "gramR_v",
+
+ "atv_v",
+ "knigh_v",
+ "mono_v",
+ "oblit_v",
+ "hype_v",
+ "dune_v",
+ "rocke_v",
+
+ "cArmor",
+ "cCellA",
+ "cCellB",
+ "cCellC",
+ "cCellD",
+ "cSedan",
+ "cCola",
+ "cCube",
+ "cCurator",
+ "cDonut",
+ "cDuff",
+ "cBlbart",
+ "cHears",
+ "cKlimo",
+ "cLimo",
+ "cMilk",
+ "cNerd",
+ "cNonup",
+ "cPolice",
+ "cVan",
+
+ //"huskA",
+ "compactA",
+ "minivanA",
+ "pickupA",
+ "sedanA",
+ "sedanB",
+ "sportsA",
+ "sportsB",
+ "wagonA",
+ "SUVA",
+ "taxiA",
+ "coffin",
+ "ship",
+ "hallo",
+ "witchcar",
+
+ "ambul",
+ "burnsarm",
+ "fishtruc",
+ "garbage",
+ "icecream",
+ "IStruck",
+ "nuctruck",
+ "pizza",
+ "schoolbu",
+ "votetruc",
+ "glastruc",
+ "cFire_v",
+ "cBone",
+ "redbrick",
+
+ "" // dummy terminator
+ };
+
+ const unsigned int NUM_OVERRIDE_VEHICLES =
+ sizeof( OVERRIDE_VEHICLE_NAMES ) / sizeof( OVERRIDE_VEHICLE_NAMES[ 0 ] ) - 1;
+
+ const char* VEHICLES_DIR = "art\\cars\\";
+
+ int CGuiScreenPhoneBooth::s_currentDebugVehicleSelection = 0;
+ unsigned CGuiScreenPhoneBooth::s_currentTeleportSelection = 0;
+#endif
+
+//===========================================================================
+// CGuiScreenPhoneBooth::
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenPhoneBooth::CGuiScreenPhoneBooth
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPhoneBooth::CGuiScreenPhoneBooth
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: IGuiScreenRewards( pScreen,
+ pScreen->GetPage( "PhoneBooth" ),
+ pParent,
+ GUI_SCREEN_ID_PHONE_BOOTH ),
+ m_damagedInfo( NULL ),
+ m_vehicleDamaged( NULL ),
+ m_repairCostInfo( NULL ),
+ m_vehicleRepairCost( NULL )
+{
+MEMTRACK_PUSH_GROUP( "CGUIScreenPhoneBooth" );
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "PhoneBooth" );
+ rAssert( pPage != NULL );
+
+#ifdef RAD_WIN32
+ m_leftArrow = pPage->GetGroup( "Arrows" )->GetSprite( "LeftArrow" );
+ m_rightArrow = pPage->GetGroup( "Arrows" )->GetSprite( "RightArrow" );
+ m_leftArrow->ScaleAboutCenter( 1.3f );
+ m_rightArrow->ScaleAboutCenter( 1.3f );
+#endif
+
+ // get vehicle damaged info
+ //
+ m_damagedInfo = pPage->GetGroup( "DamagedInfo" );
+ rAssert( m_damagedInfo != NULL );
+ m_vehicleDamaged = m_damagedInfo->GetText( "VehicleDamaged_Value" );
+
+ m_repairCostInfo = m_damagedInfo->GetGroup( "RepairCostInfo" );
+ rAssert( m_repairCostInfo != NULL );
+ m_vehicleRepairCost = m_repairCostInfo->GetText( "CostToFix_Value" );
+
+ // always show vehicle stats
+ //
+ rAssert( m_statsOverlay != NULL );
+ m_statsOverlay->SetVisible( true );
+
+#ifdef PAL
+ // re-position damaged info text
+ //
+ const int DAMAGED_INFO_TRANSLATE_X = +60;
+
+ m_vehicleDamaged->ResetTransformation();
+ m_vehicleDamaged->Translate( DAMAGED_INFO_TRANSLATE_X, 0 );
+
+ m_vehicleRepairCost->ResetTransformation();
+ m_vehicleRepairCost->Translate( DAMAGED_INFO_TRANSLATE_X, 0 );
+
+ Scrooby::Text* repairCostCoins = m_repairCostInfo->GetText( "Coins" );
+ if( repairCostCoins != NULL )
+ {
+ repairCostCoins->ResetTransformation();
+ repairCostCoins->Translate( DAMAGED_INFO_TRANSLATE_X, 0 );
+#ifdef RAD_WIN32
+ repairCostCoins->Translate( 70, 0 );
+ repairCostCoins->ScaleAboutCenter( 0.5f );
+#endif
+ }
+
+ // move stats over to the left a bit to avoid safe zone
+ // boundary clipping
+ //
+ m_statsOverlay->ResetTransformation();
+ m_statsOverlay->Translate( -15, 0 );
+
+ // scale-down vehicle name a bit
+ //
+ m_previewName->ResetTransformation();
+ m_previewName->ScaleAboutCenter( 0.9f );
+#endif // PAL
+
+ // apply correction scale to spotlight
+ //
+ Scrooby::Sprite* spotLight = pPage->GetSprite( "Spotlight" );
+ if( spotLight != NULL )
+ {
+ spotLight->ResetTransformation();
+ spotLight->ScaleAboutCenter( 4.0f );
+ }
+
+ // apply correction scale to spotlight overlay
+ //
+ spotLight = pPage->GetSprite( "Overlay" );
+ if( spotLight != NULL )
+ {
+ spotLight->ResetTransformation();
+ spotLight->ScaleAboutCenter( 4.0f );
+ }
+
+ rAssert( m_pRewardsMenu != NULL );
+ m_pRewardsMenu->SetHighlightColour( false, tColour( 255, 255, 255 ) );
+ m_pRewardsMenu->Reset();
+
+ this->AutoScaleFrame( pPage );
+
+#ifdef SRR2_OVERRIDE_CAR_SELECTION
+ pPage = m_pScroobyScreen->GetPage( "CarSelect" );
+ if( pPage != NULL )
+ {
+ m_carSelectOverlay = pPage->GetLayerByIndex( 0 );
+ rAssert( m_carSelectOverlay );
+ }
+
+ // Create a menu.
+ //
+ m_pMenu = new CGuiMenu( this );
+ rAssert( m_pMenu != NULL );
+
+ // Add menu items
+ //
+ m_pMenu->AddMenuItem( pPage->GetText( "Car" ),
+ pPage->GetText( "Car_Value" ) );
+
+ // clamp number of vehicle selections w/ only what's available
+ //
+ m_pMenu->SetSelectionValueCount( 0, NUM_OVERRIDE_VEHICLES );
+
+ // wrap vehicle names
+ //
+ Scrooby::Text* vehicleNames = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( 0 )->GetItemValue() );
+ rAssert( vehicleNames != NULL );
+ vehicleNames->SetTextMode( Scrooby::TEXT_WRAP );
+
+ m_menuTeleport = false;
+#endif
+MEMTRACK_POP_GROUP("CGUIScreenPhoneBooth");
+}
+
+//===========================================================================
+// CGuiScreenPhoneBooth::~CGuiScreenPhoneBooth
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPhoneBooth::~CGuiScreenPhoneBooth()
+{
+#ifdef SRR2_OVERRIDE_CAR_SELECTION
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+#endif
+}
+
+//===========================================================================
+// CGuiScreenPhoneBooth::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPhoneBooth::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_isLoading )
+ {
+ if( message == GUI_MSG_CONTROLLER_SELECT ||
+ message == GUI_MSG_CONTROLLER_BACK )
+ {
+ // don't allow user to select or back out of screen
+ // during loading
+ //
+ return;
+ }
+ }
+
+ rAssert( m_pRewardsMenu != NULL );
+ if( m_pRewardsMenu->HasSelectionBeenMade() || m_isLoadingReward )
+ {
+ if( this->IsControllerMessage( message ) )
+ {
+ // selection has already been made or reward is currently loading,
+ // ignore all controller inputs
+ //
+ return;
+ }
+ }
+
+#ifdef SRR2_OVERRIDE_CAR_SELECTION
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ if( message == GUI_MSG_CONTROLLER_L1 || message == GUI_MSG_CONTROLLER_R1 )
+ {
+#ifdef FINAL
+ if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_VEHICLES ) &&
+ GetCharacterSheetManager()->QueryPercentGameCompleted() > 99.999f )
+#endif
+ {
+ rAssert( m_carSelectOverlay != NULL );
+
+ // toggle visibility of car selection overlay
+ //
+ m_carSelectOverlay->SetVisible( !m_carSelectOverlay->IsVisible() );
+
+ if( m_carSelectOverlay->IsVisible() )
+ {
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, true );
+
+// Teleportation menu disabled in final build
+#ifndef FINAL
+ m_menuTeleport = (message == GUI_MSG_CONTROLLER_L1);
+#endif
+ Scrooby::Text* menuLabel = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( 0 )->GetItem() );
+ rAssert( menuLabel != NULL );
+
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+ if( !m_menuTeleport )
+ {
+ menuLabel->SetString( 0, "Vehicle:" );
+ m_pMenu->SetSelectionValue( 0, s_currentDebugVehicleSelection );
+ }
+ else
+ {
+ menuLabel->SetString( 0, "Teleport:" );
+ m_pMenu->SetSelectionValue( 0, s_currentTeleportSelection );
+ }
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+ }
+ else
+ {
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT,
+ this->GetCurrentPreviewObject()->isUnlocked );
+ }
+ }
+ }
+ }
+
+ if( m_carSelectOverlay->IsVisible() )
+ {
+ this->HandleMessageForCar( message, param1, param2 );
+ }
+ else
+#endif
+ {
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ const PreviewObject* currentPreviewObject = this->GetCurrentPreviewObject();
+
+ if( currentPreviewObject->isUnlocked )
+ {
+ // check if selecting a damaged out vehicle; if so, reduce current bank
+ // value by repair cost amount
+ //
+ int carIndex = GetCharacterSheetManager()->GetCarIndex( currentPreviewObject->name );
+ if( carIndex >= 0 )
+ {
+ bool isVehicleDamagedOut = ( GetCharacterSheetManager()->GetCarDamageState( carIndex ) == eHusk );
+ if( isVehicleDamagedOut )
+ {
+ int repairCost = currentPreviewObject->pReward->GetRepairCost();
+
+ // TC: *** Joe says to always allow car repair, even if user
+ // doesn't quite have enough money
+/*
+ if( GetCoinManager()->GetBankValue() < repairCost )
+ {
+ // doh... not enough money in the bank to repair damaged vehicle
+ //
+ return;
+ }
+*/
+ GetCoinManager()->AdjustBankValue( -repairCost );
+
+ // trigger HUD event
+ //
+ GetEventManager()->TriggerEvent( EVENT_LOST_COINS );
+
+ //Chuck: Adding Record that the car has full hitpoints restored
+ GetCharacterSheetManager()->UpdateCarHealth(carIndex,1.0f);
+ }
+ }
+
+ Character* pWalkerCharacter = GetCharacterManager()->GetCharacter( 0 );
+ rWarning( pWalkerCharacter != NULL );
+
+ GetEventManager()->TriggerEvent( EVENT_PHONE_BOOTH_RIDE_REQUEST, reinterpret_cast<void*>( pWalkerCharacter ) );
+
+ bool isBonusVehicle = (m_previewVehicles[ m_currentPreviewVehicle ].pReward->GetQuestType() == Reward::eBonusMission);
+ if( isBonusVehicle )
+ {
+ Character* pDriverCharacter = NULL;
+
+ Vehicle* pCurrentVehicle = GetGameplayManager()->GetCurrentVehicle();
+ rAssert( pCurrentVehicle != NULL );
+
+ bool isNewVehicle = ( strcmp( pCurrentVehicle->GetName(), currentPreviewObject->name ) != 0 );
+ if( !isNewVehicle )
+ {
+ //
+ // Re-requesting old vehicle. Send some dialogue if there's a driver.
+ //
+ pDriverCharacter = pCurrentVehicle->GetDriver();
+ if( pDriverCharacter != NULL )
+ {
+ GetEventManager()->TriggerEvent( EVENT_PHONE_BOOTH_OLD_VEHICLE_RESELECTED, pDriverCharacter );
+ }
+ }
+ }
+ }
+ else
+ {
+ GetEventManager()->TriggerEvent( EVENT_FE_LOCKED_OUT );
+ return;
+ }
+
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ // load selected reward item
+ //
+ this->LoadSelectedReward();
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_LEFT:
+ {
+ m_currentPreviewVehicle = (m_currentPreviewVehicle - 1 + m_numPreviewVehicles) % m_numPreviewVehicles;
+
+ this->On3DModelSelectionChange( &m_previewVehicles[ m_currentPreviewVehicle ] );
+ this->UpdateDamagedInfo();
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_RIGHT:
+ {
+ m_currentPreviewVehicle = (m_currentPreviewVehicle + 1 + m_numPreviewVehicles) % m_numPreviewVehicles;
+
+ this->On3DModelSelectionChange( &m_previewVehicles[ m_currentPreviewVehicle ] );
+ this->UpdateDamagedInfo();
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ IGuiScreenRewards::HandleMessage( message, param1, param2 );
+ }
+}
+
+#ifdef RAD_WIN32
+//===========================================================================
+// CGuiScreenPhoneBooth::CheckCursorAgainstHotspots
+//===========================================================================
+// Description: Checks cursor position against its list of hotspots.
+//
+// Constraints: None.
+//
+// Parameters: float x - The x position of cursor in P3D coordinates.
+// float y - The y position of cursor in P3D coordinates.
+//
+// Return: N/A.
+//
+//===========================================================================
+eFEHotspotType CGuiScreenPhoneBooth::CheckCursorAgainstHotspots( float x, float y )
+{
+ eFEHotspotType hotSpotType = CGuiScreen::CheckCursorAgainstHotspots( x, y );
+ if( hotSpotType == HOTSPOT_NONE )
+ {
+ if( m_leftArrow )
+ {
+ if( m_leftArrow->IsPointInBoundingRect( x, y ) )
+ {
+ hotSpotType = HOTSPOT_ARROWLEFT;
+ }
+ }
+ if( m_rightArrow )
+ {
+ if( m_rightArrow->IsPointInBoundingRect( x, y ) )
+ {
+ hotSpotType = HOTSPOT_ARROWRIGHT;
+ }
+ }
+
+ }
+ return hotSpotType;
+}
+#endif
+
+//===========================================================================
+// CGuiScreenPhoneBooth::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPhoneBooth::InitIntro()
+{
+ IGuiScreenRewards::InitIntro();
+
+ // hide lock by default
+ //
+ rAssert( m_lockedOverlay != NULL );
+ m_lockedOverlay->SetVisible( false );
+
+ // set level default vehicle as default garage vehicle selection
+ //
+ Reward* pDefaultCar = GetRewardsManager()->GetReward( GetGameplayManager()->GetCurrentLevelIndex(),
+ Reward::eDefaultCar );
+ if( pDefaultCar != NULL )
+ {
+ for( int i = 0; i < m_numPreviewVehicles; i++ )
+ {
+ if( m_previewVehicles[ i ].pReward == pDefaultCar )
+ {
+ m_currentPreviewVehicle = i;
+
+ break;
+ }
+ }
+ }
+
+ this->UpdateDamagedInfo();
+
+ // load current 3D model object
+ //
+ this->On3DModelSelectionChange( this->GetCurrentPreviewObject() );
+
+ // notify sound manager that game is paused
+ //
+ GetSoundManager()->OnStoreScreenStart();
+}
+
+//===========================================================================
+// CGuiScreenPhoneBooth::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPhoneBooth::InitRunning()
+{
+ IGuiScreenRewards::InitRunning();
+
+ CGuiScreenHud::UpdateNumCoinsDisplay( GetCoinManager()->GetBankValue() );
+}
+
+//===========================================================================
+// CGuiScreenPhoneBooth::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPhoneBooth::InitOutro()
+{
+ if( m_isLoadingReward )
+ {
+ RelativeAnimatedCam::AllowSkipping( true );
+ RelativeAnimatedCam::Reset();
+ RelativeAnimatedCam::SetCamera( "phonecameraShape" );
+ RelativeAnimatedCam::SetMulticontroller( "phonecamera" );
+ tCameraAnimationController* camController = p3d::find< tCameraAnimationController >( "CAM_phonecameraShape" );
+
+ SuperCam* sc = GetSuperCamManager()->GetSCC( 0 )->GetSuperCam( SuperCam::RELATIVE_ANIMATED_CAM );
+ RelativeAnimatedCam* rac = dynamic_cast< RelativeAnimatedCam* >( sc );
+ rac->SetCameraAnimationController( camController );
+ GetSuperCamManager()->GetSCC( 0 )->SelectSuperCam( SuperCam::RELATIVE_ANIMATED_CAM );
+ RelativeAnimatedCam::CheckPendingCameraSwitch();
+
+ GetMissionManager()->Update( 16 );
+ GetSuperCamManager()->GetSCC( 0 )->NoTransition();
+ GetSuperCamManager()->Update( 16, true );
+ }
+
+ CGuiScreenHud::UpdateNumCoinsDisplay( 0, false );
+
+ IGuiScreenRewards::InitOutro();
+
+ // notify sound manager that game is un-paused
+ //
+ GetSoundManager()->OnStoreScreenEnd();
+}
+
+void
+CGuiScreenPhoneBooth::On3DModelLoaded( const PreviewObject* previewObject )
+{
+ p3d::pddi->DrawSync();
+
+ rAssert( m_previewImage != NULL );
+ m_previewImage->SetVisible( true );
+ m_previewImage->ResetTransformation();
+
+ // apply alpha to locked vehicles
+ //
+ m_previewImage->SetAlpha( previewObject->isUnlocked ? 1.0f : VEHICLE_LOCKED_IMAGE_ALPHA );
+
+ CarDamageStateEnum damageState = eNull;
+ if( previewObject->isUnlocked )
+ {
+ int carIndex = GetCharacterSheetManager()->GetCarIndex( previewObject->name );
+ if( carIndex >= 0 )
+ {
+ damageState = GetCharacterSheetManager()->GetCarDamageState( carIndex );
+ }
+ }
+
+ if( damageState == eHusk )
+ {
+ m_previewImage->ScaleAboutCenter( HUSK_CORRECTION_SCALE );
+
+ // show generic husk
+ //
+ m_previewImage->SetRawSprite( NULL, true );
+ }
+ else
+ {
+ // search for 2D image(s) in inventory
+ //
+ char name[ 16 ];
+
+ if( damageState == eDamaged )
+ {
+ // show damaged vehicle
+ //
+#ifdef LOAD_DAMAGED_VEHICLE_IMAGES
+ sprintf( name, "%sD.png", previewObject->nameModel );
+ m_previewImage->ScaleAboutCenter( VEHICLE_DAMAGED_CORRECTION_SCALE );
+#else
+ sprintf( name, "%s.png", previewObject->nameModel );
+ m_previewImage->ScaleAboutCenter( VEHICLE_CORRECTION_SCALE );
+#endif
+ }
+ else
+ {
+ // show normal vehicle
+ //
+ sprintf( name, "%s.png", previewObject->nameModel );
+
+ m_previewImage->ScaleAboutCenter( VEHICLE_CORRECTION_SCALE );
+ }
+
+ tSprite* pSprite = p3d::find<tSprite>( name );
+ if( pSprite != NULL )
+ {
+ m_previewImage->SetRawSprite( pSprite, true );
+ }
+ else
+ {
+ rAssertMsg( false, "*** Can't find 2D vehicle image!!" );
+ }
+ }
+}
+
+const PreviewObject*
+CGuiScreenPhoneBooth::GetCurrentPreviewObject() const
+{
+ const PreviewObject* previewObject = NULL;
+
+ if( m_numPreviewVehicles > 0 )
+ {
+ previewObject = &m_previewVehicles[ m_currentPreviewVehicle ];
+ }
+
+ return previewObject;
+}
+
+void
+CGuiScreenPhoneBooth::InitMenu()
+{
+ const int highestLevelPlayed = GetCharacterSheetManager()->QueryHighestMission().mLevel;
+
+ for( int i = 0; i <= highestLevelPlayed; i++ )
+ {
+ Reward* pReward = NULL;
+
+ for( int j = (Reward::eBlank + 1); j < Reward::NUM_QUESTS; j++ )
+ {
+ pReward = GetRewardsManager()->GetReward( i, (Reward::eQuestType)j );
+ if( pReward != NULL &&
+ pReward->GetRewardType() == Reward::ALT_PLAYERCAR )
+ {
+ rAssert( m_numPreviewVehicles < MAX_NUM_PREVIEW_VEHICLES - 1 );
+ m_numPreviewVehicles = this->InsertPreviewObject( m_previewVehicles,
+ m_numPreviewVehicles,
+ pReward,
+ true );
+ }
+ }
+
+ for( pReward = GetRewardsManager()->FindFirstMerchandise( i, Merchandise::SELLER_SIMPSON );
+ pReward != NULL;
+ pReward = GetRewardsManager()->FindNextMerchandise( i, Merchandise::SELLER_SIMPSON ) )
+ {
+ rAssert( m_numPreviewVehicles < MAX_NUM_PREVIEW_VEHICLES - 1 );
+ m_numPreviewVehicles = this->InsertPreviewObject( m_previewVehicles,
+ m_numPreviewVehicles,
+ pReward,
+ true );
+ }
+
+ for( pReward = GetRewardsManager()->FindFirstMerchandise( i, Merchandise::SELLER_GIL );
+ pReward != NULL;
+ pReward = GetRewardsManager()->FindNextMerchandise( i, Merchandise::SELLER_GIL ) )
+ {
+ rAssert( m_numPreviewVehicles < MAX_NUM_PREVIEW_VEHICLES - 1 );
+ m_numPreviewVehicles = this->InsertPreviewObject( m_previewVehicles,
+ m_numPreviewVehicles,
+ pReward,
+ true );
+ }
+ }
+
+ rAssertMsg( m_numPreviewVehicles > 0, "No vehicle selections!" );
+
+ // apply cheats, if enabled
+ //
+ if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_VEHICLES ) )
+ {
+ for( int i = 0; i < m_numPreviewVehicles; i++ )
+ {
+ m_previewVehicles[ i ].isUnlocked = true;
+ }
+ }
+}
+
+void CGuiScreenPhoneBooth::OnUpdate( unsigned int elapsedTime )
+{
+ IGuiScreenRewards::OnUpdate( elapsedTime );
+}
+
+void
+CGuiScreenPhoneBooth::LoadSelectedReward()
+{
+ // unload 3D model first before loading reward
+ //
+ this->Unload3DModel();
+
+ m_isLoading = true; // set loading flag
+ m_isLoadingReward = true; // we're loading the selected reward
+
+ const PreviewObject* currentPreviewObject = this->GetCurrentPreviewObject();
+
+ VehicleCentral::DriverInit driverInit = VehicleCentral::ALLOW_DRIVER;
+ ActionButton::SummonVehiclePhone::LoadVehicle( currentPreviewObject->name,
+ currentPreviewObject->filename,
+ driverInit );
+}
+
+void
+CGuiScreenPhoneBooth::UpdateDamagedInfo()
+{
+ if( this->GetCurrentPreviewObject()->isUnlocked )
+ {
+ m_damagedInfo->SetVisible( true );
+
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ Reward* pReward = this->GetCurrentPreviewObject()->pReward;
+ rAssert( pReward != NULL );
+
+ char buffer[ 16 ];
+
+ int carIndex = GetCharacterSheetManager()->GetCarIndex( pReward->GetName() );
+ if( carIndex != -1 )
+ {
+ float damagedAmount = 1.0f - GetCharacterSheetManager()->GetCarHealth( carIndex );
+ if( damagedAmount >= 0.0f && damagedAmount <= 1.0f )
+ {
+ sprintf( buffer, "%.0f %%", damagedAmount * 100 );
+ rAssert( m_vehicleDamaged != NULL );
+ m_vehicleDamaged->SetString( 0, buffer );
+ }
+ else
+ {
+ rAssertMsg( false, "Why is the damage amount not between 0 and 1??" );
+ }
+
+ rAssert( m_repairCostInfo != NULL );
+ m_repairCostInfo->SetVisible( damagedAmount == 1.0f );
+
+ sprintf( buffer, "%d", pReward->GetRepairCost() );
+ rAssert( m_vehicleRepairCost != NULL );
+ m_vehicleRepairCost->SetString( 0, buffer );
+ }
+ else
+ {
+ rAssertMsg( false, "Why is the car index -1??" );
+ }
+
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+ }
+ else
+ {
+ m_damagedInfo->SetVisible( false );
+ }
+}
+
+#ifdef SRR2_OVERRIDE_CAR_SELECTION
+
+void
+CGuiScreenPhoneBooth::HandleMessageForCar( eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2 )
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ rAssert( param1 == 0 );
+
+ if( m_menuTeleport )
+ {
+ if( s_currentTeleportSelection >= 0 &&
+ s_currentTeleportSelection < CharacterManager::GetNumTeleportDests() )
+ {
+ CharacterManager::Teleport(s_currentTeleportSelection );
+
+ m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN );
+ }
+ else
+ {
+ rAssertMsg( 0, "WARNING: *** Invalid teleport destination selection!" );
+ }
+ }
+ else
+ {
+ if( s_currentDebugVehicleSelection >= 0 &&
+ s_currentDebugVehicleSelection < static_cast<int>( NUM_OVERRIDE_VEHICLES ) )
+ {
+ char vehicleFileName[ 32 ];
+ sprintf( vehicleFileName, "%s%s.p3d",
+ VEHICLES_DIR,
+ OVERRIDE_VEHICLE_NAMES[ s_currentDebugVehicleSelection ] );
+
+ ActionButton::SummonVehiclePhone::CarSelectionInfo* pInfo =
+ ActionButton::SummonVehiclePhone::GetDebugCarSelectInfo();
+
+ rAssert( pInfo );
+ pInfo->AddDebugVehicleSelectionInfo( vehicleFileName,
+ OVERRIDE_VEHICLE_NAMES[ s_currentDebugVehicleSelection ],
+ "" );
+
+ this->Unload3DModel(); // unload 3D model first
+
+ ActionButton::SummonVehiclePhone::LoadDebugVehicle();
+
+ m_state = GUI_WINDOW_STATE_IDLE;
+ }
+ else
+ {
+ rAssertMsg( 0, "WARNING: *** Invalid vehicle selection!" );
+ }
+ }
+
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_VALUE_CHANGED:
+ {
+ rAssert( param1 == 0 );
+
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ Scrooby::Text* vehicleNames = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( 0 )->GetItemValue() );
+ rAssert( vehicleNames != NULL );
+
+ if( m_menuTeleport )
+ {
+ s_currentTeleportSelection = static_cast<int>( param2 );
+
+ if( s_currentTeleportSelection == 99 )
+ {
+ s_currentTeleportSelection = CharacterManager::GetNumTeleportDests() - 1;
+ m_pMenu->SetSelectionValue( 0, s_currentTeleportSelection);
+ }
+
+ if( s_currentTeleportSelection >= CharacterManager::GetNumTeleportDests() )
+ {
+ s_currentTeleportSelection = 0;
+ m_pMenu->SetSelectionValue( 0, s_currentTeleportSelection);
+ }
+
+ vehicleNames->SetString( s_currentTeleportSelection, CharacterManager::GetTeleportDest(s_currentTeleportSelection) );
+ }
+ else
+ {
+ s_currentDebugVehicleSelection = static_cast<int>( param2 );
+
+ if( param2 < NUM_OVERRIDE_VEHICLES )
+ {
+ char textBibleEntry[ 16 ];
+ strcpy( textBibleEntry, OVERRIDE_VEHICLE_NAMES[ s_currentDebugVehicleSelection ] );
+ UnicodeChar* textBibleString = GetTextBibleString( strupr( textBibleEntry ) );
+ UnicodeString unicodeString;
+ if( textBibleString != NULL )
+ {
+ unicodeString.ReadUnicode( textBibleString );
+ }
+ else
+ {
+ unicodeString.ReadAscii( OVERRIDE_VEHICLE_NAMES[ s_currentDebugVehicleSelection ] );
+ }
+
+ vehicleNames->SetString( s_currentDebugVehicleSelection, unicodeString );
+ }
+ }
+
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+ }
+
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+#endif
+
diff --git a/game/code/presentation/gui/ingame/guiscreenphonebooth.h b/game/code/presentation/gui/ingame/guiscreenphonebooth.h
new file mode 100644
index 0000000..c37fd57
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenphonebooth.h
@@ -0,0 +1,94 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPhoneBooth
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/21 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENPHONEBOOTH_H
+#define GUISCREENPHONEBOOTH_H
+
+#ifndef RAD_E3
+ // enable car selection overlay for selecting any car
+ //
+ #define SRR2_OVERRIDE_CAR_SELECTION
+#endif
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenrewards.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class CGuiMenu;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenPhoneBooth : public IGuiScreenRewards
+{
+public:
+ CGuiScreenPhoneBooth( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenPhoneBooth();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+#ifdef RAD_WIN32
+ virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y );
+#endif
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+ virtual void On3DModelLoaded( const PreviewObject* previewObject );
+ virtual const PreviewObject* GetCurrentPreviewObject() const;
+ virtual void InitMenu();
+
+private:
+ virtual void OnUpdate( unsigned int elapsedTime );
+ void LoadSelectedReward();
+ void UpdateDamagedInfo();
+
+ Scrooby::Group* m_damagedInfo;
+ Scrooby::Text* m_vehicleDamaged;
+ Scrooby::Group* m_repairCostInfo;
+ Scrooby::Text* m_vehicleRepairCost;
+
+#ifdef RAD_WIN32
+ Scrooby::Sprite* m_leftArrow;
+ Scrooby::Sprite* m_rightArrow;
+#endif
+
+#ifdef SRR2_OVERRIDE_CAR_SELECTION
+ void HandleMessageForCar( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ CGuiMenu* m_pMenu;
+ Scrooby::Layer* m_carSelectOverlay;
+ bool m_menuTeleport;
+
+ static int s_currentDebugVehicleSelection;
+ static unsigned s_currentTeleportSelection;
+#endif
+
+};
+
+#endif // GUISCREENPHONEBOOTH_H
diff --git a/game/code/presentation/gui/ingame/guiscreenpurchaserewards.cpp b/game/code/presentation/gui/ingame/guiscreenpurchaserewards.cpp
new file mode 100644
index 0000000..ccec82a
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpurchaserewards.cpp
@@ -0,0 +1,1078 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPurchaseRewards
+//
+// Description: Implementation of the CGuiScreenPurchaseRewards class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/21 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenpurchaserewards.h>
+#include <presentation/gui/ingame/guimanageringame.h>
+#include <presentation/gui/ingame/guiscreenhud.h>
+#include <presentation/gui/ingame/hudevents/hudcoincollected.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guitextbible.h>
+
+#include <ai/actionbuttonhandler.h>
+#include <cheats/cheatinputsystem.h>
+#include <mission/gameplaymanager.h>
+#include <mission/rewards/rewardsmanager.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <mission/rewards/reward.h>
+#include <sound/soundmanager.h>
+
+#include <worldsim/character/charactermanager.h>
+#include <worldsim/character/character.h>
+#include <worldsim/coins/coinmanager.h>
+
+#include <p3d/anim/animate.hpp>
+#include <p3d/anim/poseanimation.hpp>
+#include <p3d/anim/skeleton.hpp>
+#include <raddebug.hpp> // Foundation
+
+// Scrooby Header Files
+//
+#include <screen.h>
+#include <page.h>
+#include <group.h>
+#include <sprite.h>
+#include <pure3dobject.h>
+
+#include <string.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const float PREVIEW_CHARACTER_SCALE = 2.0f;
+const float PREVIEW_PEDESTAL_SCALE_FOR_SKINS = 0.75f;
+
+const float PREVIEW_VEHICLE_RADIUS = 3.6f;
+
+const tUID CHARACTER_NAME_HOMER = tEntity::MakeUID( "homer" );
+const tUID CHARACTER_NAME_BART = tEntity::MakeUID( "bart" );
+const tUID CHARACTER_NAME_LISA = tEntity::MakeUID( "lisa" );
+const tUID CHARACTER_NAME_MARGE = tEntity::MakeUID( "marge" );
+const tUID CHARACTER_NAME_APU = tEntity::MakeUID( "apu" );
+
+const char* PURCHASE_REWARDS_INVENTORY_SECTION = "FE_PurchaseRewardsScreen";
+const char* PURCHASE_REWARDS_BGD = "art\\frontend\\scrooby\\resource\\pure3d\\rewardbg.p3d";
+const char* PURCHASE_REWARDS_BGD_DRAWABLE = "Pedestal_Scenegraph";
+const char* PURCHASE_REWARDS_BGD_CAMERA = "Pedestal_Camera";
+const char* PURCHASE_REWARDS_BGD_MULTICONTROLLER = "Pedestal_MasterController";
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenPurchaseRewards::CGuiScreenPurchaseRewards
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPurchaseRewards::CGuiScreenPurchaseRewards
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: IGuiScreenRewards( pScreen,
+ pScreen->GetPage( "Rewards" ),
+ pParent,
+ GUI_SCREEN_ID_PURCHASE_REWARDS ),
+ m_currentType( Merchandise::INVALID_SELLER_TYPE ),
+ m_isPurchasingReward( false ),
+ m_elapsedCoinDecrementTotalTime( 0 ),
+ m_elapsedCoinDecrementTime( 0 ),
+ m_bankValueBeforePurchase( 0 ),
+ m_purchaseLabel( NULL ),
+ m_skinMultiController( NULL ),
+ m_skinAnimController( NULL )
+{
+ this->SetFadingEnabled( false );
+ this->SetIrisWipeEnabled( true );
+
+ // Retrieve the Scrooby drawing elements (from Rewards page).
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Rewards" );
+ rAssert( pPage != NULL );
+
+#ifdef RAD_WIN32
+ m_leftArrow = pPage->GetGroup( "Arrows" )->GetSprite( "LeftArrow" );
+ m_rightArrow = pPage->GetGroup( "Arrows" )->GetSprite( "RightArrow" );
+ m_leftArrow->ScaleAboutCenter( 1.3f );
+ m_rightArrow->ScaleAboutCenter( 1.3f );
+#endif
+
+ // Retrieve the Scrooby drawing elements (from Coins page).
+ //
+ pPage = m_pScroobyScreen->GetPage( "Coins" );
+ rAssert( pPage != NULL );
+ CGuiScreenHud::SetNumCoinsDisplay( pPage->GetSprite( "NumCoins" ) );
+
+// m_numCoins.SetScroobyText( pPage->GetGroup( "NumCoins" ), "NumCoins" );
+
+ // get purchase button label
+ //
+ rAssert( m_buttonIcons[ BUTTON_ICON_ACCEPT ] != NULL );
+ m_purchaseLabel = m_buttonIcons[ BUTTON_ICON_ACCEPT ]->GetText( "Accept" );
+ rAssert( m_purchaseLabel != NULL );
+/*
+ pPage = m_pScroobyScreen->GetPage( "Buy" );
+ if( pPage != NULL )
+ {
+ m_buttonIcons[ BUTTON_ICON_ACCEPT ] = pPage->GetGroup( "AcceptLabel" );
+ rAssert( m_buttonIcons[ BUTTON_ICON_ACCEPT ] != NULL );
+
+ m_purchaseLabel = m_buttonIcons[ BUTTON_ICON_ACCEPT ]->GetText( "Accept" );
+ rAssert( m_purchaseLabel != NULL );
+ }
+*/
+
+ // create and setup controllers for character animations
+ //
+ m_skinMultiController = new tMultiController( 1, 90.0f );
+ rAssert( m_skinMultiController != NULL );
+ m_skinMultiController->AddRef();
+ m_skinMultiController->SetFramerate( 30.0f );
+
+ m_skinAnimController = new tPoseAnimationController;
+ rAssert( m_skinAnimController != NULL );
+ m_skinAnimController->AddRef();
+ m_skinMultiController->SetTrack( 0, m_skinAnimController );
+
+ m_skinTrackInfo.startTime = 0.0f;
+ m_skinTrackInfo.endTime = 0.0f;
+ m_skinTrackInfo.offset = 0.0f;
+ m_skinTrackInfo.scale = 1.0f;
+ m_skinMultiController->SetTrackInfo( 0, &m_skinTrackInfo );
+
+ rAssert( m_previewWindow != NULL );
+ m_previewWindow->SetMultiController( m_skinMultiController );
+
+ p3d::inventory->AddSection( PURCHASE_REWARDS_INVENTORY_SECTION );
+}
+
+
+//===========================================================================
+// CGuiScreenPurchaseRewards::~CGuiScreenPurchaseRewards
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenPurchaseRewards::~CGuiScreenPurchaseRewards()
+{
+ p3d::pddi->DrawSync();
+
+ p3d::inventory->DeleteSection( PURCHASE_REWARDS_INVENTORY_SECTION );
+
+ if( m_skinAnimController != NULL )
+ {
+ m_skinAnimController->Release();
+ m_skinAnimController = NULL;
+ }
+
+ if( m_skinMultiController != NULL )
+ {
+ m_skinMultiController->Release();
+ m_skinMultiController = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenPurchaseRewards::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+
+void CGuiScreenPurchaseRewards::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( message == GUI_MSG_WINDOW_ENTER )
+ {
+ // set current purchase center type
+ //
+ m_currentType = static_cast<Merchandise::eSellerType>( param1 );
+ rAssert( m_currentType != Merchandise::INVALID_SELLER_TYPE );
+ }
+
+ if( m_isLoading )
+ {
+ if( message == GUI_MSG_CONTROLLER_SELECT ||
+ message == GUI_MSG_CONTROLLER_BACK )
+ {
+ // don't allow user to select or back out of screen
+ // during loading
+ //
+ return;
+ }
+ }
+
+ rAssert( m_pRewardsMenu != NULL );
+ if( m_pRewardsMenu->HasSelectionBeenMade() || m_isLoadingReward || m_isPurchasingReward )
+ {
+ if( this->IsControllerMessage( message ) )
+ {
+ // selection has already been made or reward is currently loading,
+ // ignore all controller inputs
+ //
+ return;
+ }
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ int selectionDelta = 0;
+
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ if( !this->IsButtonVisible( BUTTON_ICON_ACCEPT ) )
+ {
+ // not enough coins to purchase reward
+ //
+ GetEventManager()->TriggerEvent( EVENT_FE_LOCKED_OUT );
+
+ return;
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ if( !m_pRewardsMenu->HasSelectionBeenMade() )
+ {
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK );
+
+ m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME );
+ }
+
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ // load selected reward item
+ //
+ this->PurchaseReward();
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_LEFT:
+ {
+ selectionDelta = -2;
+
+ // follow-thru
+ //
+ }
+ case GUI_MSG_CONTROLLER_RIGHT:
+ {
+ selectionDelta++;
+
+ int previousSelection = 0;
+
+ if( m_currentType == Merchandise::SELLER_INTERIOR )
+ {
+ if( m_numPreviewClothing > 1 )
+ {
+ previousSelection = m_currentPreviewClothing;
+
+ m_currentPreviewClothing = (m_currentPreviewClothing + m_numPreviewClothing + selectionDelta) % m_numPreviewClothing;
+
+ this->On3DModelSelectionChange( &m_previewClothing[ m_currentPreviewClothing ] );
+ }
+ }
+ else
+ {
+ if( m_numPreviewVehicles > 1 )
+ {
+ previousSelection = m_currentPreviewVehicle;
+
+ m_currentPreviewVehicle = (m_currentPreviewVehicle + m_numPreviewVehicles + selectionDelta) % m_numPreviewVehicles;
+
+ this->On3DModelSelectionChange( &m_previewVehicles[ m_currentPreviewVehicle ] );
+ }
+ }
+
+ this->UpdateRewardPrice();
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ else if( m_state == GUI_WINDOW_STATE_INTRO )
+ {
+ if( message == GUI_MSG_UPDATE )
+ {
+ if( m_numTransitionsPending == 1 && m_currentIrisState == IRIS_STATE_CLOSED )
+ {
+ // resume iris wipe
+ //
+ this->IrisWipeOpen();
+
+ // show the preview pedestal
+ //
+ rAssert( m_previewPedestal != NULL );
+ m_previewPedestal->SetVisible( true );
+ rAssert( m_previewBgd != NULL );
+ m_previewBgd->SetVisible( true );
+ }
+ }
+ }
+ else if( m_state == GUI_WINDOW_STATE_OUTRO )
+ {
+ if( message == GUI_MSG_UPDATE )
+ {
+ if( m_numTransitionsPending == 1 && m_currentIrisState == IRIS_STATE_CLOSED )
+ {
+ // resume iris wipe
+ //
+ this->IrisWipeOpen();
+
+ p3d::pddi->DrawSync();
+
+ // hide the preview pedestal
+ //
+ rAssert( m_previewPedestal != NULL );
+ m_previewPedestal->SetVisible( false );
+ rAssert( m_previewBgd != NULL );
+ m_previewBgd->SetVisible( false );
+
+ m_previewBgd->SetDrawable( NULL );
+ m_previewBgd->SetCamera( NULL );
+ m_previewBgd->SetMultiController( NULL );
+
+ p3d::inventory->RemoveSectionElements( PURCHASE_REWARDS_INVENTORY_SECTION );
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ IGuiScreenRewards::HandleMessage( message, param1, param2 );
+}
+
+void
+CGuiScreenPurchaseRewards::OnProcessRequestsComplete( void* pUserData )
+{
+ if( reinterpret_cast<Scrooby::Pure3dObject*>( pUserData ) == m_previewBgd )
+ {
+ m_numTransitionsPending--;
+
+ // push and select inventory section for searching
+ //
+ p3d::inventory->PushSection();
+ p3d::inventory->SelectSection( PURCHASE_REWARDS_INVENTORY_SECTION );
+ bool currentSectionOnly = p3d::inventory->GetCurrentSectionOnly();
+ p3d::inventory->SetCurrentSectionOnly( true );
+
+ // search for pedestal drawable
+ //
+ tDrawable* drawable = p3d::find<tDrawable>( PURCHASE_REWARDS_BGD_DRAWABLE );
+ if( drawable != NULL )
+ {
+ rAssert( m_previewBgd != NULL );
+ m_previewBgd->SetDrawable( drawable );
+
+ tCamera* camera = p3d::find<tCamera>( PURCHASE_REWARDS_BGD_CAMERA );
+ rAssert( camera != NULL );
+ m_previewBgd->SetCamera( camera );
+ m_previewPedestal->SetCamera( camera );
+ m_previewWindow->SetCamera( camera );
+
+ tMultiController* multiController = p3d::find<tMultiController>( PURCHASE_REWARDS_BGD_MULTICONTROLLER );
+ m_previewBgd->SetMultiController( multiController );
+ }
+ else
+ {
+ rAssertMsg( false, "*** Can't find 3D pedestal drawable!" );
+ }
+
+ // pop inventory section and restore states
+ //
+ p3d::inventory->SetCurrentSectionOnly( currentSectionOnly );
+ p3d::inventory->PopSection();
+ }
+ else if( m_isLoadingReward )
+ {
+ // this means we were waiting for the selected character skin to load;
+ // so, now that it's loaded, let's exit outa here
+ //
+ m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME );
+ }
+ else
+ {
+ IGuiScreenRewards::OnProcessRequestsComplete( pUserData );
+ }
+}
+
+#ifdef RAD_WIN32
+//===========================================================================
+// CGuiScreenPurchaseRewards::CheckCursorAgainstHotspots
+//===========================================================================
+// Description: Checks cursor position against its list of hotspots.
+//
+// Constraints: None.
+//
+// Parameters: float x - The x position of cursor in P3D coordinates.
+// float y - The y position of cursor in P3D coordinates.
+//
+// Return: N/A.
+//
+//===========================================================================
+eFEHotspotType CGuiScreenPurchaseRewards::CheckCursorAgainstHotspots( float x, float y )
+{
+ eFEHotspotType hotSpotType = CGuiScreen::CheckCursorAgainstHotspots( x, y );
+ if( hotSpotType == HOTSPOT_NONE )
+ {
+ if( m_leftArrow )
+ {
+ if( m_leftArrow->IsPointInBoundingRect( x, y ) )
+ {
+ hotSpotType = HOTSPOT_ARROWLEFT;
+ }
+ }
+ if( m_rightArrow )
+ {
+ if( m_rightArrow->IsPointInBoundingRect( x, y ) )
+ {
+ hotSpotType = HOTSPOT_ARROWRIGHT;
+ }
+ }
+
+ }
+ return hotSpotType;
+}
+#endif
+
+//===========================================================================
+// CGuiScreenPurchaseRewards::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPurchaseRewards::InitIntro()
+{
+ // load 3D pedestal
+ //
+ GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D,
+ PURCHASE_REWARDS_BGD,
+ GMA_LEVEL_MISSION,
+ PURCHASE_REWARDS_INVENTORY_SECTION,
+ PURCHASE_REWARDS_INVENTORY_SECTION,
+ this,
+ reinterpret_cast<void*>( m_previewBgd ) );
+ m_numTransitionsPending++;
+
+ IGuiScreenRewards::InitIntro();
+
+ // load current 3D model object
+ //
+ this->On3DModelSelectionChange( this->GetCurrentPreviewObject() );
+
+ // show and update reward price
+ //
+ rAssert( m_rewardPrice != NULL );
+ m_rewardPrice->SetVisible( true );
+ this->UpdateRewardPrice();
+
+ // show/hide stats button label
+ //
+ rAssert( m_statsOverlayButton );
+ m_statsOverlayButton->SetVisible( m_currentType != Merchandise::SELLER_INTERIOR );
+
+ // hide vehicle stats by default
+ //
+ this->SetVehicleStatsVisible( false );
+
+ // adjust pedestal scale
+ //
+ rAssert( m_previewPedestal != NULL );
+ if( m_currentType == Merchandise::SELLER_INTERIOR )
+ {
+ // scale down pedestal a bit
+ //
+ m_previewPedestal->SetDrawableScale( PREVIEW_PEDESTAL_SCALE_FOR_SKINS );
+
+ // notify sound manager that game is paused, include dialogue in
+ // ducking to kill gag sounds -- Esan
+ //
+ GetSoundManager()->DuckEverythingButMusicBegin( true );
+ }
+ else
+ {
+ m_previewPedestal->SetDrawableScale( 1.0f );
+
+ // notify sound manager that game is paused, don't duck dialogue
+ // so we can still hear ol' Gil -- Esan
+ //
+ GetSoundManager()->OnStoreScreenStart( true );
+ }
+
+ // enable/disable L/R arrows
+ //
+ if( m_numPreviewClothing > 1 || m_numPreviewVehicles > 1 )
+ {
+ m_pRewardsMenu->SetSelectionValueCount( 0, 2 );
+ }
+ else
+ {
+ m_pRewardsMenu->SetSelectionValueCount( 0, 1 );
+ }
+
+ m_bankValueBeforePurchase = GetCoinManager()->GetBankValue();
+}
+
+//===========================================================================
+// CGuiScreenPurchaseRewards::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPurchaseRewards::InitRunning()
+{
+ IGuiScreenRewards::InitRunning();
+
+ CGuiScreenHud::UpdateNumCoinsDisplay( m_bankValueBeforePurchase );
+}
+
+//===========================================================================
+// CGuiScreenPurchaseRewards::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenPurchaseRewards::InitOutro()
+{
+ // hide 3D coin on FE render layer
+ //
+ CGuiScreenHud::UpdateNumCoinsDisplay( 0, false );
+
+ IGuiScreenRewards::InitOutro();
+
+ if( m_currentType == Merchandise::SELLER_INTERIOR )
+ {
+ // notify sound manager that game is paused
+ //
+ GetSoundManager()->DuckEverythingButMusicEnd( true );
+ }
+ else
+ {
+ GetSoundManager()->OnStoreScreenEnd();
+ }
+}
+
+void
+CGuiScreenPurchaseRewards::On3DModelLoaded( const PreviewObject* previewObject )
+{
+ p3d::pddi->DrawSync();
+
+ // search for 3D model in inventory
+ //
+ tDrawable* drawable = p3d::find<tDrawable>( previewObject->nameModel );
+ if( drawable != NULL )
+ {
+ rAssert( m_previewWindow != NULL );
+ m_previewWindow->SetDrawable( drawable );
+
+ if( m_currentType != Merchandise::SELLER_INTERIOR )
+ {
+ // place vehicles (w/ wheels) on the ground (y = 0)
+ //
+ rmt::Box3D box3D;
+ drawable->GetBoundingBox( &box3D );
+ float groundOffset = box3D.low.y;
+ m_previewWindow->SetDrawableTranslation( 0.0f, -groundOffset, 0.0f );
+
+ // scale vehicles so that they fit nicely on pedestal
+ //
+ rmt::Sphere sphere;
+ drawable->GetBoundingSphere( &sphere );
+ m_previewWindow->SetDrawableScale( PREVIEW_VEHICLE_RADIUS / sphere.radius );
+ }
+ else
+ {
+ // assume characters are already placed on ground (y = 0)
+ //
+ m_previewWindow->SetDrawableTranslation( 0.0f, 0.0f, 0.0f );
+
+ // scale characters larger to fill the screen
+ //
+ m_previewWindow->SetDrawableScale( PREVIEW_CHARACTER_SCALE );
+
+ // set character animation
+ //
+ HeapMgr()->PushHeap( GMA_LEVEL_MISSION );
+ tDrawablePose *drawable_pose = dynamic_cast<tDrawablePose *>(drawable);
+ rAssert( drawable_pose != NULL );
+
+ m_skinAnimController->SetPose( drawable_pose->GetPose() );
+
+ p3d::inventory->SetCurrentSectionOnly( false );
+ char anim_name[32];
+ switch(GetGameplayManager()->GetCurrentLevelIndex())
+ {
+ case 0:
+ case 6:
+ strcpy(anim_name,"hom");
+ break;
+ case 1:
+ case 5:
+ strcpy(anim_name,"brt");
+ break;
+ case 2:
+ strcpy(anim_name,"lsa");
+ break;
+ case 3:
+ strcpy(anim_name,"mrg");
+ break;
+ case 4:
+ strcpy(anim_name,"apu");
+ break;
+ default:
+ strcpy( anim_name,"hom" );
+ break;
+ }
+ strcat(anim_name, "_loco_idle_rest");
+ tAnimation* anim = p3d::find<tAnimation>( anim_name );
+ rAssert( anim != NULL );
+ anim->SetCyclic( true );
+
+ rAssert( m_skinAnimController != NULL );
+ m_skinAnimController->SetAnimation( anim, 0.0f, 0.0f );
+
+ m_skinTrackInfo.endTime = anim->GetNumFrames();
+
+ rAssert( m_skinMultiController != NULL );
+ m_skinMultiController->Reset();
+ m_skinMultiController->SetFrame( 0.0f );
+ m_skinMultiController->SetTrackInfo( 0, &m_skinTrackInfo );
+
+ HeapMgr()->PopHeap( GMA_LEVEL_MISSION );
+
+ }
+ }
+ else
+ {
+ rAssertMsg( false, "*** Can't find drawable for 3D model!!" );
+ }
+}
+
+const PreviewObject*
+CGuiScreenPurchaseRewards::GetCurrentPreviewObject() const
+{
+ const PreviewObject* previewObject = NULL;
+
+ switch( m_currentType )
+ {
+ case Merchandise::SELLER_INTERIOR:
+ {
+ if( m_numPreviewClothing > 0 )
+ {
+ previewObject = &m_previewClothing[ m_currentPreviewClothing ];
+ }
+
+ break;
+ }
+ case Merchandise::SELLER_SIMPSON:
+ case Merchandise::SELLER_GIL:
+ {
+ if( m_numPreviewVehicles > 0 )
+ {
+ previewObject = &m_previewVehicles[ m_currentPreviewVehicle ];
+ }
+
+ break;
+ }
+ default:
+ {
+ rAssert( false );
+ break;
+ }
+ }
+
+ return previewObject;
+}
+
+void
+CGuiScreenPurchaseRewards::InitMenu()
+{
+ int currentLevel = GetGameplayManager()->GetCurrentLevelIndex();
+ Reward* pReward = NULL;
+
+ m_numPreviewClothing = 0;
+ m_numPreviewVehicles = 0;
+
+ switch( m_currentType )
+ {
+ case Merchandise::SELLER_INTERIOR:
+ {
+ Character* currentCharacter = GetCharacterManager()->GetCharacter( 0 );
+ rAssert( currentCharacter != NULL );
+ const char* currentSkinName = GetCharacterManager()->GetModelName( currentCharacter );
+
+ // insert default character skin first
+ //
+ pReward = GetRewardsManager()->GetReward( currentLevel, Reward::eDefaultSkin );
+ if( pReward != NULL )
+ {
+ if( strcmp( currentSkinName, pReward->GetName() ) != 0 )
+ {
+ m_numPreviewClothing = this->InsertPreviewObject( m_previewClothing,
+ m_numPreviewClothing,
+ pReward );
+ }
+ }
+
+ // insert all other purchasable skins
+ //
+ for( pReward = GetRewardsManager()->FindFirstMerchandise( currentLevel, m_currentType );
+ pReward != NULL;
+ pReward = GetRewardsManager()->FindNextMerchandise( currentLevel, m_currentType ) )
+ {
+ if( strcmp( currentSkinName, pReward->GetName() ) != 0 )
+ {
+ rAssert( m_numPreviewClothing < MAX_NUM_PREVIEW_CLOTHING );
+ m_numPreviewClothing = this->InsertPreviewObject( m_previewClothing,
+ m_numPreviewClothing,
+ pReward );
+ }
+ }
+
+ if( GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_SKINS ) )
+ {
+ for( int i = 0; i < m_numPreviewClothing; i++ )
+ {
+ m_previewClothing[ i ].isUnlocked = true;
+ }
+ }
+
+ break;
+ }
+ case Merchandise::SELLER_SIMPSON:
+ case Merchandise::SELLER_GIL:
+ {
+ for( pReward = GetRewardsManager()->FindFirstMerchandise( currentLevel, m_currentType );
+ pReward != NULL;
+ pReward = GetRewardsManager()->FindNextMerchandise( currentLevel, m_currentType ) )
+ {
+ // only display locked rewards
+ //
+ if( !pReward->RewardStatus() )
+ {
+ rAssert( m_numPreviewVehicles < MAX_NUM_PREVIEW_VEHICLES );
+ m_numPreviewVehicles = this->InsertPreviewObject( m_previewVehicles,
+ m_numPreviewVehicles,
+ pReward,
+ true );
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ rAssert( false );
+ break;
+ }
+ }
+}
+
+void
+CGuiScreenPurchaseRewards::OnUpdate( unsigned int elapsedTime )
+{
+/*
+ // always show accept button
+ //
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, true );
+*/
+/*
+ // rotate reward object
+ //
+ const unsigned int ROTATION_PERIOD = 3000;
+
+ m_elapsedRotationTime = (m_elapsedRotationTime + elapsedTime) % ROTATION_PERIOD;
+
+ rAssert( m_previewWindow != NULL );
+ m_previewWindow->ResetTransformation();
+
+ float rotation = (m_elapsedRotationTime / (float)ROTATION_PERIOD) * 360.0f;
+ m_previewWindow->RotateAboutCenter( rotation,
+ rmt::Vector( 0.0f, 1.0f, 0.0f ) );
+*/
+ if( m_isPurchasingReward )
+ {
+ const unsigned int COINS_DECREMENT_DURATION = 1000; // in msec
+ const unsigned int COINS_DECREMENT_PERIOD = 100; // in msec
+
+ m_elapsedCoinDecrementTotalTime += elapsedTime;
+ if( m_elapsedCoinDecrementTotalTime < COINS_DECREMENT_DURATION )
+ {
+ m_elapsedCoinDecrementTime += elapsedTime;
+ if( m_elapsedCoinDecrementTime > COINS_DECREMENT_PERIOD )
+ {
+ int deltaCoins = m_bankValueBeforePurchase - GetCoinManager()->GetBankValue();
+ int bankValue = m_bankValueBeforePurchase - (int)( m_elapsedCoinDecrementTotalTime / (float)COINS_DECREMENT_DURATION * deltaCoins );
+
+ CGuiScreenHud::UpdateNumCoinsDisplay( bankValue );
+
+ GetCoinManager()->AddFlyDownCoin();
+
+ m_elapsedCoinDecrementTime %= COINS_DECREMENT_PERIOD;
+ }
+ }
+ else
+ {
+ CGuiScreenHud::UpdateNumCoinsDisplay( GetCoinManager()->GetBankValue() );
+
+ m_isPurchasingReward = false;
+
+ // ok, we've reached the real current bank value;
+ // now load the purchased reward now
+ //
+ this->LoadSelectedReward();
+/*
+ if( m_currentType == Merchandise::SELLER_INTERIOR )
+ {
+ this->LoadSelectedReward();
+ }
+ else
+ {
+ // don't load vehicles, user must go to the phone
+ // booth to do that
+ //
+ m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN );
+ }
+*/
+ }
+ }
+
+ IGuiScreenRewards::OnUpdate( elapsedTime );
+}
+
+void
+CGuiScreenPurchaseRewards::UpdateRewardPrice()
+{
+ const PreviewObject* currentPreviewObject = this->GetCurrentPreviewObject();
+ rAssert( currentPreviewObject != NULL );
+
+ if( currentPreviewObject->isUnlocked )
+ {
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, true );
+ }
+ else
+ {
+ Merchandise* pMerchandise = GetRewardsManager()->GetMerchandise( GetGameplayManager()->GetCurrentLevelIndex(),
+ currentPreviewObject->name );
+ if( pMerchandise != NULL )
+ {
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ int rewardCost = pMerchandise->GetCost();
+ rAssertMsg( rewardCost > 0, "Reward price should be a positive integer!" );
+
+ // get "coins" text
+ //
+ char coinsText[ 32 ];
+ p3d::UnicodeToAscii( GetTextBibleString( "COINS" ), coinsText, sizeof( coinsText ) );
+
+ char buffer[ 32 ];
+#ifdef PAL
+ if( CGuiTextBible::GetCurrentLanguage() == Scrooby::XL_GERMAN )
+ {
+ // special case for German for proper grammar
+ //
+ sprintf( buffer, "Für %d %s", rewardCost, coinsText );
+ }
+ else
+#endif // PAL
+ {
+ sprintf( buffer, "%d %s", rewardCost, coinsText );
+ }
+
+ rAssert( strlen( buffer ) < sizeof( buffer ) );
+
+ rAssert( m_rewardPrice != NULL );
+ m_rewardPrice->SetString( 0, buffer );
+
+ // only show accept label if user has enough money to purchase OR
+ // if reward is already unlocked
+ //
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, GetCoinManager()->GetBankValue() >= rewardCost );
+
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+ }
+ }
+
+ // update purchase label
+ //
+ rAssert( m_purchaseLabel != NULL );
+ m_purchaseLabel->SetIndex( currentPreviewObject->isUnlocked ? 1 : 0 );
+}
+
+void
+CGuiScreenPurchaseRewards::PurchaseReward()
+{
+ const PreviewObject* currentPreviewObject = this->GetCurrentPreviewObject();
+ rAssert( currentPreviewObject != NULL );
+
+ if( currentPreviewObject->isUnlocked )
+ {
+ // reward is already unlocked, so just load it
+ //
+ this->LoadSelectedReward();
+ }
+ else
+ {
+ bool boughtReward = GetRewardsManager()->BuyMerchandise( GetGameplayManager()->GetCurrentLevelIndex(),
+ currentPreviewObject->name );
+
+ if( boughtReward )
+ {
+ // hide lock overlay
+ //
+ rAssert( m_lockedOverlay != NULL );
+ m_lockedOverlay->SetVisible( false );
+
+ // update hud coins current item count
+ //
+ CGuiScreenHud* currentHud = GetCurrentHud();
+ if( currentHud != NULL )
+ {
+ HudCoinCollected* hudCoinCollected = static_cast<HudCoinCollected*>( currentHud->GetEventHandler( CGuiScreenHud::HUD_EVENT_HANDLER_COIN_COLLECTED ) );
+ rAssert( hudCoinCollected != NULL );
+ hudCoinCollected->SetCurrentItemCount( GetCoinManager()->GetBankValue() );
+ hudCoinCollected->Start();
+ }
+
+ m_isPurchasingReward = true;
+ m_elapsedCoinDecrementTotalTime = 0;
+ m_elapsedCoinDecrementTime = 0;
+ }
+ else
+ {
+ rAssertMsg( false, "This should not happen!" );
+ }
+ }
+}
+
+void
+CGuiScreenPurchaseRewards::LoadSelectedReward()
+{
+ // unload 3D model first before loading reward
+ //
+ this->Unload3DModel();
+
+ m_isLoading = true; // set loading flag
+ m_isLoadingReward = true; // we're loading the selected reward
+
+ if( m_currentType == Merchandise::SELLER_INTERIOR )
+ {
+ Character* currentCharacter = GetCharacterManager()->GetCharacter( 0 );
+
+ char characterName[ 16 ];
+ tUID characterUID = currentCharacter->GetUID();
+
+ if( characterUID == CHARACTER_NAME_HOMER )
+ {
+ strcpy( characterName, "homer" );
+ }
+ else if( characterUID == CHARACTER_NAME_BART )
+ {
+ strcpy( characterName, "bart" );
+ }
+ else if( characterUID == CHARACTER_NAME_LISA )
+ {
+ strcpy( characterName, "lisa" );
+ }
+ else if( characterUID == CHARACTER_NAME_MARGE )
+ {
+ strcpy( characterName, "marge" );
+ }
+ else if( characterUID == CHARACTER_NAME_APU )
+ {
+ strcpy( characterName, "apu" );
+ }
+ else
+ {
+ rAssert( false );
+ }
+
+ GetCharacterManager()->SwapData( currentCharacter,
+ m_previewClothing[ m_currentPreviewClothing ].name,
+ characterName );
+
+ //Chuck: Save the skin they are buy/changing into as the current skin
+ GetCharacterSheetManager()->SetCurrentSkin(GetGameplayManager()->GetCurrentLevelIndex(),m_previewClothing[ m_currentPreviewClothing ].name);
+
+ GetCharacterManager()->PreloadCharacter( m_previewClothing[ m_currentPreviewClothing ].name,
+ characterName,
+ this );
+
+ //for the HitnRun system
+ GetEventManager()->TriggerEvent( EVENT_SWITCH_SKIN, NULL );
+
+ }
+ else
+ {
+ ActionButton::SummonVehiclePhone::LoadVehicle( m_previewVehicles[ m_currentPreviewVehicle ].name,
+ m_previewVehicles[ m_currentPreviewVehicle ].filename,
+ VehicleCentral::ALLOW_DRIVER );
+ }
+}
+
diff --git a/game/code/presentation/gui/ingame/guiscreenpurchaserewards.h b/game/code/presentation/gui/ingame/guiscreenpurchaserewards.h
new file mode 100644
index 0000000..6b972ca
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenpurchaserewards.h
@@ -0,0 +1,87 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenPurchaseRewards
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/21 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENPURCHASEREWARDS_H
+#define GUISCREENPURCHASEREWARDS_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenrewards.h>
+#include <mission/rewards/merchandise.h>
+#include <p3d/anim/multicontroller.hpp>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class tMultiController;
+class tPoseAnimationController;
+class tPose;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenPurchaseRewards : public IGuiScreenRewards
+{
+public:
+ CGuiScreenPurchaseRewards( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenPurchaseRewards();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ void OnProcessRequestsComplete( void* pUserData );
+
+#ifdef RAD_WIN32
+ virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y );
+#endif
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+ virtual void On3DModelLoaded( const PreviewObject* previewObject );
+ virtual const PreviewObject* GetCurrentPreviewObject() const;
+ virtual void InitMenu();
+
+private:
+ void OnUpdate( unsigned int elapsedTime );
+ void UpdateRewardPrice();
+ void UpdateBankValue();
+ void PurchaseReward();
+ void LoadSelectedReward();
+
+ Merchandise::eSellerType m_currentType;
+ bool m_isPurchasingReward;
+ unsigned int m_elapsedCoinDecrementTotalTime;
+ unsigned int m_elapsedCoinDecrementTime;
+ int m_bankValueBeforePurchase;
+ Scrooby::Text* m_purchaseLabel;
+
+#ifdef RAD_WIN32
+ Scrooby::Sprite* m_leftArrow;
+ Scrooby::Sprite* m_rightArrow;
+#endif
+
+ tMultiController::TrackInfo m_skinTrackInfo;
+ tMultiController* m_skinMultiController;
+ tPoseAnimationController* m_skinAnimController;
+
+};
+
+#endif // GUISCREENPURCHASEREWARDS_H
diff --git a/game/code/presentation/gui/ingame/guiscreenrewards.cpp b/game/code/presentation/gui/ingame/guiscreenrewards.cpp
new file mode 100644
index 0000000..997c67e
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenrewards.cpp
@@ -0,0 +1,854 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: IGuiScreenRewards
+//
+// Description: Implementation of the IGuiScreenRewards class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/21 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenrewards.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guitextbible.h>
+
+#include <memory/srrmemory.h>
+#include <mission/gameplaymanager.h>
+#include <mission/rewards/rewardsmanager.h>
+#include <mission/rewards/reward.h>
+#include <worldsim/coins/coinmanager.h>
+
+#include <screen.h>
+#include <page.h>
+#include <sprite.h>
+#include <text.h>
+#include <pure3dobject.h>
+#include <group.h>
+#include <polygon.h>
+
+#include <p3d/unicode.hpp>
+#include <raddebug.hpp> // Foundation
+
+#include <string.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const char* REWARDS_INVENTORY_SECTION = "FE_RewardsScreen";
+
+#ifdef RAD_XBOX
+ const float PHONE_BOOTH_BGD_CORRECTION_SCALE = 8.0f;
+#else
+ const float PHONE_BOOTH_BGD_CORRECTION_SCALE = 8.8f;
+#endif
+
+const float LIGHT_OPEN_CLOSE_TRANSITION_TIME = 500.0f; // in msec
+
+const char* PHONE_BOOTH_3DMODEL_CARS_DIR = "art\\frontend\\dynaload\\cars\\";
+const char* PHONE_BOOTH_2DMODEL_CARS_DIR = "art\\frontend\\dynaload\\images\\cars2D\\";
+
+//===========================================================================
+// PhoneBoothStars::
+//===========================================================================
+
+PhoneBoothStars::PhoneBoothStars( Scrooby::Page* pPage, const char* namePrefix )
+{
+ rAssert( pPage );
+ for( int i = 0; i < MAX_NUM_STARS; i++ )
+ {
+ char name[ 32 ];
+ sprintf( name, "%s_Stars%d", namePrefix, i );
+ m_stars[ i ] = pPage->GetSprite( name );
+ }
+}
+
+void
+PhoneBoothStars::SetNumStars( float numStars )
+{
+ rWarningMsg( numStars >= 0.0f && numStars <= static_cast<float>( MAX_NUM_STARS ),
+ "Number of stars exceeds boundaries!" );
+
+ for( int i = 0; i < MAX_NUM_STARS; i++ )
+ {
+ bool isOn = (i < static_cast<int>( numStars ));
+
+ // check if half on
+ //
+ bool isHalfOn = !isOn && (static_cast<float>( i ) < numStars);
+
+ rAssert( m_stars[ i ] != NULL );
+ if( isOn )
+ {
+ m_stars[ i ]->SetIndex( 2 );
+// m_stars[ i ]->SetAlpha( 1.0f );
+ }
+ else if( isHalfOn )
+ {
+ m_stars[ i ]->SetIndex( 1 );
+// m_stars[ i ]->SetAlpha( 1.0f );
+ }
+ else
+ {
+ m_stars[ i ]->SetIndex( 0 );
+// m_stars[ i ]->SetAlpha( 0.5f );
+ }
+ }
+}
+
+
+//===========================================================================
+// IGuiScreenRewards::
+//===========================================================================
+
+IGuiScreenRewards::IGuiScreenRewards( Scrooby::Screen* pScreen,
+ Scrooby::Page* pPage,
+ CGuiEntity* pParent,
+ eGuiWindowID windowID )
+: CGuiScreen( pScreen, pParent, windowID ),
+ m_pRewardsMenu( NULL ),
+ m_currentState( REWARDS_SCREEN_LIGHT_CLOSED ),
+ m_elapsedTime( 0.0f ),
+ m_previewLightCover( NULL ),
+ m_previewWindow( NULL ),
+ m_previewPedestal( NULL ),
+ m_previewBgd( NULL ),
+ m_previewImage( NULL ),
+ m_previewName( NULL ),
+ m_numPreviewVehicles( 0 ),
+ m_currentPreviewVehicle( 0 ),
+ m_numPreviewClothing( 0 ),
+ m_currentPreviewClothing( 0 ),
+ m_isLoading( false ),
+ m_isLoadingReward( false ),
+ m_lockedOverlay( NULL ),
+ m_lockedLevel( NULL ),
+ m_rewardPrice( NULL ),
+ m_statsOverlay( NULL ),
+ m_statsOverlayButton( NULL ),
+ m_statsOverlayButtonLabel( NULL ),
+ m_statsOverlayToggle( false )
+{
+ // Retrieve the Scrooby drawing elements.
+ //
+ rAssert( pPage != NULL );
+
+ Scrooby::Sprite* previewLightL = pPage->GetSprite( "PreviewLightL" );
+ Scrooby::Sprite* previewLightR = pPage->GetSprite( "PreviewLightR" );
+ if( previewLightL != NULL && previewLightR != NULL )
+ {
+ previewLightL->ResetTransformation();
+ previewLightR->ResetTransformation();
+
+ // apply image correction scales
+ //
+ previewLightL->ScaleAboutCenter( PHONE_BOOTH_BGD_CORRECTION_SCALE );
+ previewLightR->ScaleAboutCenter( PHONE_BOOTH_BGD_CORRECTION_SCALE );
+
+ // flip the right light image horizontally to mirror the
+ // left light image
+ //
+ previewLightR->RotateAboutCenter( 180.0f, rmt::Vector( 0.0f, 1.0f, 0.0f ) );
+ }
+
+ // get preview light cover (for opening/closing light)
+ //
+ m_previewLightCover = pPage->GetPolygon( "PreviewLightCover" );
+
+ // get preview image
+ //
+ m_previewImage = pPage->GetSprite( "PreviewImage" );
+
+ // create rewards menu w/ preview name
+ //
+ m_previewName = pPage->GetText( "PreviewName" );
+ rAssert( m_previewName );
+ m_previewName->SetTextMode( Scrooby::TEXT_WRAP );
+
+ m_pRewardsMenu = new CGuiMenu( this, 1, GUI_TEXT_MENU, MENU_SFX_NONE );
+ rAssert( m_pRewardsMenu != NULL );
+
+ m_pRewardsMenu->AddMenuItem( m_previewName,
+ pPage->GetText( "PreviewNameDummy" ),
+ NULL,
+ NULL,
+ pPage->GetSprite( "LeftArrow" ),
+ pPage->GetSprite( "RightArrow" ) );
+
+ // get preview window and pedestal
+ //
+ m_previewWindow = pPage->GetPure3dObject( "PreviewWindow" );
+ if( m_previewWindow != NULL )
+ {
+ m_previewWindow->SetVisible( false );
+ m_previewWindow->SetClearDepthBuffer( true );
+ }
+
+ m_previewPedestal = pPage->GetPure3dObject( "RewardFG" );
+ if ( m_previewPedestal != NULL )
+ {
+ m_previewPedestal->SetVisible( false );
+ }
+
+ m_previewBgd = pPage->GetPure3dObject( "RewardBG" );
+ if( m_previewBgd != NULL )
+ {
+ m_previewBgd->SetVisible( false );
+ m_previewBgd->SetClearDepthBuffer( true );
+ }
+
+ // get lock overlay
+ //
+ m_lockedOverlay = pPage->GetGroup( "Locked" );
+ rAssert( m_lockedOverlay );
+
+ // get locked level
+ //
+ m_lockedLevel = pPage->GetText( "Level" );
+
+#ifdef RAD_E3
+ if( m_lockedLevel != NULL )
+ {
+ m_lockedLevel->SetVisible( false ); // hide level display on E3 build
+ }
+#endif
+
+ // get reward price
+ //
+ m_rewardPrice = m_lockedOverlay->GetText( "Price" );
+ if( m_rewardPrice != NULL )
+ {
+ m_rewardPrice->SetDisplayOutline( true );
+
+ Scrooby::Text* toPurchase = m_lockedOverlay->GetText( "ToPurchase" );
+ if( toPurchase != NULL )
+ {
+ toPurchase->SetDisplayOutline( true );
+ }
+ }
+
+ // get stats overlay and button label
+ //
+ m_statsOverlay = pPage->GetGroup( "VehicleStats" );
+ m_statsOverlayButton = pPage->GetGroup( "ToggleView" );
+ m_statsOverlayButtonLabel = pPage->GetText( "ToggleView" );
+
+ // get vehicle star ratings
+ //
+ for( int i = 0; i < NUM_VEHICLE_RATINGS; i++ )
+ {
+ m_vehicleRatings[ i ] = NULL;
+ }
+
+ m_vehicleRatings[ VEHICLE_RATING_SPEED ] = new PhoneBoothStars( pPage, "Spe" );
+ m_vehicleRatings[ VEHICLE_RATING_ACCELERATION ] = new PhoneBoothStars( pPage, "Acc" );
+ m_vehicleRatings[ VEHICLE_RATING_TOUGHNESS ] = new PhoneBoothStars( pPage, "Tou" );
+ m_vehicleRatings[ VEHICLE_RATING_STABILITY ] = new PhoneBoothStars( pPage, "Sta" );
+
+ // create inventory section for loading rewards
+ //
+ p3d::inventory->AddSection( REWARDS_INVENTORY_SECTION );
+}
+
+IGuiScreenRewards::~IGuiScreenRewards()
+{
+ for( int i = 0; i < NUM_VEHICLE_RATINGS; i++ )
+ {
+ if( m_vehicleRatings[ i ] != NULL )
+ {
+ delete m_vehicleRatings[ i ];
+ m_vehicleRatings[ i ] = NULL;
+ }
+ }
+
+ if( m_pRewardsMenu != NULL )
+ {
+ delete m_pRewardsMenu;
+ m_pRewardsMenu = NULL;
+ }
+
+ // destroy inventory section for loading rewards
+ //
+ p3d::pddi->DrawSync();
+
+ p3d::inventory->DeleteSection( REWARDS_INVENTORY_SECTION );
+}
+
+void
+IGuiScreenRewards::HandleMessage( eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2 )
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ this->OnUpdate( param1 );
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_AUX_X:
+ {
+ // toggle vehicle stats overlay
+ //
+ if( m_statsOverlayButton != NULL && m_statsOverlayButton->IsVisible() )
+ {
+ this->SetVehicleStatsVisible( !m_statsOverlayToggle );
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ rAssert( m_pRewardsMenu != NULL );
+ m_pRewardsMenu->HandleMessage( message, param1, param2 );
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+void
+IGuiScreenRewards::OnProcessRequestsComplete( void* pUserData )
+{
+ m_isLoading = false; // reset loading flag
+
+ const PreviewObject* currentPreviewObject = this->GetCurrentPreviewObject();
+/*
+ if( m_state != GUI_WINDOW_STATE_RUNNING )
+ {
+ // hmmm... the user must have backed out of this screen before
+ // the preview object has been loaded; fine, we'll just unload it then
+ //
+ this->Unload3DModel();
+ }
+ else
+*/
+ {
+ if( reinterpret_cast<PreviewObject*>( pUserData ) != currentPreviewObject )
+ {
+ // selection must have changed while loading, so let's try
+ // to catch up
+ //
+ this->On3DModelSelectionChange( currentPreviewObject );
+ }
+ else
+ {
+ // push and select inventory section for searching
+ //
+ p3d::inventory->PushSection();
+ p3d::inventory->SelectSection( REWARDS_INVENTORY_SECTION );
+ bool currentSectionOnly = p3d::inventory->GetCurrentSectionOnly();
+ p3d::inventory->SetCurrentSectionOnly( true );
+
+ this->On3DModelLoaded( currentPreviewObject );
+
+ // pop inventory section and restore states
+ //
+ p3d::inventory->SetCurrentSectionOnly( currentSectionOnly );
+ p3d::inventory->PopSection();
+/*
+ // turn on/off lights depending on whether or not reward is unlocked
+ //
+ rAssert( m_previewBgd );
+ tView* pView = m_previewBgd->GetView();
+ if( pView != NULL )
+ {
+ for( unsigned int i = 0; i < MAX_VIEW_LIGHTS; i++ )
+ {
+ tLight* pLight = pView->GetLight( i );
+ if( pLight != NULL )
+ {
+ pLight->Enable( currentPreviewObject->isUnlocked );
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+*/
+ }
+ }
+}
+
+void
+IGuiScreenRewards::InitIntro()
+{
+ m_numPreviewVehicles = 0;
+ m_currentPreviewVehicle = 0;
+
+ m_numPreviewClothing = 0;
+ m_currentPreviewClothing = 0;
+
+ // close light by default
+ //
+ this->SetLightOpening( 0.0f );
+ m_currentState = REWARDS_SCREEN_LIGHT_CLOSED;
+
+ // initialize menu w/ level-specific selections
+ //
+ this->InitMenu();
+
+ GetCoinManager()->SetDrawAfterGui(true);
+
+}
+
+void
+IGuiScreenRewards::InitRunning()
+{
+}
+
+void
+IGuiScreenRewards::InitOutro()
+{
+ m_isLoading = false;
+ m_isLoadingReward = false;
+
+ // unload current 3D vehicle
+ //
+ this->Unload3DModel();
+
+ GetCoinManager()->SetDrawAfterGui(false);
+}
+
+int
+IGuiScreenRewards::InsertPreviewObject( PreviewObject* previewObjects,
+ int numPreviewObjects,
+ Reward* pReward,
+ bool isSorted )
+{
+ rAssert( previewObjects != NULL );
+ rAssert( pReward != NULL );
+
+ int newSlot = numPreviewObjects;
+
+ if( isSorted )
+ {
+ // *** assumes array is already sorted ***
+
+ // sort by unlock status first (unlocked rewards before locked rewards);
+ // then sort unlocked rewards alphabetically, and sort locked rewards by level
+ //
+ for( int i = 0; i < numPreviewObjects; i++ )
+ {
+ bool insertHere = false;
+
+ if( static_cast<int>( pReward->RewardStatus() ) > static_cast<int>( previewObjects[ i ].isUnlocked ) )
+ {
+ insertHere = true;
+ }
+ else if( pReward->RewardStatus() && previewObjects[ i ].isUnlocked )
+ {
+ char stringID[ 16 ];
+ char string1[ 64 ];
+ char string2[ 64 ];
+
+ strcpy( stringID, pReward->GetName() );
+ p3d::UnicodeToAscii( GetTextBibleString( strupr( stringID ) ), string1, sizeof( string1 ) );
+
+ strcpy( stringID, previewObjects[ i ].name );
+ p3d::UnicodeToAscii( GetTextBibleString( strupr( stringID ) ), string2, sizeof( string2 ) );
+
+ insertHere = ( strcmp( string1, string2 ) < 0 );
+ }
+ else if( !pReward->RewardStatus() && !previewObjects[ i ].isUnlocked )
+ {
+ insertHere = ( pReward->GetLevel() < previewObjects[ i ].pReward->GetLevel() );
+ }
+
+ if( insertHere )
+ {
+ // OK, found it!
+ //
+ newSlot = i;
+
+ // move all remaining preview objects up a slot to make room
+ // for the new guy
+ //
+ for( int j = numPreviewObjects - 1; j >= i; j-- )
+ {
+ strcpy( previewObjects[ j + 1 ].name, previewObjects[ j ].name );
+ strcpy( previewObjects[ j + 1 ].filename, previewObjects[ j ].filename );
+ strcpy( previewObjects[ j + 1 ].nameModel, previewObjects[ j ].nameModel );
+ strcpy( previewObjects[ j + 1 ].filenameModel, previewObjects[ j ].filenameModel );
+ previewObjects[ j + 1 ].isUnlocked = previewObjects[ j ].isUnlocked;
+ previewObjects[ j + 1 ].pReward = previewObjects[ j ].pReward;
+ }
+
+ // we're done
+ //
+ break;
+ }
+ }
+ }
+
+ // insert new object into the available slot
+ //
+ strncpy( previewObjects[ newSlot ].name, pReward->GetName(),
+ sizeof( previewObjects[ newSlot ].name ) );
+
+ strncpy( previewObjects[ newSlot ].filename, pReward->GetFile(),
+ sizeof( previewObjects[ newSlot ].filename ) );
+
+ if( m_ID == GUI_SCREEN_ID_PHONE_BOOTH )
+ {
+ // use 2D images for phone booth
+ //
+ strcpy( previewObjects[ newSlot ].nameModel, pReward->GetName() );
+
+ sprintf( previewObjects[ newSlot ].filenameModel, "%s%s",
+ PHONE_BOOTH_2DMODEL_CARS_DIR,
+ pReward->GetName() );
+ }
+ else
+ {
+ if( pReward->GetRewardType() == Reward::ALT_PLAYERCAR )
+ {
+ sprintf( previewObjects[ newSlot ].nameModel, "%s",
+ pReward->GetName() );
+
+ // 3D models for cars are not the same as the in-game ones
+ // (they use less memory than the in-game ones)
+ //
+ sprintf( previewObjects[ newSlot ].filenameModel, "%s%s.p3d",
+ PHONE_BOOTH_3DMODEL_CARS_DIR,
+ pReward->GetName() );
+ }
+ else
+ {
+ sprintf( previewObjects[ newSlot ].nameModel, "%s_h",
+ pReward->GetName() );
+
+ strncpy( previewObjects[ newSlot ].filenameModel, pReward->GetFile(),
+ sizeof( previewObjects[ newSlot ].filenameModel ) );
+ }
+ }
+
+ previewObjects[ newSlot ].isUnlocked = pReward->RewardStatus();
+ previewObjects[ newSlot ].pReward = pReward;
+
+ // return the new number of preview objects
+ //
+ return (numPreviewObjects + 1);
+}
+
+void
+IGuiScreenRewards::OnUpdate( unsigned int elapsedTime )
+{
+ switch( m_currentState )
+ {
+ case REWARDS_SCREEN_OPENING_LIGHT:
+ {
+ if( m_elapsedTime < LIGHT_OPEN_CLOSE_TRANSITION_TIME )
+ {
+ float lightOpening = m_elapsedTime / LIGHT_OPEN_CLOSE_TRANSITION_TIME;
+
+ this->SetLightOpening( lightOpening );
+ }
+ else
+ {
+ // set light fully opened
+ //
+ this->SetLightOpening( 1.0f );
+
+ m_currentState = REWARDS_SCREEN_LIGHT_OPENED;
+ }
+
+ break;
+ }
+ case REWARDS_SCREEN_LIGHT_OPENED:
+ {
+ // do nothing
+
+ break;
+ }
+ case REWARDS_SCREEN_CLOSING_LIGHT:
+ {
+ if( m_elapsedTime < LIGHT_OPEN_CLOSE_TRANSITION_TIME )
+ {
+ float lightOpening = 1.0f - m_elapsedTime / LIGHT_OPEN_CLOSE_TRANSITION_TIME;
+
+ this->SetLightOpening( lightOpening );
+ }
+ else
+ {
+ // set light fully closed
+ //
+ this->SetLightOpening( 0.0f );
+
+ m_currentState = REWARDS_SCREEN_LIGHT_CLOSED;
+ }
+
+ break;
+ }
+ case REWARDS_SCREEN_LIGHT_CLOSED:
+ {
+ this->SetLightOpening( 0.0f );
+
+ // check if loading is done yet
+ //
+ if( !m_isLoading )
+ {
+ // ok, re-open light
+ //
+ m_currentState = REWARDS_SCREEN_OPENING_LIGHT;
+ m_elapsedTime = 0.0f;
+
+ // show 3D model
+ //
+ if( m_previewWindow != NULL )
+ {
+ m_previewWindow->SetVisible( true );
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ m_elapsedTime += static_cast<float>( elapsedTime );
+}
+
+void
+IGuiScreenRewards::SetLightOpening( float amount )
+{
+ if( m_previewLightCover != NULL )
+ {
+ const float MAX_LIGHT_AMOUNT_CLOSED = 0.85f;
+ float amountClosed = (1.0f - amount) * MAX_LIGHT_AMOUNT_CLOSED;
+ amount = 1.0f - amountClosed;
+
+ m_previewLightCover->SetAlpha( amountClosed );
+ }
+}
+
+void
+IGuiScreenRewards::On3DModelSelectionChange( const PreviewObject* nextModel )
+{
+ if( nextModel != NULL )
+ {
+ // update preview object display name
+ //
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ char textBibleEntry[ sizeof( nextModel->name ) ];
+ strcpy( textBibleEntry, nextModel->name );
+ UnicodeChar* textBibleString = GetTextBibleString( strupr( textBibleEntry ) );
+ UnicodeString unicodeString;
+ if( textBibleString != NULL )
+ {
+ unicodeString.ReadUnicode( textBibleString );
+ }
+ else
+ {
+ rAssertMsg( false, "Skin/Vehicle name not found in text bible!" );
+ unicodeString.ReadAscii( nextModel->name );
+ }
+
+#ifdef PAL
+ if( m_ID == GUI_SCREEN_ID_PHONE_BOOTH &&
+ CGuiTextBible::GetCurrentLanguage() == Scrooby::XL_GERMAN )
+ {
+ if( strcmp( textBibleEntry, "BOOKB_V" ) == 0 )
+ {
+ UnicodeString str1;
+ str1.ReadAscii( "mobil" );
+
+ UnicodeString str2;
+ str2.ReadAscii( "-\nmobil" );
+
+ unicodeString.Replace( str1, str2 );
+ }
+
+ if( strcmp( textBibleEntry, "SCORP_V") == 0 )
+ {
+ UnicodeString str1;
+ str1.ReadAscii( "Auto" );
+
+ UnicodeString str2;
+ str2.ReadAscii( "\nAuto" );
+
+ unicodeString.Replace( str1, str2 );
+ }
+ }
+#endif // PAL
+
+ rAssert( m_previewName );
+ m_previewName->SetString( 0, unicodeString );
+
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+
+ // update locked/unlocked status
+ //
+ rAssert( m_lockedOverlay );
+ m_lockedOverlay->SetVisible( !nextModel->isUnlocked );
+
+ if( m_ID == GUI_SCREEN_ID_PHONE_BOOTH )
+ {
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, nextModel->isUnlocked );
+ }
+
+ // update locked level display
+ //
+ if( m_lockedLevel != NULL )
+ {
+ m_lockedLevel->SetIndex( nextModel->pReward->GetLevel() );
+ }
+
+ // update vehicle stats
+ //
+ this->UpdateVehicleStats();
+
+ if( !m_isLoading )
+ {
+ // unload current 3D model
+ //
+ this->Unload3DModel();
+
+ // load next 3D model
+ //
+ this->Load3DModel( nextModel );
+ }
+ }
+}
+
+void
+IGuiScreenRewards::Load3DModel( const PreviewObject* previewObject )
+{
+ m_isLoading = true; // set loading flag
+ m_isLoadingReward = false; // not loading reward
+
+ rAssert( previewObject != NULL );
+
+ if( m_ID == GUI_SCREEN_ID_PHONE_BOOTH )
+ {
+ char filename[ 64 ];
+
+ // load normal 2D car image
+ //
+ sprintf( filename, "%s.p3d", previewObject->filenameModel );
+ GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D,
+ filename,
+ GMA_LEVEL_OTHER,
+ REWARDS_INVENTORY_SECTION,
+ REWARDS_INVENTORY_SECTION );
+
+#ifdef LOAD_DAMAGED_VEHICLE_IMAGES
+ // load damaged 2D car image
+ //
+ sprintf( filename, "%sD.p3d", previewObject->filenameModel );
+ GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D,
+ filename,
+ GMA_LEVEL_OTHER,
+ REWARDS_INVENTORY_SECTION,
+ REWARDS_INVENTORY_SECTION );
+#endif
+ }
+ else
+ {
+ // add request to load 3D model
+ //
+ GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D,
+ previewObject->filenameModel,
+ GMA_LEVEL_MISSION,
+ REWARDS_INVENTORY_SECTION,
+ REWARDS_INVENTORY_SECTION );
+ }
+
+ GetLoadingManager()->AddCallback( this, (void*)previewObject );
+}
+
+void
+IGuiScreenRewards::Unload3DModel()
+{
+ p3d::pddi->DrawSync();
+
+ if( m_previewWindow != NULL )
+ {
+ m_previewWindow->SetDrawable( NULL );
+ m_previewWindow->SetVisible( false );
+ }
+
+ if( m_previewImage != NULL )
+ {
+ m_previewImage->SetRawSprite( NULL );
+ m_previewImage->SetVisible( false );
+ }
+
+ // remove 3D model from inventory
+ //
+ p3d::inventory->RemoveSectionElements( REWARDS_INVENTORY_SECTION );
+
+ // change current state to closing light, if not already closed
+ // or in the progress of closing
+ //
+ if( m_currentState != REWARDS_SCREEN_CLOSING_LIGHT &&
+ m_currentState != REWARDS_SCREEN_LIGHT_CLOSED )
+ {
+ if( m_currentState == REWARDS_SCREEN_OPENING_LIGHT &&
+ m_elapsedTime < LIGHT_OPEN_CLOSE_TRANSITION_TIME )
+ {
+ m_elapsedTime = LIGHT_OPEN_CLOSE_TRANSITION_TIME - m_elapsedTime;
+ }
+ else
+ {
+ m_elapsedTime = 0.0f;
+ }
+
+ m_currentState = REWARDS_SCREEN_CLOSING_LIGHT;
+ }
+}
+
+void
+IGuiScreenRewards::SetVehicleStatsVisible( bool isVisible )
+{
+ m_statsOverlayToggle = isVisible;
+
+ rAssert( m_statsOverlay );
+ m_statsOverlay->SetVisible( m_statsOverlayToggle );
+
+ rAssert( m_statsOverlayButtonLabel );
+ m_statsOverlayButtonLabel->SetIndex( m_statsOverlayToggle ? 1 : 0 );
+}
+
+void
+IGuiScreenRewards::UpdateVehicleStats()
+{
+ const PreviewObject* currentPreviewObject = this->GetCurrentPreviewObject();
+ CarAttributeRecord* carAttributes = GetRewardsManager()->GetCarAttributeRecord( const_cast<char*>( currentPreviewObject->name ) );
+ if( carAttributes != NULL )
+ {
+ m_vehicleRatings[ VEHICLE_RATING_SPEED ]->SetNumStars( carAttributes->mSpeed );
+ m_vehicleRatings[ VEHICLE_RATING_ACCELERATION ]->SetNumStars( carAttributes->mAcceleration );
+ m_vehicleRatings[ VEHICLE_RATING_TOUGHNESS ]->SetNumStars( carAttributes->mToughness );
+ m_vehicleRatings[ VEHICLE_RATING_STABILITY ]->SetNumStars( carAttributes->mStability );
+ }
+/*
+ else
+ {
+ rAssert( false );
+ rTunePrintf( "*** WARNING: No car attributes found for [%s]!\n",
+ currentPreviewObject->name );
+ }
+*/
+}
+
diff --git a/game/code/presentation/gui/ingame/guiscreenrewards.h b/game/code/presentation/gui/ingame/guiscreenrewards.h
new file mode 100644
index 0000000..0251113
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenrewards.h
@@ -0,0 +1,171 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: IGuiScreenRewards
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/21 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENREWARDS_H
+#define GUISCREENREWARDS_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+#include <loading/loadingmanager.h>
+#include <memory/srrmemory.h>
+
+#ifdef RAD_WIN32
+#define LOAD_DAMAGED_VEHICLE_IMAGES
+#endif
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class CGuiMenu;
+class Reward;
+
+struct PreviewObject
+{
+ char name[ 16 ]; // object name
+ char filename[ 64 ]; // object filename
+
+ char nameModel[ 16 ]; // model drawable name
+ char filenameModel[ 64 ]; // model filename
+
+ bool isUnlocked : 1; // unlocked flag
+ Reward* pReward; // reference to reward object
+};
+
+class PhoneBoothStars
+{
+public:
+ PhoneBoothStars( Scrooby::Page* pPage, const char* namePrefix );
+ void SetNumStars( float numStars );
+
+private:
+ static const int MAX_NUM_STARS = 5;
+ Scrooby::Sprite* m_stars[ MAX_NUM_STARS ];
+
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class IGuiScreenRewards : public CGuiScreen,
+ public LoadingManager::ProcessRequestsCallback
+{
+public:
+ IGuiScreenRewards( Scrooby::Screen* pScreen,
+ Scrooby::Page* pPage,
+ CGuiEntity* pParent,
+ eGuiWindowID windowID );
+
+ virtual ~IGuiScreenRewards();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ void OnProcessRequestsComplete( void* pUserData );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+ virtual void On3DModelLoaded( const PreviewObject* previewObject ) = 0;
+ virtual const PreviewObject* GetCurrentPreviewObject() const = 0;
+ virtual void InitMenu() = 0;
+
+ int InsertPreviewObject( PreviewObject* previewObjects,
+ int numPreviewObjects,
+ Reward* pReward,
+ bool isSorted = false );
+
+ virtual void OnUpdate( unsigned int elapsedTime );
+
+ void SetLightOpening( float amount ); // 0.0f <= amount <= 1.0f
+
+ void On3DModelSelectionChange( const PreviewObject* nextModel );
+
+ void Load3DModel( const PreviewObject* previewObject );
+ void Unload3DModel();
+
+ void SetVehicleStatsVisible( bool isVisible );
+ void UpdateVehicleStats();
+
+ static const int MAX_NUM_PREVIEW_VEHICLES = 64;
+ static const int MAX_NUM_PREVIEW_CLOTHING = 4;
+
+ CGuiMenu* m_pRewardsMenu;
+
+ enum eRewardsScreenState
+ {
+ REWARDS_SCREEN_OPENING_LIGHT,
+ REWARDS_SCREEN_LIGHT_OPENED,
+ REWARDS_SCREEN_CLOSING_LIGHT,
+ REWARDS_SCREEN_LIGHT_CLOSED,
+
+ NUM_REWARDS_SCREEN_STATES
+ };
+
+ eRewardsScreenState m_currentState;
+ float m_elapsedTime;
+
+ Scrooby::Polygon* m_previewLightCover;
+ Scrooby::Pure3dObject* m_previewWindow;
+ Scrooby::Pure3dObject* m_previewPedestal;
+ Scrooby::Pure3dObject* m_previewBgd;
+ Scrooby::Sprite* m_previewImage;
+ Scrooby::Text* m_previewName;
+
+ // list of garage vehicles
+ //
+ PreviewObject m_previewVehicles[ MAX_NUM_PREVIEW_VEHICLES ];
+ int m_numPreviewVehicles;
+ int m_currentPreviewVehicle;
+
+ // list of character skins
+ //
+ PreviewObject m_previewClothing[ MAX_NUM_PREVIEW_CLOTHING ];
+ int m_numPreviewClothing;
+ int m_currentPreviewClothing;
+
+ bool m_isLoading : 1;
+ bool m_isLoadingReward : 1;
+
+ Scrooby::Group* m_lockedOverlay;
+ Scrooby::Text* m_lockedLevel;
+ Scrooby::Text* m_rewardPrice;
+
+ Scrooby::Group* m_statsOverlay;
+ Scrooby::Group* m_statsOverlayButton;
+ Scrooby::Text* m_statsOverlayButtonLabel;
+ bool m_statsOverlayToggle;
+
+ enum eVehicleRatingType
+ {
+ VEHICLE_RATING_SPEED,
+ VEHICLE_RATING_ACCELERATION,
+ VEHICLE_RATING_TOUGHNESS,
+ VEHICLE_RATING_STABILITY,
+
+ NUM_VEHICLE_RATINGS
+ };
+
+ PhoneBoothStars* m_vehicleRatings[ NUM_VEHICLE_RATINGS ];
+
+};
+
+#endif // GUISCREENREWARDS_H
diff --git a/game/code/presentation/gui/ingame/guiscreensavegame.cpp b/game/code/presentation/gui/ingame/guiscreensavegame.cpp
new file mode 100644
index 0000000..48dd64a
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreensavegame.cpp
@@ -0,0 +1,1011 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenSaveGame
+//
+// Description: Implementation of the CGuiScreenSaveGame class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/04 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreensavegame.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/gui/guiscreenmessage.h>
+#include <presentation/gui/guiscreenprompt.h>
+
+#include <data/gamedatamanager.h>
+#include <data/savegameinfo.h>
+#include <data/memcard/memorycardmanager.h>
+#include <memory/srrmemory.h>
+#include <gameflow/gameflow.h>
+
+#include <raddebug.hpp> // Foundation
+#include <group.h>
+#include <layer.h>
+#include <page.h>
+#include <screen.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+#ifdef RAD_XBOX
+extern char gGameFileName[NUM_GAME_SLOTS][radFileFilenameMax+1];
+#endif
+//===========================================================================
+// CGuiScreenSaveGame::CGuiScreenSaveGame
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenSaveGame::CGuiScreenSaveGame
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+:
+ CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_SAVE_GAME ),
+ CGuiScreenLoadSave( pScreen ),
+ m_pMenu( NULL ),
+ m_pFullText( NULL ),
+ m_StatusPromptShown(false),
+ m_nonEmptySlots( 0 )
+{
+MEMTRACK_PUSH_GROUP( "CGUIScreenSaveGame" );
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "GameSlots" );
+ rAssert( pPage );
+
+ Scrooby::Group* menu = pPage->GetGroup( "Menu" );
+ rAssert( menu != NULL );
+
+ m_pFullText = pPage->GetText( "FullMessage" );
+ rAssert( m_pFullText != NULL );
+ m_pFullText->SetVisible(false);
+ m_pFullText->SetTextMode( Scrooby::TEXT_WRAP );
+ // Create a menu.
+ //
+ m_pMenu = new(GMA_LEVEL_HUD) CGuiMenu( this, NUM_GAME_SLOTS );
+ rAssert( m_pMenu != NULL );
+
+ // Add menu items
+ //
+ for( unsigned int i = 0; i < NUM_GAME_SLOTS; i++ )
+ {
+ char objectName[ 32 ];
+ sprintf( objectName, "Slot%d", i );
+
+ m_pMenu->AddMenuItem( menu->GetText( objectName ) );
+ }
+
+#ifdef RAD_WIN32
+ Scrooby::Text* pText = pPage->GetText( "LoadSaveMessage" );
+ if( pText != NULL )
+ {
+ pText->SetIndex( 1 );
+ }
+#else
+ pPage = m_pScroobyScreen->GetPage( "SelectMemoryDevice" );
+ rAssert( pPage != NULL );
+ Scrooby::Layer* foreground = pPage->GetLayer( "Foreground" );
+ rAssert( foreground != NULL );
+
+ Scrooby::Text* pText = foreground->GetText( "LoadSave" );
+ if( pText != NULL )
+ {
+ pText->SetIndex( 1 );
+ }
+#endif
+
+ this->AutoScaleFrame( m_pScroobyScreen->GetPage( "BigBoard" ) );
+MEMTRACK_POP_GROUP("CGUIScreenSaveGame");
+}
+
+
+//===========================================================================
+// CGuiScreenSaveGame::~CGuiScreenSaveGame
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenSaveGame::~CGuiScreenSaveGame()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenSaveGame::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSaveGame::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if (message == GUI_MSG_MESSAGE_UPDATE)
+ {
+ if (m_formatState)
+ {
+ m_elapsedFormatTime += param1;
+ if (m_elapsedFormatTime > m_minimumFormatTime && m_formatDone)
+ {
+ m_StatusPromptShown = true;
+ m_formatState = false;
+
+ if( m_formatResult == Success )
+ {
+#ifdef RAD_PS2
+ m_currentSlot = 0; // on ps2 continue to save
+ this->SaveGame();
+#else
+ m_guiManager->DisplayPrompt(PROMPT_FORMAT_SUCCESS_GC + PLATFORM_TEXT_INDEX, this, PROMPT_TYPE_CONTINUE); // format success
+#endif
+ }
+ else
+ {
+ m_guiManager->DisplayPrompt(PROMPT_FORMAT_FAIL_GC + PLATFORM_TEXT_INDEX, this, PROMPT_TYPE_CONTINUE); // format fail
+ }
+ }
+ }
+ }
+ else if (message == GUI_MSG_PROMPT_UPDATE)
+ {
+ GetMemoryCardManager()->Update( param1 ); // update so we know the status
+
+ if (m_StatusPromptShown==false) { // check for user unplugging memcard if not showing status
+ int current_drive = GetMemoryCardManager()->GetCurrentDriveIndex();
+
+ if( !GetMemoryCardManager()->IsCurrentDrivePresent(current_drive) )
+ ReloadScreen();
+ }
+ }
+ else if( message == GUI_MSG_ON_DISPLAY_MESSAGE )
+ {
+ if( m_operation == SAVE )
+ {
+ // start the save game process
+ //
+ rAssert( m_currentSlot != -1 );
+#ifdef RAD_XBOX
+ // has existing filename
+ radFileError err = Success;
+ if (gGameFileName[m_currentSlot][0]!=0) // delete existing file if overwriting (on xbox each filename is unique)
+ {
+ err = GetGameDataManager()->DeleteGame(gGameFileName[m_currentSlot]);
+ }
+ if (err!=Success)
+ OnSaveGameComplete(err);
+ else
+ GetGameDataManager()->SaveGame( m_currentSlot, this );
+#else
+ GetGameDataManager()->SaveGame( m_currentSlot, this );
+#endif
+ }
+ else if( m_operation == DELETE_GAME )
+ {
+ // get the filename
+ char filename[ radFileFilenameMax + 1 ];
+#ifdef RAD_XBOX
+ strcpy(filename, gGameFileName[m_currentSlot]);
+#else
+ GetGameDataManager()->FormatSavedGameFilename( filename,
+ sizeof( filename ),
+ m_currentSlot );
+#endif
+ radFileError err = GetGameDataManager()->DeleteGame( filename, true, this );
+ }
+ else
+ {
+ FormatCurrentDrive();
+ }
+ }
+ else if ( message==GUI_MSG_PROMPT_START_RESPONSE )
+ {
+ m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME );
+ }
+ else if (message == GUI_MSG_ERROR_PROMPT_RESPONSE )
+ {
+ this->HandleErrorResponse( static_cast<CGuiMenuPrompt::ePromptResponse>( param2 ) );
+ }
+ else if( message == GUI_MSG_MENU_PROMPT_RESPONSE )
+ {
+ switch( param1 )
+ {
+
+ case PROMPT_FORMAT_CONFIRM_GC:
+ case PROMPT_FORMAT_CONFIRM_PS2:
+ case PROMPT_FORMAT_CONFIRM_XBOX: // do you really want to format
+ {
+ if (param2==CGuiMenuPrompt::RESPONSE_YES)
+ m_guiManager->DisplayPrompt(PROMPT_FORMAT_CONFIRM2_GC + PLATFORM_TEXT_INDEX,this);
+ else
+ {
+ this->GotoMemoryCardScreen( true );
+ }
+ break;
+ }
+ case PROMPT_FORMAT_CONFIRM2_GC:
+ case PROMPT_FORMAT_CONFIRM2_PS2:
+ case PROMPT_FORMAT_CONFIRM2_XBOX: // really format
+ {
+ if (param2==CGuiMenuPrompt::RESPONSE_YES)
+ {
+ m_operation = FORMAT;
+ m_guiManager->DisplayMessage(CGuiScreenMessage::MSG_ID_FORMATTING_GC + PLATFORM_TEXT_INDEX, this);
+ }
+ else
+ {
+ this->GotoMemoryCardScreen( true );
+ }
+ break;
+ }
+ case PROMPT_LOAD_DELETE_CORRUPT_GC:
+ case PROMPT_LOAD_DELETE_CORRUPT_PS2:
+ case PROMPT_LOAD_DELETE_CORRUPT_XBOX:
+ case PROMPT_LOAD_DELETE_CORRUPT_XBOX_HD:
+ {
+ if (param2==CGuiMenuPrompt::RESPONSE_NO)
+ {
+ this->ReloadScreen();
+ }
+ else if (param2==CGuiMenuPrompt::RESPONSE_YES)
+ {
+#ifdef RAD_PS2
+ m_operation = DELETE_GAME;
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_DELETING_GC + PLATFORM_TEXT_INDEX, this );
+#else
+ // get the filename
+ char filename[ radFileFilenameMax + 1 ];
+ #ifdef RAD_XBOX
+ strcpy(filename, gGameFileName[m_currentSlot]);
+ #else
+ GetGameDataManager()->FormatSavedGameFilename( filename,
+ sizeof( filename ),
+ m_currentSlot );
+ #endif
+ radFileError err = GetGameDataManager()->DeleteGame(filename);
+ this->OnDeleteGameComplete( err );
+#endif // RAD_PS2
+ }
+ else
+ {
+ rTuneAssert(!"not reached");
+ }
+
+ break;
+ }
+
+ case PROMPT_FORMAT_SUCCESS_GC:
+ case PROMPT_FORMAT_SUCCESS_PS2:
+ case PROMPT_FORMAT_SUCCESS_XBOX: // format ok
+ {
+ // m_currentSlot = 0; on ps2 we don't come here
+ // this->SaveGame();
+ this->ReloadScreen();
+ break;
+ }
+
+ case PROMPT_FORMAT_FAIL_GC:
+ case PROMPT_FORMAT_FAIL_PS2:
+ case PROMPT_FORMAT_FAIL_XBOX: // format fail
+ {
+ GetMemoryCardManager()->ClearCurrentDrive();
+ this->GotoMemoryCardScreen( true );
+
+ break;
+ }
+
+ case PROMPT_DELETE_CORRUPT_SUCCESS_GC:
+ case PROMPT_DELETE_CORRUPT_SUCCESS_PS2:
+ case PROMPT_DELETE_CORRUPT_SUCCESS_XBOX:
+
+ case PROMPT_DELETE_CORRUPT_FAIL_GC:
+ case PROMPT_DELETE_CORRUPT_FAIL_PS2:
+ case PROMPT_DELETE_CORRUPT_FAIL_XBOX:
+ {
+ this->ReloadScreen();
+ break;
+ }
+
+ case PROMPT_SAVE_CONFIRM_OVERWRITE_GC:
+ {
+ if( param2 == CGuiMenuPrompt::RESPONSE_YES )
+ {
+ m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_GC, this, PROMPT_TYPE_SAVE );
+ }
+ else
+ {
+ rAssert( param2 == CGuiMenuPrompt::RESPONSE_NO );
+
+ this->ReloadScreen();
+ }
+
+ break;
+ }
+ case PROMPT_SAVE_CONFIRM_GC:
+ case PROMPT_SAVE_CONFIRM_PS2:
+ case PROMPT_SAVE_CONFIRM_XBOX:
+ case PROMPT_SAVE_CONFIRM_OVERWRITE_PS2:
+ case PROMPT_SAVE_CONFIRM_OVERWRITE_XBOX:
+ {
+ if( param2 == CGuiMenuPrompt::RESPONSE_YES ||
+ param2 == CGuiMenuPrompt::RESPONSE_SAVE )
+ {
+ this->SaveGame();
+ }
+ else
+ {
+ rAssert( param2 == CGuiMenuPrompt::RESPONSE_NO );
+
+ this->ReloadScreen();
+ }
+
+ break;
+ }
+
+ case PROMPT_SAVE_SUCCESSFUL:
+ {
+ m_pParent->HandleMessage( GUI_MSG_ON_SAVE_GAME_COMPLETE );
+
+ break;
+ }
+
+ default:
+ {
+ // handle normal error response, "continue", etc
+ this->HandleErrorResponse( static_cast<CGuiMenuPrompt::ePromptResponse>( param2 ) );
+
+ break;
+ }
+ }
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ if( message == GUI_MSG_CONTROLLER_SELECT &&
+ !GetMemoryCardManager()->IsMemcardInfoLoaded() )
+ {
+ // ignore user select inputs until memcard info is loaded
+ //
+ return;
+ }
+
+ switch( message )
+ {
+#ifdef RAD_PS2
+ case GUI_MSG_CONTROLLER_START:
+ {
+ if ( GetGameFlow()->GetCurrentContext() == CONTEXT_PAUSE )
+ m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME );
+
+ break;
+ }
+#endif
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ m_currentSlot = param1; // // param1 = slot
+
+ SaveGameInfo saveGameInfo;
+ bool corrupt = false;
+ IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive();
+ bool saveGameExists = GetGameDataManager()->GetSaveGameInfo( currentDrive, m_currentSlot, &saveGameInfo, &corrupt );
+
+ if (corrupt)
+ {
+ int plat_index = PLATFORM_TEXT_INDEX;
+#ifdef RAD_XBOX
+ if (GetMemoryCardManager()->GetCurrentDriveIndex()==0)
+ plat_index++;
+#endif
+#ifdef RAD_GAMECUBE
+ int errorMessage = GetErrorMessageIndex( DataCorrupt, ERROR_DURING_SAVING );
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ ERROR_RESPONSE_CONTINUE_WITHOUT_SAVE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_DELETE );
+ m_operation = SAVE;
+#else
+ m_guiManager->DisplayPrompt( PROMPT_LOAD_DELETE_CORRUPT_GC + plat_index, this );
+#endif
+ }
+ else if( (m_nonEmptySlots & (1 << m_currentSlot)) > 0 )
+ {
+ // saved game exists in current slot; prompt w/ overwrite
+ // confirmation message
+ //
+#ifdef RAD_GAMECUBE
+ m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_OVERWRITE_GC, this );
+#endif
+
+#ifdef RAD_PS2
+ m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_OVERWRITE_PS2, this );
+#endif
+
+#ifdef RAD_XBOX
+ m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_OVERWRITE_XBOX, this );
+#endif
+
+#ifdef RAD_WIN32
+ m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_OVERWRITE_XBOX, this );
+#endif
+ }
+ else
+ {
+#ifdef RAD_GAMECUBE
+ m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_GC, this, PROMPT_TYPE_SAVE );
+#endif
+
+#ifdef RAD_PS2
+ m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_PS2, this );
+#endif
+
+#ifdef RAD_XBOX
+ m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_XBOX, this );
+#endif
+
+#ifdef RAD_WIN32
+ m_guiManager->DisplayPrompt( PROMPT_SAVE_CONFIRM_XBOX, this );
+#endif
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+#ifdef RAD_XBOX
+ s_forceGotoMemoryCardScreen = true;
+ this->GotoMemoryCardScreen();
+#endif
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ if( m_pMenu != NULL )
+ {
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+
+ CGuiScreenLoadSave::HandleMessage( message, param1, param2 );
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+void
+CGuiScreenSaveGame::OnSaveGameComplete( radFileError errorCode )
+{
+ m_lastError = errorCode;
+ m_StatusPromptShown = true;
+
+ if( errorCode == Success )
+ {
+ m_guiManager->DisplayPrompt( PROMPT_SAVE_SUCCESSFUL, this, PROMPT_TYPE_CONTINUE );
+ }
+ else
+ {
+ int errorMessage = GetErrorMessageIndex( errorCode, ERROR_DURING_SAVING );
+
+#ifdef RAD_GAMECUBE
+ switch( errorCode )
+ {
+ case Success:
+ {
+ rAssert( false );
+ break;
+ }
+ case MediaCorrupt:
+ {
+ m_guiManager->DisplayErrorPrompt( errorMessage, this, ERROR_RESPONSE_CONTINUE );
+
+ break;
+ }
+ case MediaEncodingErr:
+ case MediaNotFormatted:
+ {
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_FORMAT );
+
+ }
+ default:
+ {
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ ERROR_RESPONSE_CONTINUE | ERROR_RESPONSE_RETRY );
+
+ break;
+ }
+ }
+#endif // RAD_GAMECUBE
+
+#ifdef RAD_PS2
+ switch( errorCode )
+ {
+ case Success:
+ {
+ rAssert( false );
+ break;
+ }
+ default:
+ {
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ ERROR_RESPONSE_CONTINUE );
+
+ break;
+ }
+ }
+#endif // RAD_PS2
+
+#ifdef RAD_XBOX
+ switch( errorCode )
+ {
+ case Success:
+ {
+ rAssert( false );
+ break;
+ }
+ default:
+ {
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ ERROR_RESPONSE_CONTINUE );
+
+ break;
+ }
+ }
+#endif // RAD_XBOX
+
+#ifdef RAD_WIN32
+ switch( errorCode )
+ {
+ case Success:
+ {
+ rAssert( false );
+ break;
+ }
+ default:
+ {
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ ERROR_RESPONSE_CONTINUE );
+ break;
+ }
+ }
+#endif // RAD_WIN32
+ }
+}
+
+void
+CGuiScreenSaveGame::OnDeleteGameComplete( radFileError errorCode )
+{
+ m_operation = SCREEN_OP_IDLE;
+ m_StatusPromptShown = true;
+
+ if( errorCode == Success )
+ {
+ m_guiManager->DisplayPrompt( PROMPT_DELETE_CORRUPT_SUCCESS_GC + PLATFORM_TEXT_INDEX,
+ this,
+ PROMPT_TYPE_CONTINUE );
+ }
+ else
+ {
+ m_guiManager->DisplayPrompt( PROMPT_DELETE_CORRUPT_FAIL_GC + PLATFORM_TEXT_INDEX,
+ this,
+ PROMPT_TYPE_CONTINUE );
+ }
+}
+
+void
+CGuiScreenSaveGame::HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response )
+{
+ switch( response )
+ {
+ case (CGuiMenuPrompt::RESPONSE_CONTINUE):
+ case (CGuiMenuPrompt::RESPONSE_CONTINUE_WITHOUT_SAVE):
+ {
+ if( m_operation == SAVE )
+ {
+ this->ReloadScreen();
+ }
+ else if( m_operation == FORMAT )
+ {
+ this->ReloadScreen();
+ }
+ else
+ {
+ this->GotoMemoryCardScreen( true );
+ }
+
+ break;
+ }
+ case (CGuiMenuPrompt::RESPONSE_RETRY):
+ {
+ if( m_operation == SAVE )
+ {
+#ifdef RAD_GAMECUBE
+ SaveGameInfo saveGameInfo;
+ bool corrupt = false;
+ IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive();
+ GetGameDataManager()->GetSaveGameInfo( currentDrive, m_currentSlot, &saveGameInfo, &corrupt );
+ if( corrupt )
+ {
+ int errorMessage = GetErrorMessageIndex( DataCorrupt, ERROR_DURING_SAVING );
+ m_guiManager->DisplayErrorPrompt( errorMessage, this,
+ ERROR_RESPONSE_CONTINUE_WITHOUT_SAVE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_DELETE );
+ }
+ else
+#endif
+ {
+ this->SaveGame();
+ }
+ }
+ else if( m_operation == FORMAT )
+ {
+ m_guiManager->DisplayMessage(CGuiScreenMessage::MSG_ID_FORMATTING_GC + PLATFORM_TEXT_INDEX, this);
+ }
+ else
+ {
+ this->ReloadScreen();
+ }
+
+ break;
+ }
+
+#ifdef RAD_GAMECUBE
+ case (CGuiMenuPrompt::RESPONSE_DELETE):
+ {
+ m_guiManager->DisplayPrompt( PROMPT_LOAD_DELETE_CORRUPT_GC, this );
+
+ break;
+ }
+#endif // RAD_GAMECUBE
+
+ case (CGuiMenuPrompt::RESPONSE_FORMAT_GC):
+ case (CGuiMenuPrompt::RESPONSE_FORMAT_XBOX):
+ case (CGuiMenuPrompt::RESPONSE_FORMAT_PS2):
+ {
+ m_guiManager->DisplayPrompt(PROMPT_FORMAT_CONFIRM2_GC + PLATFORM_TEXT_INDEX,this);
+ break;
+ }
+ default:
+ {
+ rTunePrintf( "*** WARNING: Unhandled response for error [%d]!\n", m_lastError );
+ rAssert( false );
+
+ this->ReloadScreen();
+
+ break;
+ }
+ }
+
+ CGuiScreenLoadSave::HandleErrorResponse( response );
+}
+
+
+//===========================================================================
+// CGuiScreenSaveGame::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSaveGame::InitIntro()
+{
+ unsigned int num_empty_slots = 0;
+ bool unformatted = false;
+ IRadDrive::MediaInfo::MediaState mediaState;
+
+ m_StatusPromptShown = false;
+ m_operation = SCREEN_OP_IDLE;
+
+ if( s_forceGotoMemoryCardScreen || !GetMemoryCardManager()->IsCurrentDriveReady( true, &unformatted, &mediaState ))
+ {
+ if (unformatted && !s_forceGotoMemoryCardScreen)
+ {
+#ifdef RAD_GAMECUBE
+ int errorMessage;
+
+ errorMessage = GetErrorMessageIndex( mediaState );
+ m_guiManager->DisplayErrorPrompt( errorMessage,
+ this,
+ ERROR_RESPONSE_CONTINUE_WITHOUT_SAVE | ERROR_RESPONSE_RETRY | ERROR_RESPONSE_FORMAT );
+#else
+ m_guiManager->DisplayPrompt(PROMPT_FORMAT_CONFIRM_GC+PLATFORM_TEXT_INDEX,this);
+#endif
+ m_numTransitionsPending = -1; // disable all transitions
+ }
+ else
+ {
+ this->GotoMemoryCardScreen();
+ m_numTransitionsPending = -1; // disable all transitions
+ }
+ return;
+ }
+
+ m_nonEmptySlots = 0; // reset non-empty slots bitmask
+
+ this->UpdateCurrentMemoryDevice();
+
+ rAssert( m_pMenu );
+ m_pMenu->Reset();
+
+ IRadDrive* currentDrive = GetMemoryCardManager()->GetCurrentDrive();
+
+ int currentDriveIndex = GetMemoryCardManager()->GetCurrentDriveIndex();
+ bool enoughFreeSpace = GetMemoryCardManager()->EnoughFreeSpace( currentDriveIndex );
+
+ radDate mostRecentTimestamp;
+ mostRecentTimestamp.m_Year = 0;
+
+ // update all save game slots display info
+ //
+ for( unsigned int i = 0; i < NUM_GAME_SLOTS; i++ )
+ {
+ SaveGameInfo saveGameInfo;
+ bool corrupt;
+ bool saveGameExists = GetGameDataManager()->GetSaveGameInfo( currentDrive, i, &saveGameInfo, &corrupt );
+// saveGameExists = saveGameExists && saveGameInfo.CheckData();
+
+ Scrooby::Text* slotText = dynamic_cast<Scrooby::Text*>( m_pMenu->GetMenuItem( i )->GetItem() );
+ rAssert( slotText != NULL );
+
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+#ifdef RAD_XBOX
+ gGameFileName[i][0] = 0;
+#endif
+ if( saveGameExists )
+ {
+ if (corrupt)
+ {
+ UnicodeString corruptSlot;
+#ifdef RAD_XBOX
+ corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(XBOX)" ) );
+#endif
+#ifdef RAD_WIN32
+ corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(XBOX)" ) );
+#endif
+#ifdef RAD_PS2
+ corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(PS2)" ) );
+#endif
+#ifdef RAD_GAMECUBE
+ corruptSlot.ReadUnicode( GetTextBibleString( "CORRUPT_SLOT_(GC)" ) );
+#endif
+ slotText->SetString(0,corruptSlot);
+#ifdef RAD_XBOX
+ strcpy(gGameFileName[i], saveGameInfo.m_displayFilename); // cache filename in the slot
+#endif
+ }
+ else
+ {
+ slotText->SetString( 0, saveGameInfo.m_displayFilename );
+ #ifdef RAD_XBOX
+ strcpy(gGameFileName[i], saveGameInfo.m_displayFilename); // cache filename in the slot
+ #endif
+ }
+
+ // default to slot with most recent saved game file
+ //
+ const SaveGameInfoData* pData = saveGameInfo.GetData();
+ rAssert( pData != NULL );
+ if( SaveGameInfo::CompareTimeStamps( pData->m_timeStamp, mostRecentTimestamp ) > 0 )
+ {
+ memcpy( &mostRecentTimestamp, &pData->m_timeStamp, sizeof( radDate ) );
+
+ m_pMenu->Reset( i );
+ }
+
+ // update non-empty slots bitmask
+ //
+ m_nonEmptySlots |= (1 << i);
+ }
+ else
+ {
+ UnicodeString emptySlot;
+ if (enoughFreeSpace)
+ emptySlot.ReadUnicode( GetTextBibleString( "EMPTY_SLOT" ) );
+ else
+ emptySlot.ReadUnicode( GetTextBibleString( "FULL_SLOT" ) );
+
+#ifdef RAD_XBOX
+ if (num_empty_slots) // blank out extra empty slot item
+ emptySlot.ReadUnicode( GetTextBibleString ("SPACE") );
+#endif
+ slotText->SetString( 0, emptySlot );
+ num_empty_slots++;
+ }
+ HeapMgr()->PopHeap(GMA_LEVEL_HUD);
+
+ // enable slot selection only if save game exists or there's enough
+ // free space to save a new game
+ //
+ m_pMenu->SetMenuItemEnabled( i, saveGameExists || enoughFreeSpace );
+#ifdef RAD_XBOX
+ if (num_empty_slots > 1) // disable extra empty slot for xbox
+ m_pMenu->SetMenuItemEnabled( i, false );
+#endif
+ }
+
+ /* display/hide full message */
+ if (!enoughFreeSpace)
+ {
+ int message_index = 0; // no existing slot
+ if (num_empty_slots < NUM_GAME_SLOTS )
+ message_index = 1; // has existing slot
+ // we have 2 group of per platform messages, gc,ps2,xbox_mu, xbox_hd
+ message_index = message_index * 4 + PLATFORM_TEXT_INDEX;
+#ifdef RAD_XBOX
+ if (currentDriveIndex==0)
+ {
+ message_index++; // xbox hard disk
+ }
+#endif
+#ifdef RAD_WIN32
+ message_index = 9;
+#endif
+ m_pFullText->SetIndex(message_index);
+ m_pFullText->SetVisible(true);
+
+#ifdef RAD_GAMECUBE
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ // append "Use Memory Card Screen" text to message; this is done in
+ // code because the text bible compiler can't handle strings with
+ // more than 255 characters
+ //
+ UnicodeString useMemCardScreen;
+ useMemCardScreen.ReadUnicode( GetTextBibleString( "USE_MEMORY_CARD_SCREEN" ) );
+
+ UnicodeString newString;
+ newString.ReadUnicode( GetTextBibleString( "MEMCARD_FULL_HAS_EXISTING_(GC)" ) );
+ newString.Append( ' ' );
+ newString += useMemCardScreen;
+
+ m_pFullText->SetString( message_index, newString );
+
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+#endif // RAD_GAMECUBE
+ }
+ else
+ {
+ m_pFullText->SetVisible(false);
+ }
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, m_pMenu->GetSelection() != -1 );
+}
+
+
+//===========================================================================
+// CGuiScreenSaveGame::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSaveGame::InitRunning()
+{
+// rAssertMsg( GetMemoryCardManager()->IsMemcardInfoLoaded(),
+// "WARNING: *** Memory card info not loaded yet!" );
+}
+
+
+//===========================================================================
+// CGuiScreenSaveGame::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenSaveGame::InitOutro()
+{
+}
+
+
+void
+CGuiScreenSaveGame::GotoMemoryCardScreen( bool isFromPrompt )
+{
+#ifdef RAD_WIN32
+ m_pParent->HandleMessage( GUI_MSG_BACK_SCREEN );
+#else
+ if( isFromPrompt )
+ {
+ s_forceGotoMemoryCardScreen = true;
+ this->ReloadScreen();
+ }
+ else
+ {
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MEMORY_CARD );
+ }
+#endif // RAD_WIN32
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenSaveGame::SaveGame()
+{
+ m_operation = SAVE;
+
+#ifdef RAD_GAMECUBE
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_SAVING_GAME_GC, this );
+#endif
+
+#ifdef RAD_PS2
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_SAVING_GAME_PS2, this );
+#endif
+
+#ifdef RAD_XBOX
+ if( m_currentDriveIndex == 0 ) // xbox hard disk
+ {
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_SAVING_GAME_XBOX_HD, this );
+ }
+ else // xbox memory unit
+ {
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_SAVING_GAME_XBOX, this );
+ }
+#endif
+
+#ifdef RAD_WIN32
+ m_guiManager->DisplayMessage( CGuiScreenMessage::MSG_ID_SAVING_GAME_PC, this );
+#endif
+}
+
diff --git a/game/code/presentation/gui/ingame/guiscreensavegame.h b/game/code/presentation/gui/ingame/guiscreensavegame.h
new file mode 100644
index 0000000..361b21f
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreensavegame.h
@@ -0,0 +1,72 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenSaveGame
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/30 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENSAVEGAME_H
+#define GUISCREENSAVEGAME_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <presentation/gui/guiscreenmemorycard.h>
+#include <data/gamedatamanager.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+class CGuiMenu;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenSaveGame : public CGuiScreen,
+ public CGuiScreenLoadSave,
+ public GameDataSaveCallback,
+ public GameDataDeleteCallback
+{
+public:
+ CGuiScreenSaveGame( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenSaveGame();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ // Implements GameDataSaveCallback and GameDataDeleteCallback
+ //
+ virtual void OnSaveGameComplete( radFileError errorCode );
+ virtual void OnDeleteGameComplete( radFileError errorCode );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+ void GotoMemoryCardScreen( bool isFromPrompt = false );
+ void HandleErrorResponse( CGuiMenuPrompt::ePromptResponse response );
+
+private:
+ void SaveGame();
+
+ CGuiMenu* m_pMenu;
+ Scrooby::Text* m_pFullText;
+ bool m_StatusPromptShown;
+ unsigned short m_nonEmptySlots;
+
+};
+
+#endif // GUISCREENSAVEGAME_H
diff --git a/game/code/presentation/gui/ingame/guiscreentutorial.cpp b/game/code/presentation/gui/ingame/guiscreentutorial.cpp
new file mode 100644
index 0000000..7ff9536
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreentutorial.cpp
@@ -0,0 +1,373 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenTutorial
+//
+// Description: Implementation of the CGuiScreenTutorial class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/04/15 TChu Created
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreentutorial.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/gui/utility/specialfx.h>
+
+#include <presentation/tutorialmanager.h>
+
+#include <events/eventmanager.h>
+#include <main/commandlineoptions.h>
+#include <sound/soundmanager.h>
+
+// Scrooby
+#include <screen.h>
+#include <page.h>
+#include <layer.h>
+#include <group.h>
+#include <sprite.h>
+
+// ATG
+#include <raddebug.hpp>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+#define WAIT_UNTIL_DIALOG_DONE
+
+const float BART_ICON_CORRECTION_SCALE = 1.0f;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenTutorial::CGuiScreenTutorial
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenTutorial::CGuiScreenTutorial
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_TUTORIAL, SCREEN_FX_ZOOM ),
+ m_tutorialMessage( NULL ),
+ m_bartsHead( NULL ),
+ m_disableTutorial( NULL ),
+ m_elapsedDialogTime( 0 )
+{
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "Tutorial" );
+ rAssert( pPage != NULL );
+
+ Scrooby::Group* iconAndMessage = pPage->GetGroup( "IconAndMessage" );
+ rAssert( iconAndMessage != NULL );
+
+ m_bartsHead = iconAndMessage->GetSprite( "BartIcon" );
+
+ m_tutorialMessage = iconAndMessage->GetSprite( "TutorialMessage" );
+ rAssert( m_tutorialMessage != NULL );
+ m_tutorialMessage->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT );
+ m_tutorialMessage->CreateBitmapTextBuffer( MAX_TUTORIAL_MESSAGE_LENGTH );
+#ifdef RAD_WIN32
+ m_tutorialMessage->ScaleAboutCenter( 0.25f );
+#else
+ m_tutorialMessage->ScaleAboutCenter( 0.5f );
+#endif
+
+#ifdef PAL
+ iconAndMessage->ResetTransformation();
+ iconAndMessage->Translate( 0, 15 );
+#endif // PAL
+
+ m_disableTutorial = pPage->GetGroup( "DisableTutorial" );
+ rAssert( m_disableTutorial != NULL );
+
+ Scrooby::Text* disableTutorial = m_disableTutorial->GetText( "DisableTutorial" );
+ if( disableTutorial != NULL )
+ {
+ disableTutorial->SetDisplayOutline( true );
+ disableTutorial->SetTextMode( Scrooby::TEXT_WRAP );
+ }
+
+ Scrooby::Page* pPageSmallBoard = m_pScroobyScreen->GetPage( "SmallBoard" );
+ if( pPageSmallBoard != NULL )
+ {
+ this->AutoScaleFrame( pPageSmallBoard );
+
+#ifdef PAL
+ Scrooby::Group* frame = pPageSmallBoard->GetGroup( "Frame" );
+ if( frame != NULL )
+ {
+ frame->ResetTransformation();
+ frame->ScaleAboutCenter( 1.0f, 1.2f, 1.0f );
+ }
+#endif // PAL
+ }
+
+/*
+ // get continue icon button
+ //
+ pPage = m_pScroobyScreen->GetPage( "Continue" );
+ if( pPage != NULL )
+ {
+ m_buttonIcons[ BUTTON_ICON_ACCEPT ] = pPage->GetGroup( "Continue" );
+ rAssert( m_buttonIcons[ BUTTON_ICON_ACCEPT ] != NULL );
+ }
+*/
+}
+
+//===========================================================================
+// CGuiScreenTutorial::~CGuiScreenTutorial
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenTutorial::~CGuiScreenTutorial()
+{
+}
+
+//===========================================================================
+// CGuiScreenTutorial::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenTutorial::HandleMessage( eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2 )
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ // pulse bart's head
+ //
+ m_elapsedDialogTime += param1;
+
+ float currentScale = GuiSFX::Pulse( (float)m_elapsedDialogTime,
+ 600.0f,
+ BART_ICON_CORRECTION_SCALE,
+ 0.1f );
+
+ rAssert( m_bartsHead != NULL );
+ m_bartsHead->ResetTransformation();
+ m_bartsHead->ScaleAboutCenter( currentScale );
+
+#ifdef WAIT_UNTIL_DIALOG_DONE
+/*
+ #ifndef FINAL
+ if( m_elapsedDialogTime > MAX_TUTORIAL_DIALOG_TIME )
+ {
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, true );
+
+ rAssert( m_disableTutorial != NULL );
+ m_disableTutorial->SetVisible( true );
+ }
+ else
+ #endif // !FINAL
+*/
+ {
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, !GetTutorialManager()->IsDialogPlaying() );
+
+// rAssert( m_disableTutorial != NULL );
+// m_disableTutorial->SetVisible( !GetTutorialManager()->IsDialogPlaying() );
+ }
+#endif // WAIT_UNTIL_DIALOG_DONE
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_AUX_X:
+ {
+ rAssert( m_disableTutorial != NULL );
+ if( m_disableTutorial->IsVisible() )
+ {
+ // disable tutorial events
+ //
+ GetTutorialManager()->EnableTutorialEvents( false );
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK ); // sound effect
+
+ if( GetTutorialManager()->IsDialogPlaying() &&
+ !CommandLineOptions::Get( CLO_MUTE ) )
+ {
+ // if dialog is still playing, stop it!
+ // (unless all sounds are muted)
+ //
+ GetEventManager()->TriggerEvent( EVENT_CONVERSATION_SKIP );
+ }
+
+ m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME );
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+#ifdef WAIT_UNTIL_DIALOG_DONE
+ if( !this->IsButtonVisible( BUTTON_ICON_ACCEPT ) )
+ {
+ // ignore input
+ //
+ return;
+ }
+#endif
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT ); // sound effect
+
+ m_pParent->HandleMessage( GUI_MSG_RESUME_INGAME );
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_START:
+ {
+ // only pause if dialog is still playing
+ //
+ if( GetTutorialManager()->IsDialogPlaying() )
+ {
+ m_pParent->HandleMessage( GUI_MSG_PAUSE_INGAME );
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+//===========================================================================
+// CGuiScreenTutorial::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenTutorial::InitIntro()
+{
+ int index = GetTutorialManager()->GetCurrentEventID();
+
+ char textBibleID[ 32 ];
+ sprintf( textBibleID, "TUTORIAL_%03d", index );
+ P3D_UNICODE* text = GetTextBibleString( textBibleID );
+
+ // check for platform-specific text; if found, override default text
+ //
+#ifdef RAD_GAMECUBE
+ strcat( textBibleID, "_(GC)" );
+#endif
+#ifdef RAD_PS2
+ strcat( textBibleID, "_(PS2)" );
+#endif
+#ifdef RAD_XBOX
+ strcat( textBibleID, "_(XBOX)" );
+#endif
+ P3D_UNICODE* platformText = GetTextBibleString( textBibleID );
+ if( platformText != NULL )
+ {
+ text = platformText;
+
+ rTunePrintf( "Replacing default tutorial text with entry: %s\n", textBibleID );
+ }
+
+ rAssert( m_tutorialMessage != NULL );
+ m_tutorialMessage->SetBitmapText( text );
+
+#ifdef WAIT_UNTIL_DIALOG_DONE
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, false ); // hide by default
+
+// rAssert( m_disableTutorial != NULL );
+// m_disableTutorial->SetVisible( false ); // hide by default
+
+ rAssert( m_bartsHead != NULL );
+ m_bartsHead->ResetTransformation();
+ m_bartsHead->ScaleAboutCenter( BART_ICON_CORRECTION_SCALE );
+
+ m_elapsedDialogTime = 0;
+#endif
+
+ //
+ // Inform the sound manager that it's time to turn the sound down a bit
+ //
+ GetSoundManager()->OnMissionBriefingStart();
+}
+
+//===========================================================================
+// CGuiScreenTutorial::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenTutorial::InitRunning()
+{
+}
+
+//===========================================================================
+// CGuiScreenTutorial::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenTutorial::InitOutro()
+{
+ //
+ // Turn the sound back up
+ //
+ GetSoundManager()->OnMissionBriefingEnd();
+}
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/ingame/guiscreentutorial.h b/game/code/presentation/gui/ingame/guiscreentutorial.h
new file mode 100644
index 0000000..ad13bc4
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreentutorial.h
@@ -0,0 +1,58 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenTutorial
+//
+// Description:
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/04/15 TChu Created
+//
+//===========================================================================
+
+#ifndef GUISCREENTUTORIAL_H
+#define GUISCREENTUTORIAL_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenTutorial : public CGuiScreen
+{
+public:
+ CGuiScreenTutorial( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenTutorial();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ void SetTutorialMessage( int index );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+ static const int MAX_TUTORIAL_MESSAGE_LENGTH = 256;
+ Scrooby::Sprite* m_tutorialMessage;
+ Scrooby::Sprite* m_bartsHead;
+ Scrooby::Group* m_disableTutorial;
+
+ static const unsigned int MAX_TUTORIAL_DIALOG_TIME = 10000; // in msec
+ unsigned int m_elapsedDialogTime;
+
+};
+
+
+#endif // GUISCREENTUTORIAL_H
diff --git a/game/code/presentation/gui/ingame/guiscreenviewcards.cpp b/game/code/presentation/gui/ingame/guiscreenviewcards.cpp
new file mode 100644
index 0000000..be6bef2
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenviewcards.cpp
@@ -0,0 +1,213 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenViewCards
+//
+// Description: Implementation of the CGuiScreenViewCards class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/10 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/guiscreenviewcards.h>
+
+#include <memory/srrmemory.h>
+#include <mission/gameplaymanager.h>
+
+// Scrooby
+//
+#include <screen.h>
+#include <page.h>
+#include <layer.h>
+
+// ATG
+//
+#include <raddebug.hpp>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenViewCards::CGuiScreenViewCards
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenViewCards::CGuiScreenViewCards
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreenCardGallery( pScreen, pParent, GUI_SCREEN_ID_VIEW_CARDS ),
+ m_pauseFgdLayer( NULL ),
+ m_bigBoardFgdLayer( NULL )
+{
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "PauseFgd" );
+ if( pPage != NULL )
+ {
+ m_pauseFgdLayer = pPage->GetLayerByIndex( 0 );
+ }
+
+ pPage = m_pScroobyScreen->GetPage( "BigBoard" );
+ if( pPage != NULL )
+ {
+ m_bigBoardFgdLayer = pPage->GetLayerByIndex( 0 );
+ }
+
+#ifndef RAD_WIN32
+ m_cardScaleLarge = (1.0f / m_cardScaleSmall) * 0.8f;
+ m_cardScaleSmall = 1.0f;
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenViewCards::~CGuiScreenViewCards
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenViewCards::~CGuiScreenViewCards()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenViewCards::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenViewCards::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ if( m_pauseFgdLayer != NULL )
+ {
+ m_pauseFgdLayer->SetVisible( m_cardGalleryState == STATE_BROWSING_CARDS );
+ }
+
+ if( m_bigBoardFgdLayer != NULL )
+ {
+ m_bigBoardFgdLayer->SetVisible( m_cardGalleryState == STATE_BROWSING_CARDS );
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_START:
+ {
+ if( !m_pMenu->HasSelectionBeenMade() && m_cardGalleryState == STATE_BROWSING_CARDS )
+ {
+ // resume game
+ m_pParent->HandleMessage( GUI_MSG_UNPAUSE_INGAME );
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreenCardGallery::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenViewCards::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenViewCards::InitIntro()
+{
+ this->UpdateCards( GetGameplayManager()->GetCurrentLevelIndex() );
+}
+
+
+//===========================================================================
+// CGuiScreenViewCards::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenViewCards::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenViewCards::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenViewCards::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/ingame/guiscreenviewcards.h b/game/code/presentation/gui/ingame/guiscreenviewcards.h
new file mode 100644
index 0000000..b70e8ca
--- /dev/null
+++ b/game/code/presentation/gui/ingame/guiscreenviewcards.h
@@ -0,0 +1,52 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenViewCards
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/10 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENVIEWCARDS_H
+#define GUISCREENVIEWCARDS_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/frontend/guiscreencardgallery.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenViewCards : public CGuiScreenCardGallery
+{
+public:
+ CGuiScreenViewCards( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenViewCards();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ Scrooby::Layer* m_pauseFgdLayer;
+ Scrooby::Layer* m_bigBoardFgdLayer;
+
+};
+
+#endif // GUISCREENVIEWCARDS_H
diff --git a/game/code/presentation/gui/ingame/hudevents/allhudevents.cpp b/game/code/presentation/gui/ingame/hudevents/allhudevents.cpp
new file mode 100644
index 0000000..7a3724f
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/allhudevents.cpp
@@ -0,0 +1,9 @@
+#include <presentation/gui/ingame/hudevents/hudeventhandler.cpp>
+#include <presentation/gui/ingame/hudevents/hudcardcollected.cpp>
+#include <presentation/gui/ingame/hudevents/hudcoincollected.cpp>
+#include <presentation/gui/ingame/hudevents/hudmissionprogress.cpp>
+#include <presentation/gui/ingame/hudevents/hudmissionobjective.cpp>
+#include <presentation/gui/ingame/hudevents/hudcountdown.cpp>
+#include <presentation/gui/ingame/hudevents/hudhitnrun.cpp>
+#include <presentation/gui/ingame/hudevents/hudwaspdestroyed.cpp>
+#include <presentation/gui/ingame/hudevents/huditemdropped.cpp>
diff --git a/game/code/presentation/gui/ingame/hudevents/hudcardcollected.cpp b/game/code/presentation/gui/ingame/hudevents/hudcardcollected.cpp
new file mode 100644
index 0000000..00d801d
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudcardcollected.cpp
@@ -0,0 +1,429 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudCardCollected
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudcardcollected.h>
+#include <presentation/gui/utility/specialfx.h>
+
+#include <cards/cardgallery.h>
+#include <mission/gameplaymanager.h>
+
+// Scrooby
+#include <app.h>
+#include <page.h>
+#include <group.h>
+#include <sprite.h>
+#include <text.h>
+
+#ifdef RAD_WIN32
+const float HUDCARD_THUMBNAIL_SCALE = 0.44f;
+#endif
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+HudCardCollected::HudCardCollected( Scrooby::Page* pPage )
+: HudEventHandler( pPage->GetGroup( "ItemCollected" ) ),
+ m_currentSubState( 0 ),
+ m_cardImage( NULL ),
+ m_cardText( NULL ),
+ m_cardGet( NULL ),
+ m_cardTitle( NULL ),
+ m_itemsCount( NULL ),
+ m_numCards( NULL ),
+ m_itemsComplete( NULL ),
+ m_cardDeckComplete( NULL ),
+ m_isCardDeckComplete( false ),
+ m_itemsUnlocked( NULL )
+{
+ rAssert( pPage != NULL );
+ Scrooby::Group* itemCollected = pPage->GetGroup( "ItemCollected" );
+ rAssert( itemCollected != NULL );
+ m_cardImage = itemCollected->GetSprite( "CardCollected" );
+ rAssert( m_cardImage != NULL );
+
+ m_cardText = itemCollected->GetGroup( "CardText" );
+ rAssert( m_cardText != NULL );
+
+ m_cardGet = m_cardText->GetText( "CardGet" );
+ rAssert( m_cardGet != NULL );
+
+ m_cardTitle = m_cardText->GetText( "CardTitle" );
+ rAssert( m_cardTitle != NULL );
+ m_cardTitle->SetTextMode( Scrooby::TEXT_WRAP );
+
+ m_itemsCount = itemCollected->GetGroup( "ItemsCount" );
+ rAssert( m_itemsCount != NULL );
+
+ m_numCards = m_itemsCount->GetSprite( "ItemsCount" );
+ rAssert( m_numCards != NULL );
+ m_numCards->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT );
+ m_numCards->CreateBitmapTextBuffer( BITMAP_TEXT_BUFFER_SIZE );
+ m_numCards->SetBitmapTextSpacing( -8 );
+
+ m_itemsComplete = itemCollected->GetGroup( "ItemsComplete" );
+ rAssert( m_itemsComplete != NULL );
+
+ m_cardDeckComplete = m_itemsComplete->GetText( "ItemsComplete" );
+ rAssert( m_cardDeckComplete != NULL );
+ m_cardDeckComplete->SetTextMode( Scrooby::TEXT_WRAP );
+
+ m_itemsUnlocked = m_itemsComplete->GetText( "ItemsUnlocked" );
+ rAssert(m_itemsUnlocked != NULL );
+ m_itemsUnlocked->SetTextMode( Scrooby::TEXT_WRAP );
+}
+
+HudCardCollected::~HudCardCollected()
+{
+}
+
+void
+HudCardCollected::Start()
+{
+ this->OnStart();
+
+ m_currentSubState = STATE_CARD_TRANSITION_IN;
+
+ // restore drawable properties
+ //
+ rAssert( m_cardImage != NULL );
+ m_cardImage->ResetTransformation();
+ m_cardImage->SetAlpha( 1.0f );
+
+ rAssert( m_cardText != NULL );
+ m_cardText->ResetTransformation();
+ m_cardText->SetAlpha( 1.0f );
+
+ rAssert( m_itemsCount != NULL );
+ m_itemsCount->ResetTransformation();
+ m_itemsCount->SetAlpha( 1.0f );
+
+ rAssert( m_itemsComplete != NULL );
+ m_itemsComplete->ResetTransformation();
+ m_itemsComplete->SetAlpha( 1.0f );
+ m_itemsComplete->SetVisible( false );
+
+ // show all the cards sub-groups
+ //
+ m_cardImage->SetVisible( true );
+ m_cardText->SetVisible( true );
+
+ // update card count
+ //
+ int currentLevel = GetGameplayManager()->GetCurrentLevelIndex();
+ const CardList* cardList = GetCardGallery()->GetCollectedCards( currentLevel );
+ rAssert( cardList != NULL );
+ this->SetCardCount( cardList->m_numCards, NUM_CARDS_PER_LEVEL );
+}
+
+void
+HudCardCollected::Stop()
+{
+ this->OnStop();
+}
+
+void
+HudCardCollected::Update( float elapsedTime )
+{
+ if( m_currentState == STATE_RUNNING )
+ {
+ m_elapsedTime += elapsedTime;
+
+ switch( m_currentSubState )
+ {
+ case STATE_CARD_TRANSITION_IN:
+ {
+ const float CARD_TRANSITION_IN_TIME = 500.0f;
+
+ const float centerX = Scrooby::App::GetInstance()->GetScreenWidth() / 2.0f;
+ const float centerY = Scrooby::App::GetInstance()->GetScreenHeight() / 2.0f;
+
+ rAssert( m_cardImage != NULL );
+ m_cardImage->ResetTransformation();
+
+ int cardCenterX = 0;
+ int cardCenterY = 0;
+ m_cardImage->GetBoundingBoxCenter( cardCenterX, cardCenterY );
+
+ rAssert( m_cardText != NULL );
+ m_cardText->ResetTransformation();
+
+ rAssert( m_itemsCount != NULL );
+
+ if( m_elapsedTime < CARD_TRANSITION_IN_TIME )
+ {
+ float percentageDone = m_elapsedTime / CARD_TRANSITION_IN_TIME;
+
+ // fade in card image (and scale up)
+ //
+ m_cardImage->SetAlpha( percentageDone );
+#ifdef RAD_WIN32
+ m_cardImage->ScaleAboutCenter( percentageDone * HUDCARD_THUMBNAIL_SCALE );
+#else
+ m_cardImage->ScaleAboutCenter( percentageDone );
+#endif
+
+ // apply projectile motion effect to card image
+ //
+ const float CARD_GRAVITY = 0.005f;
+ GuiSFX::Projectile( m_cardImage,
+ m_elapsedTime,
+ CARD_TRANSITION_IN_TIME,
+ rmt::Vector( (float)cardCenterX, (float)cardCenterY, 0.0f ),
+ rmt::Vector( centerX, centerY, 0.0f ),
+ true,
+ CARD_GRAVITY );
+
+ // scale up card text
+ //
+ m_cardText->ScaleAboutCenter( percentageDone );
+
+ // apply projectile motion effect to card text
+ //
+ const float TEXT_GRAVITY = 0.0005f;
+ GuiSFX::Projectile( m_cardText,
+ m_elapsedTime,
+ CARD_TRANSITION_IN_TIME,
+ rmt::Vector( 0.0f, 0.0f, 0.0f ),
+ rmt::Vector( 0.0f, 0.0f, 0.0f ),
+ false,
+ TEXT_GRAVITY );
+
+ // fade in card count
+ //
+ m_itemsCount->SetAlpha( percentageDone );
+/*
+ // flash card text
+ //
+ GuiSFX::Flash( m_cardGet, m_elapsedTime, CARD_TRANSITION_IN_TIME, 1, 1.1f, 1.0f );
+ GuiSFX::Flash( m_cardTitle, m_elapsedTime, CARD_TRANSITION_IN_TIME, 1, 1.1f, 1.0f );
+*/
+ }
+ else
+ {
+ m_cardImage->SetAlpha( 1.0f );
+ m_itemsCount->SetAlpha( 1.0f );
+#ifdef RAD_WIN32
+ m_cardImage->ScaleAboutCenter( HUDCARD_THUMBNAIL_SCALE );
+#endif
+
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case STATE_CARD_DISPLAY_HOLD:
+ {
+ const float CARD_DISPLAY_HOLD_TIME = 2000.0f;
+
+ if( m_elapsedTime < CARD_DISPLAY_HOLD_TIME )
+ {
+ // do nothing
+ }
+ else
+ {
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case STATE_CARD_TRANSITION_OUT:
+ {
+ const float CARD_TRANSITION_OUT_TIME = 300.0f;
+
+ m_itemsComplete->ResetTransformation();
+
+ if( m_elapsedTime < CARD_TRANSITION_OUT_TIME )
+ {
+ float percentageDone = m_elapsedTime / CARD_TRANSITION_OUT_TIME;
+
+ // slide out card image
+ //
+ GuiSFX::SlideY( m_cardImage,
+ m_elapsedTime,
+ CARD_TRANSITION_OUT_TIME,
+ false,
+ GuiSFX::SLIDE_BORDER_TOP );
+
+ // slide out card count
+ //
+ GuiSFX::SlideY( m_itemsCount,
+ m_elapsedTime,
+ CARD_TRANSITION_OUT_TIME,
+ false,
+ GuiSFX::SLIDE_BORDER_TOP,
+ 100 );
+
+ // fade out card text (and scale up)
+ //
+ rAssert( m_cardText != NULL );
+ m_cardText->SetAlpha( 1.0f - percentageDone );
+
+ m_cardText->ResetTransformation();
+ m_cardText->ScaleAboutCenter( 1.0f + percentageDone * 0.5f );
+
+#ifdef RAD_WIN32
+ m_cardImage->ScaleAboutCenter( HUDCARD_THUMBNAIL_SCALE );
+#endif
+
+ if( m_isCardDeckComplete )
+ {
+ m_itemsComplete->SetVisible( true );
+
+ // scale up card deck complete text
+ //
+ m_itemsComplete->ScaleAboutCenter( percentageDone );
+
+ // apply projectile motion effect to card deck complete text
+ //
+ const float TEXT_GRAVITY = 0.005f;
+ GuiSFX::Projectile( m_itemsComplete,
+ m_elapsedTime,
+ CARD_TRANSITION_OUT_TIME,
+ rmt::Vector( 0.0f, 0.0f, 0.0f ),
+ rmt::Vector( 0.0f, 0.0f, 0.0f ),
+ false,
+ TEXT_GRAVITY );
+ }
+ }
+ else
+ {
+ m_cardText->SetAlpha( 0.0f );
+
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+
+ if( !m_isCardDeckComplete )
+ {
+ // skip to final sub state
+ //
+ m_currentSubState = NUM_SUB_STATES;
+ }
+ }
+
+ break;
+ }
+ case STATE_CARD_DECK_COMPLETE_DISPLAY_HOLD:
+ {
+ const float CARD_DISPLAY_HOLD_TIME = 2000.0f;
+
+ if( m_elapsedTime < CARD_DISPLAY_HOLD_TIME )
+ {
+ // do nothing
+ }
+ else
+ {
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case STATE_CARD_DECK_COMPLETE_TRANSITION_OUT:
+ {
+ const float CARD_TRANSITION_OUT_TIME = 300.0f;
+
+ if( m_elapsedTime < CARD_TRANSITION_OUT_TIME )
+ {
+ float percentageDone = m_elapsedTime / CARD_TRANSITION_OUT_TIME;
+
+ // fade out card text (and scale up)
+ //
+ rAssert( m_itemsComplete != NULL );
+ m_itemsComplete->SetAlpha( 1.0f - percentageDone );
+
+ m_itemsComplete->ResetTransformation();
+ m_itemsComplete->ScaleAboutCenter( 1.0f + percentageDone * 0.5f );
+ }
+ else
+ {
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case NUM_SUB_STATES:
+ {
+ // ok, we're done
+ //
+ this->Stop();
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Unhandled sub-state!" );
+ break;
+ }
+ }
+ }
+}
+
+void
+HudCardCollected::SetCurrentCard( unsigned int cardID )
+{
+ rAssert( m_cardImage != NULL );
+ m_cardImage->SetIndex( cardID );
+
+ rAssert( m_cardTitle != NULL );
+ m_cardTitle->SetIndex( cardID );
+}
+
+void
+HudCardCollected::SetCardCount( unsigned int numCollected,
+ unsigned int numCollectibles )
+{
+ char buffer[ BITMAP_TEXT_BUFFER_SIZE ];
+ sprintf( buffer, "%d/%d", numCollected, numCollectibles );
+
+ rAssert( m_numCards != NULL );
+ m_numCards->SetBitmapText( buffer );
+
+#ifndef RAD_DEMO
+ // set card deck complete flag
+ //
+ m_isCardDeckComplete = (numCollected == numCollectibles);
+
+ if( m_isCardDeckComplete &&
+ GetCardGallery()->GetNumCardDecksCompleted() == RenderEnums::numLevels )
+ {
+ // all card decks completed
+ //
+ rAssert( m_cardDeckComplete != NULL );
+ m_cardDeckComplete->SetIndex( CARD_DECK_COMPLETE );
+
+ rAssert( m_itemsUnlocked != NULL );
+ m_itemsUnlocked->SetIndex( UNLOCKED_IS_MOVIE );
+ }
+#endif // !RAD_DEMO
+}
+
diff --git a/game/code/presentation/gui/ingame/hudevents/hudcardcollected.h b/game/code/presentation/gui/ingame/hudevents/hudcardcollected.h
new file mode 100644
index 0000000..619af5c
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudcardcollected.h
@@ -0,0 +1,100 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudCardCollected
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+#ifndef HUDCARDCOLLECTED_H
+#define HUDCARDCOLLECTED_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudeventhandler.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class Page;
+ class Group;
+ class Sprite;
+ class Text;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+class HudCardCollected : public HudEventHandler
+{
+public:
+ HudCardCollected( Scrooby::Page* pPage );
+ virtual ~HudCardCollected();
+
+ virtual void Start();
+ virtual void Stop();
+ virtual void Update( float elapsedTime );
+
+ void SetCurrentCard( unsigned int cardID );
+
+private:
+ void SetCardCount( unsigned int numCollected, unsigned int numCollectibles );
+
+ static const unsigned int BITMAP_TEXT_BUFFER_SIZE = 8;
+
+ enum eSubState
+ {
+ STATE_CARD_TRANSITION_IN,
+ STATE_CARD_DISPLAY_HOLD,
+ STATE_CARD_TRANSITION_OUT,
+
+ // extra state when last card per level is collected
+ //
+ STATE_CARD_DECK_COMPLETE_DISPLAY_HOLD,
+ STATE_CARD_DECK_COMPLETE_TRANSITION_OUT,
+
+ NUM_SUB_STATES
+ };
+
+ unsigned int m_currentSubState;
+
+ Scrooby::Sprite* m_cardImage;
+
+ Scrooby::Group* m_cardText;
+ Scrooby::Text* m_cardGet;
+ Scrooby::Text* m_cardTitle;
+
+ Scrooby::Group* m_itemsCount;
+ Scrooby::Sprite* m_numCards;
+
+ Scrooby::Group* m_itemsComplete;
+
+ enum eCardDeckCompleteMessage
+ {
+ LEVEL_CARDS_COMPLETE,
+ CARD_DECK_COMPLETE
+ };
+
+ Scrooby::Text* m_cardDeckComplete;
+ bool m_isCardDeckComplete : 1;
+
+ enum eItemUnlockedMessage
+ {
+ UNLOCKED_MINI_GAME_TRACK,
+ UNLOCKED_IS_MOVIE
+ };
+
+ Scrooby::Text* m_itemsUnlocked;
+
+};
+
+#endif // HUDCARDCOLLECTED_H
diff --git a/game/code/presentation/gui/ingame/hudevents/hudcoincollected.cpp b/game/code/presentation/gui/ingame/hudevents/hudcoincollected.cpp
new file mode 100644
index 0000000..0728a36
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudcoincollected.cpp
@@ -0,0 +1,324 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudCoinCollected
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudcoincollected.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <presentation/gui/guiscreen.h>
+
+#include <worldsim/coins/coinmanager.h>
+
+// Scrooby
+#include <app.h>
+#include <page.h>
+#include <group.h>
+#include <sprite.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const short NUMERIC_TEXT_SPACING = -12;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+HudCoinCollected::HudCoinCollected( Scrooby::Page* pPage )
+: HudEventHandler( pPage->GetGroup( "ItemCollected" ) ),
+ m_currentSubState( 0 ),
+ m_cardImage( NULL ),
+ m_cardText( NULL ),
+ m_itemsCount( NULL ),
+ m_numCoins( NULL ),
+ m_currentItemCount( 0 ),
+ m_itemsComplete( NULL ),
+ m_isFullCount( false ),
+ m_elapsedCoinDecrementTime( 0.0f )
+{
+ rAssert( pPage != NULL );
+
+ m_itemsCount = pPage->GetGroup( "ItemsCount" );
+ rAssert( m_itemsCount != NULL );
+
+ m_numCoins = m_itemsCount->GetSprite( "ItemsCount" );
+ rAssert( m_numCoins != NULL );
+ m_numCoins->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT );
+ m_numCoins->CreateBitmapTextBuffer( BITMAP_TEXT_BUFFER_SIZE );
+ m_numCoins->SetBitmapTextSpacing( NUMERIC_TEXT_SPACING );
+#ifdef RAD_WIN32
+ m_numCoins->Translate( 70, 0 );
+ m_numCoins->ScaleAboutCenter( 0.5f );
+#endif
+
+ m_itemsComplete = pPage->GetGroup( "ItemsComplete" );
+
+ Scrooby::Group* itemCollected = pPage->GetGroup( "ItemCollected" );
+ rAssert( itemCollected != NULL );
+
+ m_cardImage = itemCollected->GetSprite( "CardCollected" );
+ rAssert( m_cardImage != NULL );
+
+ m_cardText = itemCollected->GetGroup( "CardText" );
+ rAssert( m_cardText != NULL );
+
+ m_currentItemCount = GetCoinManager()->GetBankValue();
+}
+
+HudCoinCollected::~HudCoinCollected()
+{
+}
+
+void
+HudCoinCollected::Start()
+{
+ if( m_currentState == STATE_RUNNING )
+ {
+ if( m_currentSubState > STATE_COIN_TRANSITION_IN )
+ {
+ // return to beginning of display hold state
+ //
+ m_currentSubState = STATE_COIN_DISPLAY_HOLD;
+ m_elapsedTime = 0.0f;
+ m_elapsedCoinDecrementTime = 0.0f;
+
+ // restore drawable properties
+ //
+ rAssert( m_itemsCount != NULL );
+ m_itemsCount->ResetTransformation();
+ m_itemsCount->SetAlpha( 1.0f );
+ }
+ }
+ else
+ {
+ m_currentSubState = STATE_COIN_TRANSITION_IN;
+ m_elapsedCoinDecrementTime = 0.0f;
+
+ rAssert( m_numCoins != NULL );
+ m_numCoins->SetColour( tColour( 255, 255, 255 ) );
+
+ // restore drawable properties
+ //
+ rAssert( m_itemsCount != NULL );
+ m_itemsCount->ResetTransformation();
+ m_itemsCount->SetAlpha( 0.0f );
+
+ rAssert( m_itemsComplete != NULL );
+ m_itemsComplete->SetVisible( false );
+
+ // hide all the cards sub-groups
+ //
+ m_cardImage->SetVisible( false );
+ m_cardText->SetVisible( false );
+ }
+
+ this->OnStart();
+
+ // update coin count
+ //
+ this->SetItemCount( static_cast<unsigned int>( m_currentItemCount ), 0 );
+}
+
+void
+HudCoinCollected::Stop()
+{
+ GetCoinManager()->SetHUDCoin( 0, 0, false );
+
+ this->OnStop();
+}
+
+void
+HudCoinCollected::Update( float elapsedTime )
+{
+ if( m_currentState == STATE_RUNNING )
+ {
+ m_elapsedTime += elapsedTime;
+
+ switch( m_currentSubState )
+ {
+ case STATE_COIN_TRANSITION_IN:
+ {
+ const float COIN_TRANSITION_IN_TIME = 200.0f;
+
+ rAssert( m_itemsCount != NULL );
+
+ if( m_elapsedTime < COIN_TRANSITION_IN_TIME )
+ {
+ float percentageDone = m_elapsedTime / COIN_TRANSITION_IN_TIME;
+
+ // slide in coin count
+ //
+ GuiSFX::SlideY( m_itemsCount,
+ m_elapsedTime,
+ COIN_TRANSITION_IN_TIME,
+ true,
+ GuiSFX::SLIDE_BORDER_TOP,
+ 100 );
+
+ // fade in coin coint
+ //
+ m_itemsCount->SetAlpha( percentageDone );
+ }
+ else
+ {
+ m_itemsCount->ResetTransformation();
+ m_itemsCount->SetAlpha( 1.0f );
+
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case STATE_COIN_DISPLAY_HOLD:
+ {
+ const float COIN_DISPLAY_HOLD_TIME = 2000.0f;
+ const float COIN_UPDATE_PERIOD = 40.0f;
+
+ if( m_elapsedTime < COIN_DISPLAY_HOLD_TIME )
+ {
+ static int coinPosX = CGuiScreen::IsWideScreenDisplay() ? 500 : 555;
+ static int coinPosY = 422;
+ GetCoinManager()->SetHUDCoin( coinPosX, coinPosY, true );
+
+ int currentBankValue = GetCoinManager()->GetBankValue();
+
+ rAssert( m_numCoins != NULL );
+ if( m_currentItemCount > currentBankValue )
+ {
+ // coin loss
+ //
+ m_elapsedCoinDecrementTime += elapsedTime;
+
+ tColour coinColour;
+ GuiSFX::ModulateColour( &coinColour,
+ m_elapsedCoinDecrementTime,
+ COIN_UPDATE_PERIOD * 2,
+ tColour( 255, 255, 255 ),
+ tColour( 255, 0, 0 ) );
+
+ m_numCoins->SetColour( coinColour );
+ }
+ else
+ {
+ m_numCoins->SetColour( tColour( 255, 255, 255 ) );
+ }
+
+ // update coin change progressively
+ //
+ if( m_elapsedTime > COIN_UPDATE_PERIOD )
+ {
+ if( m_currentItemCount < currentBankValue )
+ {
+ m_currentItemCount++;
+ this->SetItemCount( static_cast<unsigned int>( m_currentItemCount ), 0 );
+
+ m_elapsedTime -= COIN_UPDATE_PERIOD;
+ }
+ else if( m_currentItemCount > currentBankValue )
+ {
+ m_currentItemCount--;
+ this->SetItemCount( static_cast<unsigned int>( m_currentItemCount ), 0 );
+
+ GetCoinManager()->AddFlyDownCoin();
+
+ m_elapsedTime -= COIN_UPDATE_PERIOD;
+ }
+ }
+ }
+ else
+ {
+ GetCoinManager()->SetHUDCoin( 0, 0, false );
+
+ rAssert( m_numCoins != NULL );
+ m_numCoins->SetColour( tColour( 255, 255, 255 ) );
+
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case STATE_COIN_TRANSITION_OUT:
+ {
+ const float COIN_TRANSITION_OUT_TIME = 200.0f;
+
+ if( m_elapsedTime < COIN_TRANSITION_OUT_TIME )
+ {
+ float percentageDone = m_elapsedTime / COIN_TRANSITION_OUT_TIME;
+
+ // slide out coin count
+ //
+ GuiSFX::SlideY( m_itemsCount,
+ m_elapsedTime,
+ COIN_TRANSITION_OUT_TIME,
+ false,
+ GuiSFX::SLIDE_BORDER_TOP,
+ 100 );
+ }
+ else
+ {
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+
+ if( !m_isFullCount )
+ {
+ // skip to final sub state
+ //
+ m_currentSubState = NUM_SUB_STATES;
+
+ }
+ }
+
+ break;
+ }
+ case NUM_SUB_STATES:
+ {
+ // ok, we're done
+ //
+ this->Stop();
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Unhandled sub-state!" );
+ break;
+ }
+ }
+ }
+}
+
+void
+HudCoinCollected::SetItemCount( unsigned int numCollected,
+ unsigned int numCollectibles )
+{
+ char buffer[ BITMAP_TEXT_BUFFER_SIZE ];
+ sprintf( buffer, "%d", numCollected );
+
+ rAssert( m_numCoins != NULL );
+ m_numCoins->SetBitmapText( buffer );
+
+ // set card deck complete flag
+ //
+ m_isFullCount = (numCollected == numCollectibles);
+}
+
diff --git a/game/code/presentation/gui/ingame/hudevents/hudcoincollected.h b/game/code/presentation/gui/ingame/hudevents/hudcoincollected.h
new file mode 100644
index 0000000..08f93bb
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudcoincollected.h
@@ -0,0 +1,84 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudCoinCollected
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+#ifndef HUDCOINCOLLECTED_H
+#define HUDCOINCOLLECTED_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudeventhandler.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class Page;
+ class Group;
+ class Sprite;
+ class Text;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+class HudCoinCollected : public HudEventHandler
+{
+public:
+ HudCoinCollected( Scrooby::Page* pPage );
+ virtual ~HudCoinCollected();
+
+ virtual void Start();
+ virtual void Stop();
+ virtual void Update( float elapsedTime );
+
+ void SetCurrentItemCount( int itemCount );
+
+private:
+ void SetItemCount( unsigned int numCollected, unsigned int numCollectibles );
+
+ static const unsigned int BITMAP_TEXT_BUFFER_SIZE = 8;
+
+ enum eSubState
+ {
+ STATE_COIN_TRANSITION_IN,
+ STATE_COIN_DISPLAY_HOLD,
+ STATE_COIN_TRANSITION_OUT,
+
+ NUM_SUB_STATES
+ };
+
+ unsigned int m_currentSubState;
+
+ Scrooby::Sprite* m_cardImage;
+ Scrooby::Group* m_cardText;
+
+ Scrooby::Group* m_itemsCount;
+ Scrooby::Sprite* m_numCoins;
+ int m_currentItemCount;
+
+ Scrooby::Group* m_itemsComplete;
+ bool m_isFullCount : 1;
+
+ float m_elapsedCoinDecrementTime;
+
+};
+
+inline void HudCoinCollected::SetCurrentItemCount( int itemCount )
+{
+ m_currentItemCount = itemCount;
+}
+
+#endif // HUDCOINCOLLECTED_H
diff --git a/game/code/presentation/gui/ingame/hudevents/hudcountdown.cpp b/game/code/presentation/gui/ingame/hudevents/hudcountdown.cpp
new file mode 100644
index 0000000..b8fc05f
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudcountdown.cpp
@@ -0,0 +1,233 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudCountDown
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudcountdown.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <presentation/gui/guitextbible.h>
+
+#include <events/eventmanager.h>
+#include <input/controller.h>
+#include <input/inputmanager.h>
+#include <mission/gameplaymanager.h>
+#include <gameflow/gameflow.h>
+#include <worldsim/character/charactermanager.h>
+
+// Scrooby
+#include <group.h>
+#include <page.h>
+#include <sprite.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+HudCountDown::HudCountDown( Scrooby::Page* pPage )
+: HudEventHandler( pPage->GetGroup( "CountDown" ) ),
+ m_countDownMessage( NULL ),
+ m_missionStage( NULL ),
+ m_currentSequenceUnit( NULL ),
+ m_nextSequenceIndex( 0 ),
+ m_InputDisablePending( false ),
+ m_isDialogTriggerPending( false )
+{
+// const float BITMAP_TEXT_SPACING = 0.8f;
+
+ rAssert( pPage != NULL );
+ m_countDownMessage = pPage->GetSprite( "CountDown" );
+ rAssert( m_countDownMessage != NULL );
+ m_countDownMessage->SetSpriteMode( Scrooby::SPRITE_BITMAP_TEXT );
+ m_countDownMessage->CreateBitmapTextBuffer( 32 );
+// m_countDownMessage->SetBitmapTextSpacing( BITMAP_TEXT_SPACING );
+}
+
+HudCountDown::~HudCountDown()
+{
+}
+
+//=============================================================================
+// HudCountDown::OnStart
+//=============================================================================
+// Description: Called when the HudCountDown starts
+//
+// Parameters: NONE
+//
+// Return: void
+//
+//=============================================================================
+void HudCountDown::OnStart()
+{
+ Parent::OnStart();
+}
+
+//=============================================================================
+// HudCountDown::QueueDisableInput
+//=============================================================================
+// Description: tells the object that the next time update is called, we need
+// to disable the input system
+//
+// Parameters: NONE
+//
+// Return: void
+//
+//=============================================================================
+void HudCountDown::QueueDisableInput()
+{
+ m_InputDisablePending = true;
+}
+
+void
+HudCountDown::Start()
+{
+ Character* npcPtr;
+ const char* modelName;
+
+ this->OnStart();
+
+ m_missionStage = GetGameplayManager()->GetCurrentMission()->GetCurrentStage();
+
+ m_nextSequenceIndex = 0;
+ this->GetNextSequenceUnit();
+
+ // get dialog event data and queue it up for triggering on the next update
+ //
+ BonusMissionInfo* bonusMissionInfo = const_cast<BonusMissionInfo*>( GetGameplayManager()->GetCurrentBonusMissionInfo() );
+ if( bonusMissionInfo != NULL )
+ {
+ npcPtr = bonusMissionInfo->GetNPC();
+ rAssert( npcPtr != NULL );
+ modelName = GetCharacterManager()->GetModelName( npcPtr );
+
+ m_dialogData.charUID1 = tEntity::MakeUID( modelName );
+ m_dialogData.charUID2 = m_missionStage->GetCountdownSecondSpeakerUID();
+ m_dialogData.dialogName = m_missionStage->GetCountdownDialogID();
+
+ m_isDialogTriggerPending = true;
+ }
+
+ QueueDisableInput();
+}
+
+void
+HudCountDown::Stop()
+{
+ m_missionStage = NULL;
+ m_currentSequenceUnit = NULL;
+
+ // enable the controller - yes i know this is not an animated cam
+ //
+ if( GetInputManager()->GetGameState() == Input::ACTIVE_ANIM_CAM )
+ {
+ InputManager::GetInstance()->SetGameState( Input::DEACTIVE_ANIM_CAM );
+ }
+
+ this->OnStop();
+}
+
+void
+HudCountDown::Update( float elapsedTime )
+{
+ if( m_InputDisablePending )
+ {
+ // disable the controller - yes i know this is not an animated cam
+ //
+ InputManager::GetInstance()->SetGameState( Input::ACTIVE_ANIM_CAM );
+ m_InputDisablePending = false;
+ }
+
+ if( m_currentState == STATE_RUNNING )
+ {
+ if( m_isDialogTriggerPending )
+ {
+ m_isDialogTriggerPending = false;
+
+ GetEventManager()->TriggerEvent( EVENT_IN_GAMEPLAY_CONVERSATION, static_cast<void*>( &m_dialogData ) );
+ }
+
+#ifdef RAD_WIN32
+ static float COUNT_DOWN_MAX_SCALE = 1.5f;
+#else
+ static float COUNT_DOWN_MAX_SCALE = 3.0f;
+#endif
+ static float COUNT_DOWN_THRESHOLD_SCALE = 2.5f;
+ static int COUNT_DOWN_ZOOM_RATE = 2;
+
+ if( m_currentSequenceUnit != NULL )
+ {
+ bool done = GuiSFX::Flash( m_countDownMessage,
+ m_elapsedTime,
+ (float)m_currentSequenceUnit->durationTime,
+ COUNT_DOWN_ZOOM_RATE,
+ COUNT_DOWN_MAX_SCALE,
+ COUNT_DOWN_THRESHOLD_SCALE );
+ if( done )
+ {
+ m_elapsedTime = 0;
+
+ this->GetNextSequenceUnit();
+ }
+ }
+ else
+ {
+ // countdown finished
+ //
+ this->Stop();
+
+ // start the mission!
+ //
+ GetEventManager()->TriggerEvent( EVENT_GUI_MISSION_START );
+
+ //
+ // Take all the AI cars out of the limbo state
+ //
+ MissionStage* stage = GetGameplayManager()->GetCurrentMission()->GetCurrentStage();
+ rAssert( stage != NULL );
+ stage->PutAllAisInLimbo( false );
+ }
+
+ m_elapsedTime += elapsedTime;
+ }
+}
+
+void
+HudCountDown::GetNextSequenceUnit()
+{
+ rAssert( m_missionStage != NULL );
+ m_currentSequenceUnit = m_missionStage->GetCountdownSequenceUnit( m_nextSequenceIndex );
+
+ if( m_currentSequenceUnit != NULL )
+ {
+ // set text message
+ //
+ rAssert( m_countDownMessage != NULL );
+ m_countDownMessage->SetAlpha( 0.0f );
+
+ P3D_UNICODE* text = GetTextBibleString( m_currentSequenceUnit->textID );
+ if( text != NULL )
+ {
+ m_countDownMessage->SetBitmapText( text );
+ }
+ else
+ {
+ m_countDownMessage->SetBitmapText( "" );
+ }
+ }
+
+ m_nextSequenceIndex++;
+}
+
diff --git a/game/code/presentation/gui/ingame/hudevents/hudcountdown.h b/game/code/presentation/gui/ingame/hudevents/hudcountdown.h
new file mode 100644
index 0000000..4ea50b0
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudcountdown.h
@@ -0,0 +1,69 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudCountDown
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+#ifndef HUDCOUNTDOWN_H
+#define HUDCOUNTDOWN_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudeventhandler.h>
+#include <mission/missionstage.h>
+#include <events/eventdata.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class Page;
+ class Sprite;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+class HudCountDown : public HudEventHandler
+{
+private:
+ typedef HudEventHandler Parent;
+
+public:
+ HudCountDown( Scrooby::Page* pPage );
+ virtual ~HudCountDown();
+
+ virtual void Start();
+ virtual void Stop();
+ virtual void Update( float elapsedTime );
+
+protected:
+ void OnStart();
+ void QueueDisableInput();
+
+private:
+ void GetNextSequenceUnit();
+
+ Scrooby::Sprite* m_countDownMessage;
+
+ MissionStage* m_missionStage;
+ MissionStage::CountdownSequenceUnit* m_currentSequenceUnit;
+ int m_nextSequenceIndex;
+ bool m_InputDisablePending;
+
+ bool m_isDialogTriggerPending;
+ DialogEventData m_dialogData;
+
+};
+
+#endif // HUDCOUNTDOWN_H
diff --git a/game/code/presentation/gui/ingame/hudevents/hudeventhandler.cpp b/game/code/presentation/gui/ingame/hudevents/hudeventhandler.cpp
new file mode 100644
index 0000000..378401e
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudeventhandler.cpp
@@ -0,0 +1,77 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudEventHandler
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudeventhandler.h>
+
+// Scrooby
+#include <group.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+HudEventHandler::HudEventHandler( Scrooby::Group* drawableGroup )
+: m_drawableGroup( drawableGroup ),
+ m_elapsedTime( 0.0f ),
+ m_currentState( STATE_IDLE )
+{
+ rAssert( drawableGroup != NULL );
+ drawableGroup->SetVisible( false );
+}
+
+HudEventHandler::~HudEventHandler()
+{
+}
+
+void
+HudEventHandler::OnStart()
+{
+ if( m_currentState != STATE_RUNNING )
+ {
+ // show all drawable elements in group
+ //
+ rAssert( m_drawableGroup != NULL );
+ m_drawableGroup->SetVisible( true );
+
+ // reset elapsed time
+ //
+ m_elapsedTime = 0.0;
+
+ // update current state
+ //
+ m_currentState = STATE_RUNNING;
+ }
+}
+
+void
+HudEventHandler::OnStop()
+{
+ if( m_currentState != STATE_IDLE )
+ {
+ // hide all drawable elements in group
+ //
+ rAssert( m_drawableGroup != NULL );
+ m_drawableGroup->SetVisible( false );
+
+ // update current state
+ //
+ m_currentState = STATE_IDLE;
+ }
+}
+
diff --git a/game/code/presentation/gui/ingame/hudevents/hudeventhandler.h b/game/code/presentation/gui/ingame/hudevents/hudeventhandler.h
new file mode 100644
index 0000000..fcb931d
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudeventhandler.h
@@ -0,0 +1,69 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudEventHandler
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+#ifndef HUDEVENTHANDLER_H
+#define HUDEVENTHANDLER_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class Group;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+class HudEventHandler
+{
+public:
+ HudEventHandler( Scrooby::Group* drawableGroup );
+ virtual ~HudEventHandler();
+
+ virtual void Start() = 0;
+ virtual void Stop() = 0;
+ virtual void Update( float elapsedTime ) = 0;
+
+ bool IsActive() const;
+
+protected:
+ void OnStart();
+ void OnStop();
+
+ Scrooby::Group* m_drawableGroup;
+ float m_elapsedTime;
+
+ enum eState
+ {
+ STATE_IDLE,
+ STATE_RUNNING,
+
+ NUM_STATES
+ };
+
+ eState m_currentState;
+
+};
+
+inline bool HudEventHandler::IsActive() const
+{
+ return( m_currentState != STATE_IDLE );
+}
+
+#endif // HUDEVENTHANDLER_H
diff --git a/game/code/presentation/gui/ingame/hudevents/hudhitnrun.cpp b/game/code/presentation/gui/ingame/hudevents/hudhitnrun.cpp
new file mode 100644
index 0000000..17c1da3
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudhitnrun.cpp
@@ -0,0 +1,297 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudHitNRun
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudhitnrun.h>
+#include <presentation/gui/utility/specialfx.h>
+
+// Scrooby
+#include <app.h>
+#include <group.h>
+#include <page.h>
+#include <text.h>
+#include <sprite.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+#ifdef RAD_WIN32
+const float HNR_MESSAGE_SCALE = 1.75f;
+const float HNR_MESSAGE_BUSTED_SCALE = 2.0f;
+const float HNR_TICKET_SCALE = 1.0f;
+const float HNR_MESSAGE_BUSTED_TILT_ANGLE = -10.0f; // in degrees
+const tColour HNR_MESSAGE_BUSTED_COLOUR( 43, 89, 249 );
+#else
+const float HNR_MESSAGE_SCALE = 1.75f;
+const float HNR_MESSAGE_BUSTED_SCALE = 2.0f;
+const float HNR_TICKET_SCALE = 2.0f;
+const float HNR_MESSAGE_BUSTED_TILT_ANGLE = -10.0f; // in degrees
+const tColour HNR_MESSAGE_BUSTED_COLOUR( 43, 89, 249 );
+#endif
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+HudHitNRun::HudHitNRun( Scrooby::Page* pPage )
+: HudEventHandler( pPage->GetGroup( "HitNRun" ) ),
+ m_currentSubState( 0 ),
+ m_currentMessage( MSG_HIT_N_RUN ),
+ m_hnrMessage( NULL ),
+ m_hnrTicket( NULL ),
+ m_messageTranslateX( 0 ),
+ m_messageTranslateY( 0 ),
+ m_defaultMessageColour( 100, 0, 0 )
+{
+ rAssert( pPage != NULL );
+
+ Scrooby::Group* pGroup = pPage->GetGroup( "HitNRun" );
+ rAssert( pGroup != NULL );
+
+ m_hnrMessage = pGroup->GetText( "HitNRun" );
+ rAssert( m_hnrMessage != NULL );
+ m_hnrMessage->SetTextMode( Scrooby::TEXT_WRAP );
+ m_hnrMessage->SetDisplayOutline( true );
+
+// m_defaultMessageColour = m_hnrMessage->GetColour();
+
+ m_hnrTicket = pGroup->GetSprite( "HitNRunTicket" );
+
+ int messageCenterX = 0;
+ int messageCenterY = 0;
+ m_hnrMessage->GetBoundingBoxCenter( messageCenterX, messageCenterY );
+
+ Scrooby::Sprite* radar = pPage->GetSprite( "Radar0" );
+ rAssert( radar != NULL );
+ radar->GetBoundingBoxCenter( m_messageTranslateX, m_messageTranslateY );
+
+ m_messageTranslateX -= messageCenterX;
+ m_messageTranslateY -= messageCenterY;
+}
+
+HudHitNRun::~HudHitNRun()
+{
+}
+
+void
+HudHitNRun::Start()
+{
+ if( m_currentState != STATE_RUNNING )
+ {
+ m_currentSubState = STATE_MESSAGE_TRANSITION_IN;
+
+ rAssert( m_hnrMessage != NULL );
+ m_hnrMessage->SetIndex( m_currentMessage );
+ m_hnrMessage->SetAlpha( 0.0f );
+ m_hnrMessage->SetColour( m_currentMessage == MSG_BUSTED ?
+ HNR_MESSAGE_BUSTED_COLOUR :
+ m_defaultMessageColour ); // restore default colour
+
+ rAssert( m_hnrTicket != NULL );
+ m_hnrTicket->SetAlpha( 0.0f );
+ m_hnrTicket->SetVisible( m_currentMessage == MSG_BUSTED );
+ }
+
+ this->OnStart();
+}
+
+void
+HudHitNRun::Stop()
+{
+ this->OnStop();
+}
+
+void
+HudHitNRun::Update( float elapsedTime )
+{
+ if( m_currentState == STATE_RUNNING )
+ {
+ m_elapsedTime += elapsedTime;
+
+ switch( m_currentSubState )
+ {
+ case STATE_MESSAGE_TRANSITION_IN:
+ {
+ const float MESSAGE_TRANSITION_TIME = 200.0f;
+
+ rAssert( m_hnrMessage != NULL );
+ m_hnrMessage->ResetTransformation();
+
+ rAssert( m_hnrTicket != NULL );
+ m_hnrTicket->ResetTransformation();
+
+ if( m_elapsedTime < MESSAGE_TRANSITION_TIME )
+ {
+ float percentageDone = m_elapsedTime / MESSAGE_TRANSITION_TIME;
+
+ m_hnrMessage->SetAlpha( percentageDone );
+
+ if( m_hnrMessage->GetIndex() == MSG_HIT_N_RUN )
+ {
+ m_hnrMessage->ScaleAboutCenter( percentageDone * HNR_MESSAGE_SCALE );
+ }
+ else
+ {
+ m_hnrMessage->ScaleAboutCenter( percentageDone * HNR_MESSAGE_BUSTED_SCALE );
+ m_hnrMessage->RotateAboutCenter( percentageDone * HNR_MESSAGE_BUSTED_TILT_ANGLE );
+
+ m_hnrTicket->SetAlpha( percentageDone );
+ m_hnrTicket->ScaleAboutCenter( percentageDone * HNR_TICKET_SCALE );
+
+ GuiSFX::Projectile( m_hnrTicket,
+ m_elapsedTime,
+ MESSAGE_TRANSITION_TIME,
+ rmt::Vector( 0, 0, 0 ),
+ rmt::Vector( (float)m_messageTranslateX, (float)m_messageTranslateY, 0 ),
+ true,
+ 0.0f );
+ }
+
+ GuiSFX::Projectile( m_hnrMessage,
+ m_elapsedTime,
+ MESSAGE_TRANSITION_TIME,
+ rmt::Vector( 0, 0, 0 ),
+ rmt::Vector( (float)m_messageTranslateX, (float)m_messageTranslateY, 0 ),
+ true,
+ 0.0f );
+ }
+ else
+ {
+ m_hnrMessage->SetAlpha( 1.0f );
+
+ if( m_hnrMessage->GetIndex() == MSG_HIT_N_RUN )
+ {
+ m_hnrMessage->ScaleAboutCenter( HNR_MESSAGE_SCALE );
+ }
+ else
+ {
+ m_hnrMessage->ScaleAboutCenter( HNR_MESSAGE_BUSTED_SCALE );
+ m_hnrMessage->RotateAboutCenter( HNR_MESSAGE_BUSTED_TILT_ANGLE );
+
+ m_hnrTicket->SetAlpha( 1.0f );
+ m_hnrTicket->ScaleAboutCenter( HNR_TICKET_SCALE );
+ }
+
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case STATE_MESSAGE_DISPLAY_HOLD:
+ {
+ const float MESSAGE_DISPLAY_HOLD_TIME = 1200.0f;
+
+ rAssert( m_hnrMessage != NULL );
+ if( m_elapsedTime < MESSAGE_DISPLAY_HOLD_TIME )
+ {
+ if( m_hnrMessage->GetIndex() == MSG_HIT_N_RUN )
+ {
+ static tColour MESSAGE_OTHER_COLOUR( 240, 8, 8 );
+
+ tColour currentColour;
+ GuiSFX::ModulateColour( &currentColour,
+ m_elapsedTime,
+ 333.3f,
+ m_defaultMessageColour,
+ MESSAGE_OTHER_COLOUR,
+ rmt::PI_BY2 );
+
+ m_hnrMessage->SetColour( currentColour );
+ }
+ }
+ else
+ {
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case STATE_MESSAGE_TRANSITION_OUT:
+ {
+ const float MESSAGE_TRANSITION_TIME = 200.0f;
+
+ rAssert( m_hnrMessage != NULL );
+ m_hnrMessage->ResetTransformation();
+
+ rAssert( m_hnrTicket != NULL );
+ m_hnrTicket->ResetTransformation();
+
+ if( m_elapsedTime < MESSAGE_TRANSITION_TIME )
+ {
+ float percentageDone = m_elapsedTime / MESSAGE_TRANSITION_TIME;
+
+ if( m_hnrMessage->GetIndex() == MSG_HIT_N_RUN )
+ {
+ m_hnrMessage->SetAlpha( 1.0f - percentageDone );
+ m_hnrMessage->ScaleAboutCenter( (1.0f - percentageDone) * HNR_MESSAGE_SCALE );
+
+ GuiSFX::Projectile( m_hnrMessage,
+ m_elapsedTime,
+ MESSAGE_TRANSITION_TIME,
+ rmt::Vector( 0, 0, 0 ),
+ rmt::Vector( (float)m_messageTranslateX, (float)m_messageTranslateY, 0 ),
+ false,
+ 0.0f );
+ }
+ else
+ {
+ m_hnrMessage->SetAlpha( 0.0f );
+
+ m_hnrTicket->ScaleAboutCenter( (percentageDone * 3 + 1.0f) * HNR_TICKET_SCALE );
+ m_hnrTicket->SetAlpha( 1.0f - percentageDone );
+ }
+ }
+ else
+ {
+ m_hnrMessage->SetAlpha( 0.0f );
+ m_hnrTicket->SetAlpha( 0.0f );
+
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case NUM_SUB_STATES:
+ {
+ // ok, we're done
+ //
+ this->Stop();
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Unhandled sub-state!" );
+ break;
+ }
+ }
+ }
+}
+
+void
+HudHitNRun::SetMessage( eMessage message )
+{
+ m_currentMessage = message;
+}
+
diff --git a/game/code/presentation/gui/ingame/hudevents/hudhitnrun.h b/game/code/presentation/gui/ingame/hudevents/hudhitnrun.h
new file mode 100644
index 0000000..778a867
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudhitnrun.h
@@ -0,0 +1,81 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudHitNRun
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+#ifndef HUDHITNRUN_H
+#define HUDHITNRUN_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudeventhandler.h>
+
+#include <p3d/p3dtypes.hpp>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class Page;
+ class Text;
+ class Sprite;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+class HudHitNRun : public HudEventHandler
+{
+public:
+ HudHitNRun( Scrooby::Page* pPage );
+ virtual ~HudHitNRun();
+
+ virtual void Start();
+ virtual void Stop();
+ virtual void Update( float elapsedTime );
+
+ enum eMessage
+ {
+ MSG_HIT_N_RUN,
+ MSG_BUSTED,
+
+ NUM_MESSAGES
+ };
+
+ void SetMessage( eMessage message );
+
+private:
+ enum eSubState
+ {
+ STATE_MESSAGE_TRANSITION_IN,
+ STATE_MESSAGE_DISPLAY_HOLD,
+ STATE_MESSAGE_TRANSITION_OUT,
+
+ NUM_SUB_STATES
+ };
+
+ unsigned int m_currentSubState;
+
+ eMessage m_currentMessage;
+ Scrooby::Text* m_hnrMessage;
+ Scrooby::Sprite* m_hnrTicket;
+
+ int m_messageTranslateX;
+ int m_messageTranslateY;
+
+ tColour m_defaultMessageColour;
+
+};
+
+#endif // HUDHITNRUN_H
diff --git a/game/code/presentation/gui/ingame/hudevents/huditemdropped.cpp b/game/code/presentation/gui/ingame/hudevents/huditemdropped.cpp
new file mode 100644
index 0000000..38eb6f7
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/huditemdropped.cpp
@@ -0,0 +1,217 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudItemDropped
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/huditemdropped.h>
+#include <presentation/gui/utility/specialfx.h>
+
+// Scrooby
+#include <page.h>
+#include <group.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+HudItemDropped::HudItemDropped( Scrooby::Page* pPage )
+: HudEventHandler( pPage->GetGroup( "ItemDropped" ) ),
+ m_currentSubState( 0 ),
+ m_itemDropped( NULL )
+{
+ m_itemDropped = m_drawableGroup->GetText( "ItemDropped" );
+ rAssert( m_itemDropped != NULL );
+ m_itemDropped->SetTextMode( Scrooby::TEXT_WRAP );
+}
+
+HudItemDropped::~HudItemDropped()
+{
+}
+
+void
+HudItemDropped::Start()
+{
+ this->OnStart();
+
+ m_currentSubState = STATE_TRANSITION_IN;
+
+ rAssert( m_itemDropped != NULL );
+ m_itemDropped->ResetTransformation();
+ m_itemDropped->SetAlpha( 0.0f );
+ m_itemDropped->SetVisible( true );
+}
+
+void
+HudItemDropped::Stop()
+{
+ this->OnStop();
+}
+
+void
+HudItemDropped::Update( float elapsedTime )
+{
+ if( m_currentState == STATE_RUNNING )
+ {
+ m_elapsedTime += elapsedTime;
+
+ switch( m_currentSubState )
+ {
+ case STATE_TRANSITION_IN:
+ {
+ const float TRANSITION_IN_TIME = 200.0f;
+
+ rAssert( m_itemDropped != NULL );
+ m_itemDropped->ResetTransformation();
+
+ if( m_elapsedTime < TRANSITION_IN_TIME )
+ {
+ float percentageDone = m_elapsedTime / TRANSITION_IN_TIME;
+
+ // slide in from HUD icon
+ //
+ m_itemDropped->Translate( 0, static_cast<int>( (1.0f - percentageDone) * 100 ) );
+
+ // fade in coin coint
+ //
+ m_itemDropped->SetAlpha( percentageDone );
+ }
+ else
+ {
+ m_itemDropped->ResetTransformation();
+ m_itemDropped->SetAlpha( 1.0f );
+
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case STATE_DISPLAY_HOLD:
+ {
+ const float BLINKING_PERIOD = 250.0f;
+
+ bool isBlinked = GuiSFX::Blink( m_itemDropped,
+ m_elapsedTime,
+ BLINKING_PERIOD );
+
+ if( isBlinked )
+ {
+ m_elapsedTime = static_cast<float>( static_cast<int>( m_elapsedTime ) %
+ static_cast<int>( BLINKING_PERIOD ) );
+ }
+/*
+ const float DISPLAY_HOLD_TIME = 2000.0f;
+
+ if( m_elapsedTime < DISPLAY_HOLD_TIME )
+ {
+ static int coinPosX = CGuiScreen::IsWideScreenDisplay() ? 500 : 555;
+ static int coinPosY = 422;
+ GetCoinManager()->SetHUDCoin( coinPosX, coinPosY, true );
+
+ int currentBankValue = GetCoinManager()->GetBankValue();
+
+ rAssert( m_numCoins != NULL );
+ if( m_currentItemCount > currentBankValue )
+ {
+ // coin loss
+ //
+ m_elapsedCoinDecrementTime += elapsedTime;
+
+ tColour coinColour;
+ GuiSFX::ModulateColour( &coinColour,
+ m_elapsedCoinDecrementTime,
+ UPDATE_PERIOD * 2,
+ tColour( 255, 255, 255 ),
+ tColour( 255, 0, 0 ) );
+
+ m_numCoins->SetColour( coinColour );
+ }
+ else
+ {
+ m_numCoins->SetColour( tColour( 255, 255, 255 ) );
+ }
+ }
+ else
+ {
+ GetCoinManager()->SetHUDCoin( 0, 0, false );
+
+ rAssert( m_numCoins != NULL );
+ m_numCoins->SetColour( tColour( 255, 255, 255 ) );
+
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+*/
+ break;
+ }
+ case STATE_TRANSITION_OUT:
+ {
+ const float TRANSITION_OUT_TIME = 200.0f;
+/*
+ if( m_elapsedTime < TRANSITION_OUT_TIME )
+ {
+ float percentageDone = m_elapsedTime / TRANSITION_OUT_TIME;
+
+ // slide out coin count
+ //
+ GuiSFX::SlideY( m_itemsCount,
+ m_elapsedTime,
+ TRANSITION_OUT_TIME,
+ false,
+ GuiSFX::SLIDE_BORDER_TOP,
+ 100 );
+ }
+ else
+ {
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+
+ if( !m_isFullCount )
+ {
+ // skip to final sub state
+ //
+ m_currentSubState = NUM_SUB_STATES;
+
+ }
+ }
+*/
+ break;
+ }
+ case NUM_SUB_STATES:
+ {
+ // ok, we're done
+ //
+ this->Stop();
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Unhandled sub-state!" );
+ break;
+ }
+ }
+ }
+}
+
diff --git a/game/code/presentation/gui/ingame/hudevents/huditemdropped.h b/game/code/presentation/gui/ingame/hudevents/huditemdropped.h
new file mode 100644
index 0000000..824c001
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/huditemdropped.h
@@ -0,0 +1,61 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudItemDropped
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+#ifndef HUDITEMDROPPED_H
+#define HUDITEMDROPPED_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudeventhandler.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class Page;
+ class Text;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+class HudItemDropped : public HudEventHandler
+{
+public:
+ HudItemDropped( Scrooby::Page* pPage );
+ virtual ~HudItemDropped();
+
+ virtual void Start();
+ virtual void Stop();
+ virtual void Update( float elapsedTime );
+
+private:
+ enum eSubState
+ {
+ STATE_TRANSITION_IN,
+ STATE_DISPLAY_HOLD,
+ STATE_TRANSITION_OUT,
+
+ NUM_SUB_STATES
+ };
+
+ unsigned int m_currentSubState;
+
+ Scrooby::Text* m_itemDropped;
+
+};
+
+#endif // HUDITEMDROPPED_H
diff --git a/game/code/presentation/gui/ingame/hudevents/hudmissionobjective.cpp b/game/code/presentation/gui/ingame/hudevents/hudmissionobjective.cpp
new file mode 100644
index 0000000..a6b2e05
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudmissionobjective.cpp
@@ -0,0 +1,255 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudMissionObjective
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudmissionobjective.h>
+#include <presentation/gui/ingame/guimanageringame.h>
+#include <presentation/gui/ingame/guiscreenhud.h>
+#include <presentation/gui/utility/specialfx.h>
+
+#include <mission/gameplaymanager.h>
+#include <mission/mission.h>
+#include <mission/missionstage.h>
+
+// Scrooby
+#include <group.h>
+#include <page.h>
+#include <sprite.h>
+
+// Pure3D
+#include <p3d/utility.hpp>
+#include <p3d/sprite.hpp>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const int HUD_ICON_SLIDE_DISTANCE = 310; // vertical distance in pixels
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+HudMissionObjective::HudMissionObjective( Scrooby::Page* pPage )
+: HudEventHandler( pPage->GetGroup( "MissionObjective" ) ),
+ m_currentSubState( STATE_ICON_POP_UP ),
+ m_missionIcon( NULL ),
+ m_missionIconImage( NULL ),
+ m_messageID( 0 )
+{
+ rAssert( pPage != NULL );
+
+ m_missionIcon = pPage->GetSprite( "ObjectiveIcon" );
+ rAssert( m_missionIcon != NULL );
+
+ m_iconTranslator.SetDrawable( m_missionIcon );
+ m_iconTranslator.SetStartOffscreenBottom( m_missionIcon );
+ m_iconTranslator.SetFrequency( 5.0f );
+ m_iconTranslator.SetTimeInterval( 500.0f );
+
+ bool isIconFound = this->UpdateIcon();
+ if( isIconFound )
+ {
+ this->OnStart();
+
+ m_missionIcon->ResetTransformation();
+ m_missionIcon->ScaleAboutCenter( MISSION_ICON_SCALE );
+ m_missionIcon->Translate( 0, HUD_ICON_SLIDE_DISTANCE );
+
+ m_currentSubState = STATE_IDLE;
+ }
+}
+
+HudMissionObjective::~HudMissionObjective()
+{
+ if( m_missionIconImage != NULL )
+ {
+ m_missionIconImage->Release();
+ m_missionIconImage = NULL;
+ }
+}
+
+void
+HudMissionObjective::Start()
+{
+ this->OnStart();
+
+ m_currentSubState = STATE_ICON_POP_UP;
+
+ bool isIconFound = this->UpdateIcon();
+ if( isIconFound )
+ {
+ m_iconTranslator.Reset();
+ m_iconTranslator.Activate();
+ }
+ else
+ {
+ m_iconTranslator.Deactivate();
+ }
+}
+
+void
+HudMissionObjective::Stop()
+{
+ CGuiScreenHud* currentHud = GetCurrentHud();
+ if( currentHud != NULL )
+ {
+ currentHud->DisplayMessage( false );
+ }
+
+ rAssert( m_missionIcon != NULL );
+ m_missionIcon->SetRawSprite( NULL );
+ m_missionIcon->SetVisible( false );
+
+ if( m_missionIconImage != NULL )
+ {
+ m_missionIconImage->Release();
+ m_missionIconImage = NULL;
+ }
+
+ this->OnStop();
+}
+
+void
+HudMissionObjective::Update( float elapsedTime )
+{
+ if( m_currentState == STATE_RUNNING )
+ {
+ m_elapsedTime += elapsedTime;
+
+ switch( m_currentSubState )
+ {
+ case STATE_ICON_POP_UP:
+ {
+ rAssert( m_missionIcon != NULL );
+ m_missionIcon->ResetTransformation();
+ m_missionIcon->ScaleAboutCenter( MISSION_ICON_SCALE );
+
+ if( !m_iconTranslator.IsDone() )
+ {
+ m_iconTranslator.Update( elapsedTime );
+ }
+ else
+ {
+ m_iconTranslator.Deactivate();
+
+ CGuiScreenHud* currentHud = GetCurrentHud();
+ rAssert( currentHud != NULL );
+ currentHud->DisplayMessage( true, m_messageID );
+
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case STATE_ICON_DISPLAY_HOLD:
+ {
+ const float DISPLAY_HOLD_TIME = 3000.0f;
+
+ if( m_elapsedTime < DISPLAY_HOLD_TIME )
+ {
+ // do nothing
+ }
+ else
+ {
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case STATE_ICON_SLIDE_UP:
+ {
+ const float SLIDE_UP_TIME = 200.0f;
+
+ rAssert( m_missionIcon != NULL );
+ m_missionIcon->ResetTransformation();
+ m_missionIcon->ScaleAboutCenter( MISSION_ICON_SCALE );
+
+ if( m_elapsedTime < SLIDE_UP_TIME )
+ {
+ int translateY = (int)( (m_elapsedTime / SLIDE_UP_TIME) * HUD_ICON_SLIDE_DISTANCE );
+ m_missionIcon->Translate( 0, translateY );
+ }
+ else
+ {
+ m_missionIcon->Translate( 0, HUD_ICON_SLIDE_DISTANCE );
+
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case STATE_IDLE:
+ {
+ // do nothing
+ //
+ break;
+ }
+ case NUM_SUB_STATES:
+ {
+ rAssertMsg( false, "We shouldn't be here; last sub-state should be IDLE." );
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Unhandled sub-state!" );
+
+ break;
+ }
+ }
+ }
+}
+
+bool
+HudMissionObjective::UpdateIcon()
+{
+ tSprite* pSprite = NULL;
+
+ Mission* currentMission = GetGameplayManager()->GetCurrentMission();
+ if( currentMission != NULL )
+ {
+ MissionStage* currentStage = currentMission->GetCurrentStage();
+ if( currentStage != NULL )
+ {
+ const char* iconName = currentStage->GetHUDIcon();
+ if( iconName[ 0 ] != '\0' )
+ {
+ pSprite = p3d::find<tSprite>( iconName );
+ rTuneWarningMsg( pSprite != NULL, "Can't find HUD icon for mission presentation!" );
+ }
+ }
+ }
+
+ rAssert( m_missionIcon != NULL );
+ m_missionIcon->SetVisible( pSprite != NULL );
+ m_missionIcon->SetRawSprite( pSprite, true );
+
+ if( pSprite != NULL )
+ {
+ tRefCounted::Assign( m_missionIconImage, pSprite );
+ }
+
+ return (pSprite != NULL);
+}
+
diff --git a/game/code/presentation/gui/ingame/hudevents/hudmissionobjective.h b/game/code/presentation/gui/ingame/hudevents/hudmissionobjective.h
new file mode 100644
index 0000000..7e9c217
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudmissionobjective.h
@@ -0,0 +1,84 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudMissionObjective
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+#ifndef HUDMISSIONOBJECTIVE_H
+#define HUDMISSIONOBJECTIVE_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudeventhandler.h>
+#include <presentation/gui/utility/transitions.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+#ifdef RAD_WIN32 // temporary.. for art testing.
+const float MISSION_ICON_SCALE = 0.78f;
+#else
+const float MISSION_ICON_SCALE = 1.5f;
+#endif
+
+namespace Scrooby
+{
+ class Page;
+ class Sprite;
+}
+
+class tSprite;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+class HudMissionObjective : public HudEventHandler
+{
+public:
+ HudMissionObjective( Scrooby::Page* pPage );
+ virtual ~HudMissionObjective();
+
+ virtual void Start();
+ virtual void Stop();
+ virtual void Update( float elapsedTime );
+
+ void SetMessageID( unsigned int messageID );
+ bool UpdateIcon();
+
+private:
+ enum eSubState
+ {
+ STATE_ICON_POP_UP,
+ STATE_ICON_DISPLAY_HOLD,
+ STATE_ICON_SLIDE_UP,
+ STATE_IDLE,
+
+ NUM_SUB_STATES
+ };
+
+ unsigned int m_currentSubState;
+
+ Scrooby::Sprite* m_missionIcon;
+ tSprite* m_missionIconImage;
+ unsigned int m_messageID;
+
+ GuiSFX::UnderdampedTranslator m_iconTranslator;
+
+};
+
+inline void
+HudMissionObjective::SetMessageID( unsigned int messageID )
+{
+ m_messageID = messageID;
+}
+
+#endif // HUDMISSIONOBJECTIVE_H
diff --git a/game/code/presentation/gui/ingame/hudevents/hudmissionprogress.cpp b/game/code/presentation/gui/ingame/hudevents/hudmissionprogress.cpp
new file mode 100644
index 0000000..be85e76
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudmissionprogress.cpp
@@ -0,0 +1,83 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudMissionProgress
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudmissionprogress.h>
+#include <presentation/gui/utility/specialfx.h>
+
+// Scrooby
+#include <group.h>
+#include <page.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+HudMissionProgress::HudMissionProgress( Scrooby::Page* pPage )
+: HudEventHandler( pPage->GetGroup( "MissionProgress" ) ),
+ m_stageComplete( NULL )
+{
+ rAssert( pPage != NULL );
+
+ Scrooby::Group* missionProgress = pPage->GetGroup( "MissionProgress" );
+ rAssert( missionProgress != NULL );
+
+ m_stageComplete = missionProgress->GetText( "StageComplete" );
+ rAssert( m_stageComplete != NULL );
+ m_stageComplete->SetTextMode( Scrooby::TEXT_WRAP );
+}
+
+HudMissionProgress::~HudMissionProgress()
+{
+}
+
+void
+HudMissionProgress::Start()
+{
+ this->OnStart();
+}
+
+void
+HudMissionProgress::Stop()
+{
+ this->OnStop();
+}
+
+void
+HudMissionProgress::Update( float elapsedTime )
+{
+ if( m_currentState == STATE_RUNNING )
+ {
+ m_elapsedTime += elapsedTime;
+
+ static float DURATION_TIME = 1000.0f;
+
+ bool isDone = GuiSFX::Flash( m_stageComplete,
+ m_elapsedTime,
+ DURATION_TIME,
+ 1,
+ 1.25f,
+ 1.0f );
+ if( isDone )
+ {
+ this->Stop();
+ }
+ }
+}
+
diff --git a/game/code/presentation/gui/ingame/hudevents/hudmissionprogress.h b/game/code/presentation/gui/ingame/hudevents/hudmissionprogress.h
new file mode 100644
index 0000000..11623f2
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudmissionprogress.h
@@ -0,0 +1,50 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudMissionProgress
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+#ifndef HUDMISSIONPROGRESS_H
+#define HUDMISSIONPROGRESS_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudeventhandler.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class Page;
+ class Text;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+class HudMissionProgress : public HudEventHandler
+{
+public:
+ HudMissionProgress( Scrooby::Page* pPage );
+ virtual ~HudMissionProgress();
+
+ virtual void Start();
+ virtual void Stop();
+ virtual void Update( float elapsedTime );
+
+private:
+ Scrooby::Text* m_stageComplete;
+
+};
+
+#endif // HUDMISSIONPROGRESS_H
diff --git a/game/code/presentation/gui/ingame/hudevents/hudwaspdestroyed.cpp b/game/code/presentation/gui/ingame/hudevents/hudwaspdestroyed.cpp
new file mode 100644
index 0000000..3c3a879
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudwaspdestroyed.cpp
@@ -0,0 +1,184 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudWaspDestroyed
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudwaspdestroyed.h>
+#include <presentation/gui/utility/specialfx.h>
+
+#include <mission/gameplaymanager.h>
+#include <mission/charactersheet/charactersheetmanager.h>
+#include <mission/rewards/rewardsmanager.h>
+
+// Scrooby
+#include <page.h>
+#include <group.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+HudWaspDestroyed::HudWaspDestroyed( Scrooby::Page* pPage )
+: HudEventHandler( pPage->GetGroup( "WaspsDestroyed" ) ),
+ m_currentSubState( 0 ),
+ m_itemsComplete( NULL ),
+ m_isGagInsteadOfWasp( false )
+{
+ m_itemsComplete = m_drawableGroup->GetText( "WaspsComplete" );
+ rAssert( m_itemsComplete != NULL );
+}
+
+HudWaspDestroyed::~HudWaspDestroyed()
+{
+}
+
+void
+HudWaspDestroyed::Start()
+{
+ RenderEnums::LevelEnum currentLevel = GetGameplayManager()->GetCurrentLevelIndex();
+
+ bool isComplete = m_isGagInsteadOfWasp ?
+ GetCharacterSheetManager()->QueryNumGagsViewed( currentLevel ) == GetRewardsManager()->GetTotalGags( currentLevel ) :
+ GetCharacterSheetManager()->QueryNumWaspsDestroyed( currentLevel ) == GetRewardsManager()->GetTotalWasps( currentLevel );
+
+ if( isComplete )
+ {
+ this->OnStart();
+
+ m_currentSubState = STATE_WASP_TRANSITION_IN;
+
+ // restore drawable properties
+ //
+ rAssert( m_itemsComplete != NULL );
+ m_itemsComplete->ResetTransformation();
+ m_itemsComplete->SetAlpha( 1.0f );
+ m_itemsComplete->SetIndex( m_isGagInsteadOfWasp ? 1 : 0 );
+ }
+}
+
+void
+HudWaspDestroyed::Stop()
+{
+ this->OnStop();
+}
+
+void
+HudWaspDestroyed::Update( float elapsedTime )
+{
+ if( m_currentState == STATE_RUNNING )
+ {
+ m_elapsedTime += elapsedTime;
+
+ switch( m_currentSubState )
+ {
+ case STATE_WASP_TRANSITION_IN:
+ {
+ const float CARD_TRANSITION_IN_TIME = 300.0f;
+
+ m_itemsComplete->ResetTransformation();
+
+ if( m_elapsedTime < CARD_TRANSITION_IN_TIME )
+ {
+ float percentageDone = m_elapsedTime / CARD_TRANSITION_IN_TIME;
+
+ // scale up card deck complete text
+ //
+ m_itemsComplete->ScaleAboutCenter( percentageDone );
+
+ // apply projectile motion effect to card deck complete text
+ //
+ const float TEXT_GRAVITY = 0.005f;
+ GuiSFX::Projectile( m_itemsComplete,
+ m_elapsedTime,
+ CARD_TRANSITION_IN_TIME,
+ rmt::Vector( 0.0f, 0.0f, 0.0f ),
+ rmt::Vector( 0.0f, 0.0f, 0.0f ),
+ false,
+ TEXT_GRAVITY );
+ }
+ else
+ {
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case STATE_WASP_DISPLAY_HOLD:
+ {
+ const float CARD_DISPLAY_HOLD_TIME = 2000.0f;
+
+ if( m_elapsedTime < CARD_DISPLAY_HOLD_TIME )
+ {
+ // do nothing
+ }
+ else
+ {
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case STATE_WASP_TRANSITION_OUT:
+ {
+ const float CARD_TRANSITION_OUT_TIME = 300.0f;
+
+ if( m_elapsedTime < CARD_TRANSITION_OUT_TIME )
+ {
+ float percentageDone = m_elapsedTime / CARD_TRANSITION_OUT_TIME;
+
+ // fade out card text (and scale up)
+ //
+ rAssert( m_itemsComplete != NULL );
+ m_itemsComplete->SetAlpha( 1.0f - percentageDone );
+
+ m_itemsComplete->ResetTransformation();
+ m_itemsComplete->ScaleAboutCenter( 1.0f + percentageDone * 0.5f );
+ }
+ else
+ {
+ // advance to next sub state
+ //
+ m_elapsedTime = 0.0f;
+ m_currentSubState++;
+ }
+
+ break;
+ }
+ case NUM_SUB_STATES:
+ {
+ // ok, we're done
+ //
+ this->Stop();
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Unhandled sub-state!" );
+ break;
+ }
+ }
+ }
+}
+
diff --git a/game/code/presentation/gui/ingame/hudevents/hudwaspdestroyed.h b/game/code/presentation/gui/ingame/hudevents/hudwaspdestroyed.h
new file mode 100644
index 0000000..9d50b96
--- /dev/null
+++ b/game/code/presentation/gui/ingame/hudevents/hudwaspdestroyed.h
@@ -0,0 +1,72 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudWaspDestroyed
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/02/05 TChu Created
+//
+//===========================================================================
+
+#ifndef HUDWASPDESTROYED_H
+#define HUDWASPDESTROYED_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/ingame/hudevents/hudeventhandler.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class Page;
+ class Text;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+class HudWaspDestroyed : public HudEventHandler
+{
+public:
+ HudWaspDestroyed( Scrooby::Page* pPage );
+ virtual ~HudWaspDestroyed();
+
+ virtual void Start();
+ virtual void Stop();
+ virtual void Update( float elapsedTime );
+
+ void SetGagInsteadOfWasp( bool isGagInsteadOfWasp );
+
+private:
+ enum eSubState
+ {
+ STATE_WASP_TRANSITION_IN,
+ STATE_WASP_DISPLAY_HOLD,
+ STATE_WASP_TRANSITION_OUT,
+
+ NUM_SUB_STATES
+ };
+
+ unsigned int m_currentSubState;
+
+ Scrooby::Text* m_itemsComplete;
+
+ // re-use this event handler for gags
+ //
+ bool m_isGagInsteadOfWasp : 1;
+
+};
+
+inline void HudWaspDestroyed::SetGagInsteadOfWasp( bool isGagInsteadOfWasp )
+{
+ m_isGagInsteadOfWasp = isGagInsteadOfWasp;
+}
+
+#endif // HUDWASPDESTROYED_H
diff --git a/game/code/presentation/gui/minigame/allminigame.cpp b/game/code/presentation/gui/minigame/allminigame.cpp
new file mode 100644
index 0000000..b727b65
--- /dev/null
+++ b/game/code/presentation/gui/minigame/allminigame.cpp
@@ -0,0 +1,5 @@
+#include <presentation/gui/minigame/guimanagerminigame.cpp>
+#include <presentation/gui/minigame/guiscreenminimenu.cpp>
+#include <presentation/gui/minigame/guiscreenminihud.cpp>
+#include <presentation/gui/minigame/guiscreenminipause.cpp>
+#include <presentation/gui/minigame/guiscreenminisummary.cpp>
diff --git a/game/code/presentation/gui/minigame/guimanagerminigame.cpp b/game/code/presentation/gui/minigame/guimanagerminigame.cpp
new file mode 100644
index 0000000..0392273
--- /dev/null
+++ b/game/code/presentation/gui/minigame/guimanagerminigame.cpp
@@ -0,0 +1,491 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiManagerMiniGame
+//
+// Description: Implementation of the CGuiManagerMiniGame class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/24 TChu Created
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/minigame/guimanagerminigame.h>
+#include <presentation/gui/guiwindow.h> // for window IDs
+
+#include <presentation/gui/guiscreenprompt.h>
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/minigame/guiscreenminimenu.h>
+#include <presentation/gui/minigame/guiscreenminihud.h>
+#include <presentation/gui/minigame/guiscreenminipause.h>
+#include <presentation/gui/minigame/guiscreenminisummary.h>
+#include <presentation/gui/guiscreenmessage.h>
+
+#include <gameflow/gameflow.h>
+#include <memory/srrmemory.h>
+#include <loading/loadingmanager.h>
+
+#include <p3d/utility.hpp>
+#include <p3d/inventory.hpp>
+#include <raddebug.hpp> // Foundation
+
+#include <input/inputmanager.h>
+
+#include <main/platform.h>
+#include <main/game.h>
+#include <contexts/supersprint/supersprintcontext.h>
+#include <supersprint/supersprintmanager.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const char* MINIGAME_CHARACTERS_INVENTORY = "FE_MiniGameCharacters";
+
+const char* CHARACTER_FILES[] =
+{
+ "art\\chars\\homer_m.p3d",
+ "art\\chars\\bart_m.p3d",
+ "art\\chars\\lisa_m.p3d",
+ "art\\chars\\marge_m.p3d",
+ "art\\chars\\apu_m.p3d",
+
+ ""
+};
+
+const int NUM_CHARACTER_FILES = sizeof( CHARACTER_FILES ) / sizeof( CHARACTER_FILES[ 0 ] ) - 1;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiManagerMiniGame::CGuiManagerMiniGame
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiManagerMiniGame::CGuiManagerMiniGame( Scrooby::Project* pProject,
+ CGuiEntity* pParent )
+: CGuiManager( pProject, pParent ),
+ m_isQuittingToSupersprint( false ),
+ m_controllerPromptShown( false ),
+ m_isControllerReconnected( false ),
+ m_lastControllerDisconnectedId( -1 )
+{
+ p3d::inventory->AddSection( MINIGAME_CHARACTERS_INVENTORY );
+}
+
+//===========================================================================
+// CGuiManagerMiniGame::~CGuiManagerMiniGame
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiManagerMiniGame::~CGuiManagerMiniGame()
+{
+ p3d::inventory->DeleteSection( MINIGAME_CHARACTERS_INVENTORY );
+}
+
+//===========================================================================
+// CGuiManagerMiniGame::Populate
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiManagerMiniGame::Populate()
+{
+MEMTRACK_PUSH_GROUP( "CGuiManagerMiniGame" );
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ Scrooby::Screen* pScroobyScreen = NULL;
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "Prompt" );
+ if( pScroobyScreen != NULL )
+ {
+ CGuiScreen* pScreen = new CGuiScreenPrompt( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_GENERIC_PROMPT, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MiniMenu" );
+ if( pScroobyScreen != NULL )
+ {
+ CGuiScreen* pScreen = new CGuiScreenMiniMenu( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MINI_MENU, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MiniHud" );
+ if( pScroobyScreen != NULL )
+ {
+ CGuiScreen* pScreen = new CGuiScreenMiniHud( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MINI_HUD, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MiniPause" );
+ if( pScroobyScreen != NULL )
+ {
+ CGuiScreen* pScreen = new CGuiScreenMiniPause( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MINI_PAUSE, pScreen );
+ }
+
+ pScroobyScreen = m_pScroobyProject->GetScreen( "MiniSummary" );
+ if( pScroobyScreen != NULL )
+ {
+ CGuiScreen* pScreen = new CGuiScreenMiniSummary( pScroobyScreen, this );
+ this->AddWindow( CGuiWindow::GUI_SCREEN_ID_MINI_SUMMARY, pScreen );
+ }
+
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+MEMTRACK_POP_GROUP("CGuiManagerMiniGame");
+}
+
+void
+CGuiManagerMiniGame::Start( CGuiWindow::eGuiWindowID initialWindow )
+{
+ rAssert( GUI_FE_UNINITIALIZED == m_state );
+
+ m_nextScreen = initialWindow != CGuiWindow::GUI_WINDOW_ID_UNDEFINED ?
+ initialWindow :
+ CGuiWindow::GUI_SCREEN_ID_MINI_MENU;
+
+ m_state = GUI_FE_CHANGING_SCREENS; // must be set before calling GotoScreen()
+
+ CGuiScreen* nextScreen = static_cast<CGuiScreen*>( this->FindWindowByID( m_nextScreen ) );
+ rAssert( nextScreen != NULL );
+ m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this );
+}
+
+//===========================================================================
+// CGuiManagerMiniGame::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CGuiManagerMiniGame::HandleMessage( eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2 )
+{
+ switch( message )
+ {
+ case GUI_MSG_WINDOW_FINISHED:
+ {
+ if( GUI_FE_CHANGING_SCREENS == m_state )
+ {
+ m_currentScreen = m_nextScreen;
+
+ CGuiScreen* nextScreen = static_cast<CGuiScreen*>( this->FindWindowByID( m_nextScreen ) );
+ rAssert( nextScreen != NULL );
+ m_pScroobyProject->GotoScreen( nextScreen->GetScroobyScreen(), this );
+ }
+ else if( GUI_FE_SHUTTING_DOWN == m_state )
+ {
+ if( m_isQuittingToSupersprint )
+ {
+ // quit and start loading supersprint mini-game
+ //
+ GetGameFlow()->SetContext( CONTEXT_LOADING_SUPERSPRINT );
+
+ m_state = GUI_FE_UNINITIALIZED;
+ }
+ else
+ {
+ // quit mini-game mode and return to front-end
+ //
+ GetGameFlow()->SetContext( CONTEXT_FRONTEND );
+
+ m_state = GUI_FE_TERMINATED;
+ }
+ }
+
+ break;
+ }
+ case GUI_MSG_QUIT_MINIGAME:
+ {
+ rAssert( GUI_FE_SCREEN_RUNNING == m_state );
+
+ m_state = GUI_FE_SHUTTING_DOWN;
+
+ m_isQuittingToSupersprint = (param1 > 0 );
+
+ // Tell the current screen to shut down.
+ //
+ this->FindWindowByID( m_currentScreen )->HandleMessage( GUI_MSG_WINDOW_EXIT );
+
+ break;
+ }
+
+ case GUI_MSG_CONTROLLER_DISCONNECT:
+#ifndef RAD_GAMECUBE
+ this->OnControllerDisconnected( static_cast<int>( param1 ) );
+#endif // !RAD_GAMECUBE
+ break;
+
+ case GUI_MSG_CONTROLLER_CONNECT:
+#ifndef RAD_GAMECUBE
+ m_oldControllerState = InputManager::GetInstance()->GetGameState();
+ if( m_oldControllerState == Input::ACTIVE_ANIM_CAM )
+ {
+ // deactivate anim cam state first, since the input manager
+ // won't let us set the game state to anything else prior
+ // to that
+ //
+ GetInputManager()->SetGameState( Input::DEACTIVE_ANIM_CAM );
+ }
+ GetInputManager()->SetGameState( Input::ACTIVE_FRONTEND );
+#endif // !RAD_GAMECUBE
+ break;
+ default:
+ {
+ if( message == GUI_MSG_UPDATE && m_isControllerReconnected )
+ {
+ m_isControllerReconnected = false;
+ m_controllerPromptShown = false;
+ }
+
+ if (m_controllerPromptShown) // don't pass event if controller error
+ {
+ if (message==GUI_MSG_CONTROLLER_START) // start trigger reconnection
+ {
+ this->OnControllerConnected( static_cast<int>( param1 ) );
+ }
+
+ break;
+ }
+
+ if( m_state != GUI_FE_UNINITIALIZED &&
+ m_currentScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED )
+ {
+ // Send the messages down to the current screen.
+ //
+ CGuiWindow* pScreen = this->FindWindowByID( m_currentScreen );
+ rAssert( pScreen != NULL );
+ pScreen->HandleMessage( message, param1, param2 );
+ }
+#ifndef RAD_GAMECUBE
+ if ( message == GUI_MSG_UPDATE)
+ PollControllers();
+#endif
+ break;
+ }
+ }
+
+ // propogate message up the hierarchy
+ //
+ CGuiManager::HandleMessage( message, param1, param2 );
+}
+
+void
+CGuiManagerMiniGame::OnControllerDisconnected( int controllerID, bool force_display )
+{
+ if (force_display) // update message
+ {
+ m_lastControllerDisconnectedId = controllerID;
+ char str_buffer[256];
+ CGuiScreenMessage::GetControllerDisconnectedMessage(controllerID, str_buffer, 255);
+ GetGame()->GetPlatform()->OnControllerError(str_buffer);
+ m_controllerPromptShown = true;
+ }
+ else if (m_controllerPromptShown) // check if this disconnection id is for the player already registered
+ {
+ for (int i = 0; i < SuperSprintData::NUM_PLAYERS; i++)
+ {
+ int player_controllerID = GetInputManager()->GetControllerIDforPlayer( i );
+ if (controllerID == player_controllerID)
+ {
+ m_lastControllerDisconnectedId = controllerID;
+ char str_buffer[256];
+ CGuiScreenMessage::GetControllerDisconnectedMessage(controllerID, str_buffer, 255);
+ GetGame()->GetPlatform()->OnControllerError(str_buffer);
+ m_controllerPromptShown = true;
+ }
+ }
+ }
+
+}
+bool
+CGuiManagerMiniGame::PollControllers()
+{
+ bool all_ok = true;
+ bool has_registered = false;
+
+ if ( GetGameFlow()->GetCurrentContext()==CONTEXT_SUPERSPRINT
+ && GetGameFlow()->GetContext( CONTEXT_SUPERSPRINT )->IsSuspended() ) // minigame pause menu
+ {
+ int controllerID = CGuiScreenMiniHud::s_pausedControllerID;
+ if (controllerID >= 0)
+ {
+ has_registered = true;
+ if( !GetInputManager()->GetController( controllerID )->IsConnected() )
+ {
+ OnControllerDisconnected(controllerID, true);
+ all_ok = false;
+ }
+ }
+ }
+ else
+ { // minigame game, or minigame menu
+ for (int i = 0; i < SuperSprintData::NUM_PLAYERS; i++)
+ {
+ int controllerID = GetInputManager()->GetControllerIDforPlayer( i );
+ if (controllerID >= 0)
+ {
+ has_registered = true;
+ if( !GetInputManager()->GetController( controllerID )->IsConnected() )
+ {
+ OnControllerDisconnected(controllerID, true);
+ all_ok = false;
+ break;
+ }
+ }
+ }
+ }
+ if (all_ok) {
+ if (has_registered == false) // minigame menu but no one registered yet
+ {
+ int controllerID = GetGuiSystem()->GetPrimaryController( );
+ if (controllerID >= 0)
+ {
+ if( !GetInputManager()->GetController( controllerID )->IsConnected() )
+ {
+ OnControllerDisconnected(controllerID, true);
+ all_ok = false;
+ }
+ }
+ }
+ }
+
+ if (all_ok)
+ {
+ m_isControllerReconnected = true;
+// m_controllerPromptShown = false;
+ }
+ return all_ok;
+
+}
+
+void
+CGuiManagerMiniGame::OnControllerConnected( int controllerID )
+{
+ if (controllerID==m_lastControllerDisconnectedId)
+ { // poll
+ bool all_ok = PollControllers();
+ if (all_ok)
+ {
+ GetGame()->GetPlatform()->ClearControllerError();
+ GetSSM()->RestoreControllerState();
+
+ if ( GetGameFlow()->GetCurrentContext()==CONTEXT_SUPERSPRINT )
+ {
+#ifdef RAD_XBOX
+ CGuiScreenMiniHud::s_pausedControllerID = controllerID;
+
+ if( GetSSM()->GetState() != SuperSprintManager::IDLE )
+ {
+ this->HandleMessage( GUI_MSG_GOTO_SCREEN, CGuiWindow::GUI_SCREEN_ID_MINI_PAUSE );
+ }
+
+ GetGameFlow()->GetContext( CONTEXT_SUPERSPRINT )->Suspend();
+
+ if (GetSSM()->GetState()==SuperSprintManager::COUNT_DOWN)
+ {
+ InputManager::GetInstance()->SetGameState( Input::DEACTIVE_ANIM_CAM );
+ InputManager::GetInstance()->SetGameState( Input::ACTIVE_FRONTEND );
+ }
+ else
+ {
+ InputManager::GetInstance()->SetGameState( Input::DEACTIVE_ANIM_CAM );
+ InputManager::GetInstance()->SetGameState( Input::ACTIVE_ALL );
+ }
+#endif
+ }
+
+ m_isControllerReconnected = true;
+// m_controllerPromptShown = false;
+ m_lastControllerDisconnectedId = -1;
+ }
+ }
+}
+
+//===========================================================================
+// CGuiManagerMiniGame::LoadCharacters
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void
+CGuiManagerMiniGame::LoadCharacters()
+{
+ GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D,
+ "art\\chars\\global.p3d",
+ GMA_LEVEL_HUD,
+ MINIGAME_CHARACTERS_INVENTORY,
+ MINIGAME_CHARACTERS_INVENTORY );
+
+ for( int i = 0; i < NUM_CHARACTER_FILES; i++ )
+ {
+ GetLoadingManager()->AddRequest( FILEHANDLER_PURE3D,
+ CHARACTER_FILES[ i ],
+ GMA_LEVEL_HUD,
+ MINIGAME_CHARACTERS_INVENTORY,
+ MINIGAME_CHARACTERS_INVENTORY );
+ }
+}
+
+//===========================================================================
+// CGuiManagerMiniGame::UnloadCharacters
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void
+CGuiManagerMiniGame::UnloadCharacters()
+{
+ p3d::pddi->DrawSync();
+ p3d::inventory->RemoveSectionElements( MINIGAME_CHARACTERS_INVENTORY );
+}
+
+//===========================================================================
+// Private Member Functions
+//===========================================================================
+
diff --git a/game/code/presentation/gui/minigame/guimanagerminigame.h b/game/code/presentation/gui/minigame/guimanagerminigame.h
new file mode 100644
index 0000000..b4534e2
--- /dev/null
+++ b/game/code/presentation/gui/minigame/guimanagerminigame.h
@@ -0,0 +1,71 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiManagerMiniGame
+//
+// Description: Interface for the CGuiManagerMiniGame class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/24 TChu Created
+//
+//===========================================================================
+
+#ifndef GUIMANAGERMINIGAME_H
+#define GUIMANAGERMINIGAME_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guimanager.h>
+#include <input/inputmanager.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiManagerMiniGame : public CGuiManager
+{
+public:
+ CGuiManagerMiniGame( Scrooby::Project* pProject, CGuiEntity* pParent );
+ virtual ~CGuiManagerMiniGame();
+
+ virtual void Populate();
+ virtual void Start( CGuiWindow::eGuiWindowID initialWindow = CGuiWindow::GUI_WINDOW_ID_UNDEFINED );
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ static void LoadCharacters();
+ static void UnloadCharacters();
+
+private:
+ //---------------------------------------------------------------------
+ // Private Functions
+ //---------------------------------------------------------------------
+
+ // No copying or assignment. Declare but don't define.
+ //
+ CGuiManagerMiniGame( const CGuiManagerMiniGame& );
+ CGuiManagerMiniGame& operator= ( const CGuiManagerMiniGame& );
+
+ void OnControllerDisconnected( int controllerID, bool force_display = false );
+ void OnControllerConnected( int controllerID );
+ bool PollControllers();
+ //---------------------------------------------------------------------
+ // Private Data
+ //---------------------------------------------------------------------
+
+ bool m_isQuittingToSupersprint : 1;
+ bool m_controllerPromptShown : 1;
+ bool m_isControllerReconnected : 1;
+ int m_lastControllerDisconnectedId;
+ Input::ActiveState m_oldControllerState;
+
+};
+
+#endif // GUIMANAGERMINIGAME_H
diff --git a/game/code/presentation/gui/minigame/guiscreenminihud.cpp b/game/code/presentation/gui/minigame/guiscreenminihud.cpp
new file mode 100644
index 0000000..88a9904
--- /dev/null
+++ b/game/code/presentation/gui/minigame/guiscreenminihud.cpp
@@ -0,0 +1,217 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMiniHud
+//
+// Description: Implementation of the CGuiScreenMiniHud class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/24 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/minigame/guiscreenminihud.h>
+#include <presentation/gui/guimanager.h>
+
+#include <contexts/supersprint/supersprintcontext.h>
+#include <gameflow/gameflow.h>
+
+#ifdef RAD_WIN32
+#include <input/inputmanager.h>
+#endif
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+int CGuiScreenMiniHud::s_pausedControllerID = -1;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenMiniHud::CGuiScreenMiniHud
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMiniHud::CGuiScreenMiniHud
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MINI_HUD )
+{
+}
+
+
+//===========================================================================
+// CGuiScreenMiniHud::~CGuiScreenMiniHud
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMiniHud::~CGuiScreenMiniHud()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenMiniHud::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniHud::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+#ifdef RAD_WIN32
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ if( GetInputManager()->GetValue( 0, InputManager::KeyboardEsc ) > 0.0f )
+ {
+ //GOOD! Fall through.
+ }
+ else
+ {
+ break;
+ }
+ }
+#endif
+ case GUI_MSG_CONTROLLER_START:
+ {
+ // pause mini-game
+ //
+ GetGameFlow()->GetContext( CONTEXT_SUPERSPRINT )->Suspend();
+
+ // go to pause menu
+ //
+ s_pausedControllerID = static_cast<int>( param1 );
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MINI_PAUSE );
+
+ break;
+ }
+/*
+ // TC: *** for testing only ***
+ //
+ case GUI_MSG_CONTROLLER_AUX_X:
+ case GUI_MSG_CONTROLLER_AUX_Y:
+ {
+ // go to Race Summary screen
+ //
+ GetGameFlow()->GetContext( CONTEXT_SUPERSPRINT )->Suspend();
+
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MINI_SUMMARY );
+
+ break;
+ }
+*/
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenMiniHud::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniHud::InitIntro()
+{
+#ifdef RAD_WIN32
+ GetInputManager()->GetFEMouse()->SetInGameMode( true );
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenMiniHud::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniHud::InitRunning()
+{
+ if( GetGameFlow()->GetContext( CONTEXT_SUPERSPRINT )->IsSuspended() )
+ {
+ // resume mini-game
+ //
+ GetGameFlow()->GetContext( CONTEXT_SUPERSPRINT )->Resume();
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMiniHud::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniHud::InitOutro()
+{
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
diff --git a/game/code/presentation/gui/minigame/guiscreenminihud.h b/game/code/presentation/gui/minigame/guiscreenminihud.h
new file mode 100644
index 0000000..b36c436
--- /dev/null
+++ b/game/code/presentation/gui/minigame/guiscreenminihud.h
@@ -0,0 +1,52 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMiniHud
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/24 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMINIHUD_H
+#define GUISCREENMINIHUD_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMiniHud : public CGuiScreen
+{
+public:
+ CGuiScreenMiniHud( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenMiniHud();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ // controller ID of user that paused mini-game
+ //
+ static int s_pausedControllerID;
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+};
+
+#endif // GUISCREENMINIHUD_H
diff --git a/game/code/presentation/gui/minigame/guiscreenminimenu.cpp b/game/code/presentation/gui/minigame/guiscreenminimenu.cpp
new file mode 100644
index 0000000..69e5db0
--- /dev/null
+++ b/game/code/presentation/gui/minigame/guiscreenminimenu.cpp
@@ -0,0 +1,1633 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMiniMenu
+//
+// Description: Implementation of the CGuiScreenMiniMenu class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/24 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/minigame/guiscreenminimenu.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <presentation/gui/guimenu.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/guiuserinputhandler.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/gui/guiscreenprompt.h>
+
+#include <cards/cardgallery.h>
+#include <events/eventmanager.h>
+#include <input/inputmanager.h>
+#include <memory/srrmemory.h>
+#include <mission/gameplaymanager.h>
+#include <mission/rewards/rewardsmanager.h>
+#include <mission/rewards/reward.h>
+#include <render/enums/renderenums.h>
+#include <supersprint/supersprintmanager.h>
+#include <supersprint/supersprintdata.h>
+
+// Scrooby
+//
+#include <screen.h>
+#include <page.h>
+#include <layer.h>
+#include <group.h>
+#include <sprite.h>
+#include <text.h>
+#include <pure3dobject.h>
+#include <polygon.h>
+
+// ATG
+//
+#include <p3d/camera.hpp>
+#include <p3d/utility.hpp>
+#include <raddebug.hpp>
+
+#include <string.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const float NUM_LAPS_ARROW_ROTATION = 90.0f; // in degrees
+const float NUM_LAPS_ARROW_GREY_OUT_ALPHA = 0.5f;
+
+#ifdef RAD_WIN32
+const float CHARACTER_SCALE = 0.67f;
+const float VEHICLE_SCALE = 0.5f;
+const float CHARACTER_ARROW_SCALE = 0.45f;
+const float VEHICLE_ARROW_SCALE = 0.85f;
+const float NUM_LAPS_ARROW_SCALE = 0.375f; // scale arrows down a bit
+#else
+const float NUM_LAPS_ARROW_SCALE = 0.75f; // scale arrows down a bit
+#endif
+
+PlayerMenu::PlayerMenu()
+: m_currentSubMenu( 0 ),
+ m_controllerID( -1 ),
+ m_pressStart( NULL ),
+ m_vehicleRating( NULL ),
+ m_characterSelectedIcon( NULL ),
+ m_vehicleSelectedIcon( NULL )
+{
+ memset( m_pMenu, 0, sizeof( m_pMenu ) );
+}
+
+void
+PlayerMenu::HandleMessage( eGuiMessage message, unsigned int param1,
+ unsigned int param2 )
+{
+ if( m_currentSubMenu < NUM_SUB_MENUS )
+ {
+ rAssert( m_currentSubMenu >= 0 );
+ m_pMenu[ m_currentSubMenu ]->HandleMessage( message, param1, param2 );
+ }
+}
+
+CGuiMenu*
+PlayerMenu::GetCurrentSubMenu() const
+{
+ if( m_currentSubMenu < NUM_SUB_MENUS )
+ {
+ rAssert( m_currentSubMenu >= 0 );
+ return m_pMenu[ m_currentSubMenu ];
+ }
+
+ return NULL;
+}
+
+void
+PlayerMenu::SetActive( bool isActive, int controllerID )
+{
+ m_controllerID = isActive ? controllerID : -1;
+
+ // hide/show press start text
+ //
+ rAssert( m_pressStart != NULL );
+ m_pressStart->SetVisible( !isActive );
+
+ // show/hide player cursor
+ //
+ rAssert( m_pMenu[ MENU_CHARACTERS ] != NULL );
+ m_pMenu[ MENU_CHARACTERS ]->GetCursor()->SetVisible( isActive );
+
+ // show/hide vehicle rating
+ //
+ if( m_vehicleRating != NULL )
+ {
+ m_vehicleRating->SetVisible( isActive );
+ }
+
+ // reset vehicle selection
+ //
+ rAssert( m_pMenu[ MENU_VEHICLES ] != NULL );
+ m_pMenu[ MENU_VEHICLES ]->SetSelectionValue( 0, 0 );
+ m_pMenu[ MENU_VEHICLES ]->SetMenuItemEnabled( 0, isActive, true );
+
+ // turn off selected icons
+ //
+ rAssert( m_characterSelectedIcon != NULL );
+ m_characterSelectedIcon->SetAlpha( 0.0f );
+
+ rAssert( m_vehicleSelectedIcon != NULL );
+ m_vehicleSelectedIcon->SetAlpha( 0.0f );
+
+ // set controller ID for vehicle selection menu
+ //
+ m_pMenu[ MENU_VEHICLES ]->SetControllerID( controllerID );
+
+ // reset current sub-menu
+ //
+ m_currentSubMenu = 0;
+
+
+}
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenMiniMenu::CGuiScreenMiniMenu
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMiniMenu::CGuiScreenMiniMenu
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MINI_MENU ),
+// m_screenState( SCREEN_STATE_NORMAL ),
+ m_pTrackMenu( NULL ),
+ m_trackDirection( NULL ),
+ m_trackNumLaps( NULL ),
+ m_trackNumLapsArrowU( NULL ),
+ m_trackNumLapsArrowD( NULL ),
+ m_trackCursorBgd( NULL ),
+ m_elapsedTime( 0 ),
+ m_backLabel( NULL ),
+ m_numActivePlayers( 0 ),
+ m_numActivePlayersDone( 0 ),
+ m_characterSlots( 0 ),
+ m_numUnlockedVehicles( 0 ),
+ m_optionsButton( NULL ),
+#ifdef RAD_WIN32
+ m_currentTrack(0),
+ m_bTrackSelected(false),
+#endif
+// m_optionsOverlay( NULL ),
+// m_optionsMenu( NULL ),
+ m_characterSelectInfo( NULL ),
+ m_timerOverlay( NULL ),
+ m_remainingTime( TIMER_WAIT_TIME )
+{
+ memset( m_unlockedVehicles, 0, sizeof( m_unlockedVehicles ) );
+
+#ifdef MINI_MENU_SHOW_3D_CHARACTERS
+ memset( m_3dCharacters, 0, sizeof( m_3dCharacters ) );
+#endif
+
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "MiniMenu" );
+ rAssert( pPage != NULL );
+
+ int i = 0;
+ char name[ 32 ];
+ Scrooby::Group* pGroup = NULL;
+
+ // create sub menu for tracks (only one needed for all players)
+ //
+ m_pTrackMenu = new CGuiMenu2D( this, NUM_TRACKS, NUM_TRACKS, GUI_SPRITE_MENU, MENU_SFX_NONE );
+ rAssert( m_pTrackMenu != NULL );
+
+ // add tracks to menu
+ //
+ pGroup = pPage->GetGroup( "Tracks" );
+ rAssert( pGroup != NULL );
+ for( i = 0; i < NUM_TRACKS; i++ )
+ {
+ sprintf( name, "Track%d", i );
+ m_pTrackMenu->AddMenuItem( pGroup->GetSprite( name ) );
+ }
+
+ if( this->IsWideScreenDisplay() )
+ {
+ ApplyWideScreenCorrectionScale( pGroup );
+ }
+
+ // add track cursor
+ //
+ Scrooby::Group* pGroupCursor = pGroup->GetGroup( "TrackCursor" );
+ rAssert( pGroupCursor != NULL );
+ m_pTrackMenu->SetCursor( pGroupCursor );
+
+ // get track cursor background
+ //
+ m_trackCursorBgd = pGroup->GetPolygon( "TrackBgd" );
+
+ // get track num laps and direction
+ //
+ m_trackNumLaps = pGroupCursor->GetText( "NumLaps" );
+ m_trackDirection = pGroupCursor->GetSprite( "Direction" );
+
+ rAssert( m_trackNumLaps != NULL );
+ m_trackNumLaps->SetIndex( SuperSprintData::DEFAULT_NUM_LAPS );
+
+ // rotate num laps arrows (90 deg CW) so they point up and down, respectively
+ //
+ m_trackNumLapsArrowU = pGroupCursor->GetSprite( "NumLaps_LArrow" );
+ if( m_trackNumLapsArrowU != NULL )
+ {
+ m_trackNumLapsArrowU->ResetTransformation();
+ m_trackNumLapsArrowU->ScaleAboutCenter( NUM_LAPS_ARROW_SCALE );
+ m_trackNumLapsArrowU->RotateAboutCenter( NUM_LAPS_ARROW_ROTATION );
+ }
+
+ m_trackNumLapsArrowD = pGroupCursor->GetSprite( "NumLaps_RArrow" );
+ if( m_trackNumLapsArrowD != NULL )
+ {
+ m_trackNumLapsArrowD->ResetTransformation();
+ m_trackNumLapsArrowD->ScaleAboutCenter( NUM_LAPS_ARROW_SCALE );
+ m_trackNumLapsArrowD->RotateAboutCenter( NUM_LAPS_ARROW_ROTATION );
+ }
+
+ // prepare vehicle selections (only unlocked vehicles are selectable by players)
+ //
+ this->PrepareVehicleSelections();
+
+ // if no vehicles are unlocked, just add the L1 default vehicle so there's at least one vehicle
+ // to choose from
+ //
+ if( m_numUnlockedVehicles == 0 )
+ {
+ m_unlockedVehicles[ 0 ] = GetRewardsManager()->GetReward( RenderEnums::L1, Reward::eDefaultCar );
+ m_numUnlockedVehicles++;
+ }
+
+ rAssertMsg( m_numUnlockedVehicles > 0, "There aren't any unlocked vehicles to choose from!" );
+
+ // get back label
+ //
+ rAssert( m_buttonIcons[ BUTTON_ICON_BACK ] != NULL );
+ m_backLabel = m_buttonIcons[ BUTTON_ICON_BACK ]->GetText( "Back" );
+ rAssert( m_backLabel != NULL );
+
+ // create player-specific menus
+ //
+ for( int p = 0; p < SuperSprintData::NUM_PLAYERS; p++ )
+ {
+ // create sub menu for characters
+ //
+ m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ] = new CGuiMenu2D( this,
+ NUM_CHARACTERS,
+ NUM_CHARACTERS,
+ GUI_SPRITE_MENU,
+ MENU_SFX_NONE );
+
+ rAssert( m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ] != NULL );
+ m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->SetGreyOutEnabled( false );
+
+ // add character slots to menu
+ //
+ pGroup = pPage->GetGroup( "Characters" );
+ rAssert( pGroup != NULL );
+ for( i = 0; i < NUM_CHARACTERS; i++ )
+ {
+ sprintf( name, "Character%d", i );
+ Scrooby::Sprite* characterImage = pGroup->GetSprite( name );
+#ifdef RAD_WIN32
+ characterImage->ResetTransformation();
+ characterImage->ScaleAboutCenter( CHARACTER_SCALE );
+#endif
+ m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->AddMenuItem( characterImage,
+ characterImage );
+ }
+
+ // get player cursor
+ //
+ sprintf( name, "Player%d", p );
+ pGroupCursor = pGroup->GetGroup( name );
+ rAssert( pGroupCursor != NULL );
+ m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->SetCursor( pGroupCursor );
+
+ // set player-specific colour to cursor
+ //
+ pGroupCursor->GetText( name )->SetColour( SuperSprintData::PLAYER_COLOURS[ p ] );
+
+ // get character selected icon
+ //
+ sprintf( name, "Player%d_Selected", p );
+ m_playerMenus[ p ].m_characterSelectedIcon = pGroupCursor->GetSprite( name );
+
+ // create sub menu for vehicles
+ //
+ m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ] = new CGuiMenu( this,
+ 1,
+ GUI_SPRITE_MENU,
+ MENU_SFX_NONE );
+
+ rAssert( m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ] != NULL );
+ m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->SetHighlightColour( false, tColour( 0, 0, 0 ) );
+// m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->SetSelectionMadeOutlineColour( tColour( 0, 0, 0, 192 ) );
+
+ // add vehicle selections to menu
+ //
+ pGroup = pPage->GetGroup( "Vehicles" );
+ rAssert( pGroup != NULL );
+
+ // get press start text
+ //
+ sprintf( name, "PressStart%d", p );
+ m_playerMenus[ p ].m_pressStart = pGroup->GetText( name );
+ rAssert( m_playerMenus[ p ].m_pressStart != NULL );
+ m_playerMenus[ p ].m_pressStart->SetTextMode( Scrooby::TEXT_WRAP );
+ m_playerMenus[ p ].m_pressStart->ScaleAboutCenter( 0.9f );
+ m_playerMenus[ p ].m_pressStart->SetVisible( false ); // hide by default
+
+ sprintf( name, "Vehicle%d_Value", p );
+ Scrooby::Sprite* vehicleImage = pGroup->GetSprite( name );
+ sprintf( name, "Vehicle%d_LArrow", p );
+ Scrooby::Sprite* vehicleImageLArrow = pGroup->GetSprite( name );
+ sprintf( name, "Vehicle%d_RArrow", p );
+ Scrooby::Sprite* vehicleImageRArrow = pGroup->GetSprite( name );
+
+#ifdef RAD_WIN32
+ vehicleImage->ScaleAboutCenter( VEHICLE_SCALE );
+ vehicleImageLArrow->ResetTransformation();
+ vehicleImageRArrow->ResetTransformation();
+ vehicleImageLArrow->ScaleAboutCenter( VEHICLE_ARROW_SCALE );
+ vehicleImageRArrow->ScaleAboutCenter( VEHICLE_ARROW_SCALE );
+#endif
+
+ m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->AddMenuItem( vehicleImage,
+ vehicleImage,
+ NULL,
+ NULL,
+ vehicleImageLArrow,
+ vehicleImageRArrow );
+
+ m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->SetSelectionValueCount( 0, m_numUnlockedVehicles );
+
+ // get vehicle cursor
+ //
+ sprintf( name, "Vehicle%d", p );
+ pGroupCursor = pGroup->GetGroup( name );
+ rAssert( pGroupCursor != NULL );
+ m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->SetCursor( pGroupCursor );
+
+ // set player-specific colour to cursor
+ //
+ pGroupCursor->GetText( name )->SetColour( SuperSprintData::PLAYER_COLOURS[ p ] );
+
+ // get vehicle selected icon
+ //
+ sprintf( name, "Vehicle%d_Selected", p );
+ m_playerMenus[ p ].m_vehicleSelectedIcon = pGroupCursor->GetSprite( name );
+
+ // get vehicle rating
+ //
+ sprintf( name, "Vehicle%d_Rating", p );
+ m_playerMenus[ p ].m_vehicleRating = pGroup->GetSprite( name );
+
+#ifdef RAD_WIN32
+ m_playerMenus[ p ].m_vehicleRating->ScaleAboutCenter( 0.5f );
+#endif
+
+ this->UpdateVehicleDisplayImages( p, vehicleImage );
+ }
+
+ // get 3D character models
+ //
+#ifdef MINI_MENU_SHOW_3D_CHARACTERS
+ pGroup = pPage->GetGroup( "Characters" );
+ rAssert( pGroup != NULL );
+ for( i = 0; i < NUM_CHARACTERS; i++ )
+ {
+ sprintf( name, "Character%d", i );
+ m_3dCharacters[ i ] = pGroup->GetPure3dObject( name );
+ rAssert( m_3dCharacters[ i ] != NULL );
+ m_3dCharacters[ i ]->SetClearDepthBuffer( true );
+ }
+#endif // MINI_MENU_SHOW_3D_CHARACTERS
+
+ // get options overlay stuff
+ //
+ m_optionsButton = pPage->GetGroup( "Options" );
+ rAssert( m_optionsButton != NULL );
+
+ Scrooby::Text* optionsText = m_optionsButton->GetText( "Options" );
+ if( optionsText != NULL )
+ {
+ optionsText->SetTextMode( Scrooby::TEXT_WRAP );
+ }
+
+ if( this->IsWideScreenDisplay() )
+ {
+ ApplyWideScreenCorrectionScale( m_optionsButton );
+ }
+/*
+ m_optionsOverlay = pPage->GetLayer( "Options" );
+ rAssert( m_optionsOverlay != NULL );
+
+ // create options menu
+ //
+ m_optionsMenu = new CGuiMenu( this, NUM_OPTIONS_MENU_ITEMS );
+ rAssert( m_optionsMenu != NULL );
+
+ // add menu items to options menu
+ //
+ pGroup = pPage->GetGroup( "OptionsMenu" );
+ rAssert( pGroup != NULL );
+
+ m_optionsMenu->AddMenuItem( pGroup->GetText( "NumLaps" ),
+ pGroup->GetText( "NumLaps_Value" ),
+ NULL,
+ NULL,
+ pGroup->GetSprite( "NumLaps_ArrowL" ),
+ pGroup->GetSprite( "NumLaps_ArrowR" ),
+ SELECTION_ENABLED | TEXT_OUTLINE_ENABLED );
+
+ m_optionsMenu->AddMenuItem( pGroup->GetText( "ReverseDirection" ),
+ pGroup->GetText( "ReverseDirection_Value" ),
+ NULL,
+ NULL,
+ pGroup->GetSprite( "ReverseDirection_ArrowL" ),
+ pGroup->GetSprite( "ReverseDirection_ArrowR" ),
+ SELECTION_ENABLED | VALUES_WRAPPED | TEXT_OUTLINE_ENABLED );
+*/
+
+ // get character select info
+ //
+ m_characterSelectInfo = pPage->GetGroup( "CharacterSelectInfo" );
+ if( m_characterSelectInfo != NULL )
+ {
+ m_characterSelectInfo->SetVisible( false ); // hide by default
+ }
+
+#ifdef RAD_WIN32
+ Scrooby::Sprite* arrow = m_characterSelectInfo->GetSprite( "CharacterLArrow" );
+ arrow->ResetTransformation();
+ arrow->ScaleAboutCenter( CHARACTER_ARROW_SCALE );
+ arrow = m_characterSelectInfo->GetSprite( "CharacterRArrow" );
+ arrow->ResetTransformation();
+ arrow->ScaleAboutCenter( CHARACTER_ARROW_SCALE );
+#endif
+
+ // get timer overlay stuff
+ //
+ m_timerOverlay = pPage->GetGroup( "Timer" );
+ rAssert( m_timerOverlay != NULL );
+ m_timerOverlay->SetVisible( false ); // hide by default
+
+ Scrooby::Text* waitingForOtherPlayers = m_timerOverlay->GetText( "WaitingForOtherPlayers" );
+ if( waitingForOtherPlayers != NULL )
+ {
+ waitingForOtherPlayers->SetTextMode( Scrooby::TEXT_WRAP );
+ }
+
+ m_timer.SetScroobyText( m_timerOverlay, "Timer" );
+ m_timer.m_digits[ 0 ]->ResetTransformation();
+ m_timer.m_digits[ 0 ]->ScaleAboutPoint( 1.5f, 0, 0 );
+}
+
+//===========================================================================
+// CGuiScreenMiniMenu::~CGuiScreenMiniMenu
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMiniMenu::~CGuiScreenMiniMenu()
+{
+#ifdef MINI_MENU_SHOW_3D_CHARACTERS
+ // release drawables for 3D characters
+ //
+ for( int c = 0; c < NUM_CHARACTERS; c++ )
+ {
+ if( m_3dCharacters[ c ] != NULL )
+ {
+ m_3dCharacters[ c ]->SetDrawable( NULL );
+ }
+ }
+#endif // MINI_MENU_SHOW_3D_CHARACTERS
+
+ // destroy track menu
+ //
+ if( m_pTrackMenu != NULL )
+ {
+ delete m_pTrackMenu;
+ m_pTrackMenu = NULL;
+ }
+
+ // destroy all player sub-menus
+ //
+ for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ )
+ {
+ for( int j = 0; j < PlayerMenu::NUM_SUB_MENUS; j++ )
+ {
+ if( m_playerMenus[ i ].m_pMenu[ j ] != NULL )
+ {
+ delete m_playerMenus[ i ].m_pMenu[ j ];
+ m_playerMenus[ i ].m_pMenu[ j ] = NULL;
+ }
+ }
+ }
+
+/*
+ // destroy options menu
+ //
+ if( m_optionsMenu != NULL )
+ {
+ delete m_optionsMenu;
+ m_optionsMenu = NULL;
+ }
+*/
+}
+
+//===========================================================================
+// CGuiScreenMiniMenu::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniMenu::HandleMessage( eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2 )
+{
+ if( message == GUI_MSG_MENU_PROMPT_RESPONSE )
+ {
+ rAssert( param1 == PROMPT_CONFIRM_QUIT );
+
+ switch( param2 )
+ {
+ case (CGuiMenuPrompt::RESPONSE_YES):
+ {
+ m_pParent->HandleMessage( GUI_MSG_QUIT_MINIGAME );
+
+ break;
+ }
+ case (CGuiMenuPrompt::RESPONSE_NO):
+ {
+ this->ReloadScreen();
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" );
+
+ break;
+ }
+ }
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ int controllerID = -1;
+ int playerMenuID = -1;
+
+ if( this->IsControllerMessage( message ) )
+ {
+ controllerID = static_cast<int>( param1 );
+ playerMenuID = this->GetPlayerMenuID( controllerID );
+
+ this->UpdateCharacterSlots();
+ }
+
+ if( m_numActivePlayers == 0 )
+ {
+ // relay message to track menu
+ //
+ rAssert( m_pTrackMenu != NULL );
+ m_pTrackMenu->HandleMessage( message, param1, param2 );
+ }
+ else
+ {
+ if( this->IsControllerMessage( message ) )
+ {
+ // relay message ONLY to associated player's current sub-menu
+ //
+ if( playerMenuID != -1 )
+ {
+ m_playerMenus[ playerMenuID ].HandleMessage( message, param1, param2 );
+
+ if( m_playerMenus[ playerMenuID ].m_currentSubMenu == PlayerMenu::MENU_VEHICLES )
+ {
+ this->UpdateVehicleRating( playerMenuID );
+ }
+ }
+ }
+ else
+ {
+ // relay message to all players' current sub-menu
+ //
+ for( int p = 0; p < SuperSprintData::NUM_PLAYERS; p++ )
+ {
+ m_playerMenus[ p ].HandleMessage( message, param1, param2 );
+ }
+ }
+ }
+
+ switch( message )
+ {
+ case GUI_MSG_UPDATE:
+ {
+ this->UpdateCharacterSlots();
+
+ const unsigned int PULSE_PERIOD = 500;
+
+ float alpha = GuiSFX::Pulse( (float)m_elapsedTime,
+ (float)PULSE_PERIOD,
+ 0.6f,
+ 0.4f,
+ -rmt::PI_BY2 );
+
+ if( m_numActivePlayers == 0 ) // track selection state
+ {
+ // pulse cursor bgd alpha
+ //
+ if( m_trackCursorBgd != NULL )
+ {
+ m_trackCursorBgd->SetAlpha( alpha );
+ }
+
+ // update U/D arrows on num laps
+ //
+ if( m_trackNumLapsArrowU != NULL && m_trackNumLapsArrowD != NULL )
+ {
+ m_trackNumLapsArrowU->SetIndex( 0 );
+ m_trackNumLapsArrowD->SetIndex( 0 );
+
+ int numUserInputHandlers = GetGuiSystem()->GetNumUserInputHandlers();
+ for( int i = 0; i < numUserInputHandlers; i++ )
+ {
+ CGuiUserInputHandler* userInputHandler = GetGuiSystem()->GetUserInputHandler( i );
+ if( userInputHandler != NULL )
+ {
+#ifdef RAD_WIN32
+ if( userInputHandler->IsYAxisOnUp() ||
+ GetInputManager()->GetFEMouse()->LeftButtonDownOn() == HOTSPOT_ARROWUP )
+#else
+ if( userInputHandler->IsButtonDown( GuiInput::Up ) ||
+ userInputHandler->IsYAxisOnUp() )
+#endif
+ {
+ rAssert( m_trackNumLapsArrowU->GetNumOfImages() > 1 );
+ m_trackNumLapsArrowU->SetIndex( 1 );
+ }
+
+#ifdef RAD_WIN32
+ if( userInputHandler->IsYAxisOnDown() ||
+ GetInputManager()->GetFEMouse()->LeftButtonDownOn() == HOTSPOT_ARROWDOWN )
+#else
+ if( userInputHandler->IsButtonDown( GuiInput::Down ) ||
+ userInputHandler->IsYAxisOnDown() )
+#endif
+ {
+ rAssert( m_trackNumLapsArrowD->GetNumOfImages() > 1 );
+ m_trackNumLapsArrowD->SetIndex( 1 );
+ }
+ }
+ }
+ }
+ }
+ else // not in track selection state
+ {
+#ifdef RAD_XBOX
+ // re-enable Start-to-Select button mapping
+ //
+ for( int i = 0; i < GetGuiSystem()->GetNumUserInputHandlers(); i++ )
+ {
+ GetGuiSystem()->GetUserInputHandler( i )->EnableStartToSelectMapping( true );
+ }
+#endif // RAD_XBOX
+
+ for( int p = 0; p < SuperSprintData::NUM_PLAYERS; p++ )
+ {
+ // pulse player's current sub-menu cursor
+ //
+ CGuiMenu* currentSubMenu = m_playerMenus[ p ].GetCurrentSubMenu();
+ if( currentSubMenu != NULL )
+ {
+ Scrooby::Drawable* pCursor = currentSubMenu->GetCursor();
+ rAssert( pCursor != NULL );
+ pCursor->SetAlpha( alpha );
+ }
+ }
+ }
+
+ m_elapsedTime += param1;
+ m_elapsedTime %= PULSE_PERIOD;
+
+ rAssert( m_timerOverlay != NULL );
+ if( m_timerOverlay->IsVisible() )
+ {
+ // update timer
+ //
+ m_remainingTime -= static_cast<int>( param1 );
+ if( m_remainingTime > 0 )
+
+ {
+ m_timer.SetValue( static_cast<unsigned int>( m_remainingTime ) / 1000 );
+ }
+ else
+ {
+ this->SetTimerEnabled( false );
+
+ // timer expired, letz start the mini-game!
+ //
+ m_pParent->HandleMessage( GUI_MSG_QUIT_MINIGAME, m_numActivePlayersDone );
+ }
+ }
+
+ break;
+ }
+ case GUI_MSG_MENU_SELECTION_CHANGED: // param1 = old, param2 = new
+ {
+ if( m_numActivePlayers == 0 ) // track selection state
+ {
+ this->MoveTrackCursor( static_cast<int>( param2 ), static_cast<int>( param1 ) );
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_UP:
+ {
+ if( m_numActivePlayers == 0 ) // track selection state
+ {
+ // increment number of laps
+ //
+ rAssert( m_trackNumLaps != NULL );
+ int currentNumLaps = m_trackNumLaps->GetIndex();
+ if( currentNumLaps < SuperSprintData::MAX_NUM_LAPS )
+ {
+ currentNumLaps++;
+ m_trackNumLaps->SetIndex( currentNumLaps );
+
+ if( currentNumLaps == SuperSprintData::MAX_NUM_LAPS &&
+ m_trackNumLapsArrowU != NULL )
+ {
+ m_trackNumLapsArrowU->SetAlpha( NUM_LAPS_ARROW_GREY_OUT_ALPHA ); // grey out arrow
+ }
+
+ if( m_trackNumLapsArrowD != NULL )
+ {
+ m_trackNumLapsArrowD->SetAlpha( 1.0f ); // restore normal arrow
+ }
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ }
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_DOWN:
+ {
+ if( m_numActivePlayers == 0 ) // track selection state
+ {
+ // decrement number of laps
+ //
+ rAssert( m_trackNumLaps != NULL );
+ int currentNumLaps = m_trackNumLaps->GetIndex();
+ if( currentNumLaps > SuperSprintData::MIN_NUM_LAPS )
+ {
+ currentNumLaps--;
+ m_trackNumLaps->SetIndex( currentNumLaps );
+
+ if( currentNumLaps == SuperSprintData::MIN_NUM_LAPS &&
+ m_trackNumLapsArrowD != NULL )
+ {
+ m_trackNumLapsArrowD->SetAlpha( NUM_LAPS_ARROW_GREY_OUT_ALPHA ); // grey out arrow
+ }
+
+ if( m_trackNumLapsArrowU != NULL )
+ {
+ m_trackNumLapsArrowU->SetAlpha( 1.0f ); // restore normal arrow
+ }
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+ }
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_START:
+ {
+ if( m_numActivePlayers == 0 )
+ {
+ this->OnTrackSelected();
+ }
+
+ // active new player menu
+ //
+ if( playerMenuID == -1 ) // means this player's not active yet
+ {
+#ifdef RAD_XBOX
+ // disable Start-to-Select button mapping to prevent duplicate SELECT inputs;
+ // it will be re-enabled in the next update
+ //
+ GetGuiSystem()->GetUserInputHandler( controllerID )->EnableStartToSelectMapping( false );
+#endif // RAD_XBOX
+
+ this->ActivateNewPlayer( controllerID );
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT );
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ if( m_numActivePlayers == 0 )
+ {
+ this->OnTrackSelected();
+
+ // track selected, activate the first player
+ //
+ this->ActivateNewPlayer( controllerID );
+ }
+ else
+ {
+ if( playerMenuID != -1 && !m_playerMenus[ playerMenuID ].IsDone() )
+ {
+ Scrooby::Drawable* pCursor = m_playerMenus[ playerMenuID ].GetCurrentSubMenu()->GetCursor();
+ rAssert( pCursor != NULL );
+ pCursor->SetAlpha( 1.0f ); // restore cursor alpha
+
+ m_playerMenus[ playerMenuID ].m_currentSubMenu++;
+
+ if( m_playerMenus[ playerMenuID ].IsDone() )
+ {
+ // player is done selecting from all sub-menus
+ //
+ m_numActivePlayersDone++;
+
+ this->SetTimerEnabled( true );
+
+ this->OnVehicleSelected( playerMenuID, true );
+ }
+ else
+ {
+ this->OnCharacterSelected( playerMenuID, true );
+ }
+
+ // if everyone's done selecting, start the game!
+ //
+ if( m_numActivePlayersDone == SuperSprintData::NUM_PLAYERS )
+ {
+ this->SetTimerEnabled( false );
+
+ m_pParent->HandleMessage( GUI_MSG_QUIT_MINIGAME, m_numActivePlayersDone );
+ }
+ }
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+ if( m_numActivePlayers == 0 )
+ {
+ // display quit confirmation screen
+ //
+ m_guiManager->DisplayPrompt( PROMPT_CONFIRM_QUIT, this );
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK );
+ }
+ else
+ {
+ if( playerMenuID != -1 )
+ {
+ if( m_playerMenus[ playerMenuID ].m_currentSubMenu > 0 )
+ {
+ if( !m_playerMenus[ playerMenuID ].IsDone() )
+ {
+ Scrooby::Drawable* pCursor = m_playerMenus[ playerMenuID ].GetCurrentSubMenu()->GetCursor();
+ rAssert( pCursor != NULL );
+ pCursor->SetAlpha( 1.0f ); // restore cursor alpha
+
+ this->OnCharacterSelected( playerMenuID, false );
+ }
+ else
+ {
+ this->OnVehicleSelected( playerMenuID, false );
+
+ m_numActivePlayersDone--;
+
+ // if no one's done selecting all their sub-menus, disable timer
+ //
+ if( m_numActivePlayersDone == 0 )
+ {
+ this->SetTimerEnabled( false );
+ }
+ }
+
+ m_playerMenus[ playerMenuID ].m_currentSubMenu--;
+ }
+ else
+ {
+ // de-activate player menu
+ //
+ m_playerMenus[ playerMenuID ].SetActive( false );
+ GetInputManager()->UnregisterControllerID( playerMenuID );
+
+ m_numActivePlayers--;
+
+ if( m_numActivePlayers == 0 )
+ {
+ // re-enable track selection
+ //
+ this->SetTrackSelectionEnabled( true );
+ }
+ }
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_BACK );
+ }
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_AUX_X:
+ {
+ if( m_numActivePlayers == 0 ) // track selection state
+ {
+ // toggle track direction
+ //
+ rAssert( m_trackDirection != NULL );
+ m_trackDirection->SetIndex( 1 - m_trackDirection->GetIndex() );
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_UPORDOWN );
+/*
+ // show options overlay
+ //
+ rAssert( m_optionsOverlay != NULL );
+ m_optionsOverlay->SetVisible( true );
+
+ // hide buttons
+ //
+ rAssert( m_optionsButton != NULL );
+ m_optionsButton->SetVisible( false );
+ this->SetButtonVisible( BUTTON_ICON_ACCEPT, false );
+
+ // reset options menu
+ //
+ rAssert( m_optionsMenu != NULL );
+ m_optionsMenu->Reset();
+
+ m_screenState = SCREEN_STATE_OPTIONS;
+*/
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+#ifdef RAD_WIN32
+//===========================================================================
+// CGuiScreenMiniMenu::CheckCursorAgainstHotspots
+//===========================================================================
+// Description: Checks cursor position against its list of hotspots.
+//
+// Constraints: None.
+//
+// Parameters: float x - The x position of cursor in P3D coordinates.
+// float y - The y position of cursor in P3D coordinates.
+//
+// Return: N/A.
+//
+//===========================================================================
+eFEHotspotType CGuiScreenMiniMenu::CheckCursorAgainstHotspots( float x, float y )
+{
+ if( m_bTrackSelected ) return HOTSPOT_NONE;
+ eFEHotspotType hotSpotType = HOTSPOT_NONE;
+ CGuiMenu* pCurrentMenu = HasMenu();
+ int numMenuItems = 0;
+ GuiMenuItem* pMenuItem = NULL;
+
+
+ if( pCurrentMenu )
+ {
+ numMenuItems = pCurrentMenu->GetNumItems();
+ for( int i = 0; i < numMenuItems; i++ )
+ {
+ pMenuItem = pCurrentMenu->GetMenuItem( i );
+
+ if( pMenuItem )
+ {
+ if( pMenuItem->GetItem()->IsVisible() )
+ {
+ // Just tests if the point is in the bounding rect of the sprite.
+ if( pMenuItem->GetItem()->IsPointInBoundingRect( x, y ) )
+ {
+ //rDebugPrintf( "Cursor is inside Sprite %d rectangle!\n", i );
+ pCurrentMenu->HandleMessage( GUI_MSG_MOUSE_OVER, i );
+ m_currentTrack = i;
+ hotSpotType = HOTSPOT_BUTTON;
+
+ //After taking care of all the events for this menu item, just bail out.
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if( hotSpotType == HOTSPOT_NONE )
+ {
+ // Since there's only one set of up and down arrows, when they get translated,
+ // their bounding box info doesn't change.. so I just offset it depending on
+ // their current selection.
+ float xOffset = 0.25f * m_currentTrack;
+ x -= xOffset;
+
+ if( m_trackNumLapsArrowU )
+ {
+ if( m_trackNumLapsArrowU->IsPointInBoundingRect( x, y ) )
+ {
+ hotSpotType = HOTSPOT_ARROWUP;
+ }
+ }
+ if( m_trackNumLapsArrowD )
+ {
+ if( m_trackNumLapsArrowD->IsPointInBoundingRect( x, y ) )
+ {
+ hotSpotType = HOTSPOT_ARROWDOWN;
+ }
+ }
+ }
+
+ return hotSpotType;
+}
+#endif
+
+//===========================================================================
+// CGuiScreenMiniMenu::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniMenu::InitIntro()
+{
+ // disable track(s) that are not unlocked
+ //
+ rAssert( m_pTrackMenu != NULL );
+ if( !CommandLineOptions::Get( CLO_SKIP_FE ) )
+ {
+ for( int i = 0; i < NUM_TRACKS; i++ )
+ {
+ bool isTrackUnlocked = GetCardGallery()->IsCardDeckComplete( static_cast<unsigned int>( i ) );
+ m_pTrackMenu->SetMenuItemEnabled( i, isTrackUnlocked );
+ }
+ }
+
+ rAssertMsg( m_pTrackMenu->GetSelection() != -1, "Why isn't there at least one track enabled??" );
+
+ if( m_firstTimeEntered )
+ {
+ this->MoveTrackCursor( 0, m_pTrackMenu->GetSelection() );
+ }
+
+ // set default track direction
+ //
+ rAssert( m_trackDirection != NULL );
+ m_trackDirection->SetIndex( GetSSM()->IsTrackReversed() ? 0 : 1 );
+
+ // de-activate all player menus
+ //
+ for( int p = 0; p < SuperSprintData::NUM_PLAYERS; p++ )
+ {
+ m_playerMenus[ p ].SetActive( false );
+ GetInputManager()->UnregisterControllerID( p );
+ }
+
+ // restore all normal character bitmaps
+ //
+ for( int j = 0; j < NUM_CHARACTERS; j++ )
+ {
+ rAssert( m_playerMenus[ 0 ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ] != NULL );
+ m_playerMenus[ 0 ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->SetSelectionValue( j, 0 );
+ }
+
+ m_numActivePlayers = 0;
+ m_numActivePlayersDone = 0;
+
+ this->SetTrackSelectionEnabled( true );
+}
+
+//===========================================================================
+// CGuiScreenMiniMenu::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniMenu::InitRunning()
+{
+#ifdef MINI_MENU_SHOW_3D_CHARACTERS
+ // set drawables for 3D characters
+ //
+ tDrawable* pDrawable = NULL;
+
+ pDrawable = p3d::find<tDrawable>( "homer_h" );
+ if( pDrawable != NULL )
+ {
+ m_3dCharacters[ CHARACTER_HOMER ]->SetDrawable( pDrawable );
+ }
+
+ pDrawable = p3d::find<tDrawable>( "bart_h" );
+ if( pDrawable != NULL )
+ {
+ m_3dCharacters[ CHARACTER_BART ]->SetDrawable( pDrawable );
+ }
+
+ pDrawable = p3d::find<tDrawable>( "lisa_h" );
+ if( pDrawable != NULL )
+ {
+ m_3dCharacters[ CHARACTER_LISA ]->SetDrawable( pDrawable );
+ }
+
+ pDrawable = p3d::find<tDrawable>( "marge_h" );
+ if( pDrawable != NULL )
+ {
+ m_3dCharacters[ CHARACTER_MARGE ]->SetDrawable( pDrawable );
+ }
+
+ pDrawable = p3d::find<tDrawable>( "apu_h" );
+ if( pDrawable != NULL )
+ {
+ m_3dCharacters[ CHARACTER_APU ]->SetDrawable( pDrawable );
+ }
+
+ // adjust camera aspect ratio to match viewport dimensions
+ //
+ for( int i = 0; i < NUM_CHARACTERS; i++ )
+ {
+ rAssert( m_3dCharacters[ i ] != NULL );
+
+ int width = 0;
+ int height = 0;
+ m_3dCharacters[ i ]->GetBoundingBoxSize( width, height );
+
+ tCamera* pCamera = m_3dCharacters[ i ]->GetCamera();
+ rAssert( pCamera != NULL );
+ pCamera->SetFOV( pCamera->GetFieldOfView(), (float)width / (float)height );
+
+ // show 3D characters
+ //
+ m_3dCharacters[ i ]->SetVisible( false ); // true );
+ }
+#endif // MINI_MENU_SHOW_3D_CHARACTERS
+}
+
+//===========================================================================
+// CGuiScreenMiniMenu::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniMenu::InitOutro()
+{
+#ifdef MINI_MENU_SHOW_3D_CHARACTERS
+ // hide 3D characters
+ //
+ for( int i = 0; i < NUM_CHARACTERS; i++ )
+ {
+ rAssert( m_3dCharacters[ i ] != NULL );
+ m_3dCharacters[ i ]->SetVisible( false );
+ }
+#endif // MINI_MENU_SHOW_3D_CHARACTERS
+
+ // setup supersprint stuff
+ //
+ for( int p = 0; p < SuperSprintData::NUM_PLAYERS; p++ )
+ {
+ if( m_playerMenus[ p ].IsActive() )
+ {
+
+ int character = m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->GetSelection();
+ GetSSM()->SetCharacter( p, character );
+
+ int vehicle = m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->GetSelectionValue( 0 );
+ rAssert( m_unlockedVehicles[ vehicle ] != NULL );
+ GetSSM()->SetVehicle( p, m_unlockedVehicles[ vehicle ]->GetName() );
+ }
+ }
+}
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenMiniMenu::UpdateCharacterSlots()
+{
+ // update character slots availability
+ //
+ int p = 0;
+
+ m_characterSlots = 0;
+ for( p = 0; p < SuperSprintData::NUM_PLAYERS; p++ )
+ {
+ if( m_playerMenus[ p ].IsActive() )
+ {
+ int currentSelection = m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->GetSelection();
+ m_characterSlots |= (1 << currentSelection );
+ }
+ }
+
+ // enable/disable character selections for all player menus
+ //
+ for( p = 0; p < SuperSprintData::NUM_PLAYERS; p++ )
+ {
+ if( m_playerMenus[ p ].IsActive() )
+ {
+ for( int i = 0; i < NUM_CHARACTERS; i++ )
+ {
+ int currentSelection = m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->GetSelection();
+ if( i != currentSelection )
+ {
+ bool isEnabled = ( ((1 << i) & m_characterSlots) == 0 );
+ m_playerMenus[ p ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->SetMenuItemEnabled( i, isEnabled );
+ }
+ }
+ }
+ }
+}
+
+void
+CGuiScreenMiniMenu::SetTrackSelectionEnabled( bool enable )
+{
+ // show/hide options button
+ //
+ rAssert( m_optionsButton != NULL );
+ m_optionsButton->SetVisible( enable );
+
+ // set back label to "quit" if enabled
+ //
+ rAssert( m_backLabel != NULL );
+ m_backLabel->SetIndex( enable ? 1 : 0 );
+
+ // hide/show all players' "press start"
+ //
+ for( int p = 0; p < SuperSprintData::NUM_PLAYERS; p++ )
+ {
+ rAssert( m_playerMenus[ p ].m_pressStart != NULL );
+ m_playerMenus[ p ].m_pressStart->SetVisible( !enable );
+ }
+
+ // hide/show character select info
+ //
+ if( m_characterSelectInfo != NULL )
+ {
+ m_characterSelectInfo->SetVisible( !enable );
+ }
+#ifdef RAD_WIN32
+ m_bTrackSelected = !enable;
+#endif
+}
+
+void
+CGuiScreenMiniMenu::MoveTrackCursor( int previousIndex, int nextIndex )
+{
+ // if cursor exists
+ //
+ if( m_trackCursorBgd != NULL )
+ {
+ Scrooby::BoundedDrawable* item = NULL;
+ int x1, y1, x2, y2;
+
+ rAssert( m_pTrackMenu != NULL );
+
+ // get location of previous item
+ item = m_pTrackMenu->GetMenuItem( previousIndex )->GetItem();
+ rAssert( item != NULL );
+ item->GetOriginPosition( x1, y1 );
+
+ // get location of next item
+ item = m_pTrackMenu->GetMenuItem( nextIndex )->GetItem();
+ rAssert( item != NULL );
+ item->GetOriginPosition( x2, y2 );
+
+ // translate cursor
+ m_trackCursorBgd->Translate( x2 - x1, y2 - y1 );
+ }
+}
+
+void
+CGuiScreenMiniMenu::OnTrackSelected()
+{
+ this->SetTrackSelectionEnabled( false );
+
+ // highlight track cursor bgd
+ //
+ if( m_trackCursorBgd != NULL )
+ {
+ m_trackCursorBgd->SetAlpha( 1.0f );
+ }
+
+ // restore U/D num laps arrows
+ //
+ if( m_trackNumLapsArrowU != NULL && m_trackNumLapsArrowD != NULL )
+ {
+ m_trackNumLapsArrowU->SetIndex( 0 );
+ m_trackNumLapsArrowD->SetIndex( 0 );
+ }
+
+ // get current track selection
+ //
+ rAssert( m_pTrackMenu != NULL );
+ int currentTrack = m_pTrackMenu->GetSelection();
+
+ // disable selection made delay
+ //
+ m_pTrackMenu->MakeSelection( false );
+
+ // tell gameplay manager which track to load
+ //
+ RenderEnums::LevelEnum levelIndex = static_cast<RenderEnums::LevelEnum>( RenderEnums::B01 + currentTrack );
+ GetGameplayManager()->SetLevelIndex( levelIndex );
+
+ // set track options
+ //
+ rAssert( m_trackNumLaps != NULL );
+ GetSSM()->SetNumLaps( m_trackNumLaps->GetIndex() );
+
+ rAssert( m_trackDirection != NULL );
+ GetSSM()->SetTrackDirection( m_trackDirection->GetIndex() == 0 );
+}
+
+void
+CGuiScreenMiniMenu::ActivateNewPlayer( int controllerID )
+{
+ if( m_numActivePlayers >= SuperSprintData::NUM_PLAYERS )
+ {
+ // can't activate anymore new players
+ //
+ return;
+ }
+
+ int player_slot = 0;
+#ifdef RAD_XBOX
+ player_slot = controllerID;
+#elif defined ( RAD_WIN32 )
+ player_slot = controllerID;
+#else
+ // look for non empty slot
+ for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ )
+ {
+ // find first non-active menu to activate
+ //
+ if( !m_playerMenus[ i ].IsActive() )
+ {
+ player_slot = i;
+ break;
+ }
+ }
+#endif
+
+ // ok, found it!
+ //
+ m_playerMenus[ player_slot ].SetActive( true, controllerID );
+ GetInputManager()->RegisterControllerID( player_slot , controllerID);
+
+ m_numActivePlayers++;
+
+ // default character selection to first empty slot
+ //
+ for( int s = 0; s < NUM_CHARACTERS; s++ )
+ {
+ if( ((1 << s) & m_characterSlots) == 0 )
+ {
+ m_playerMenus[ player_slot ].GetCurrentSubMenu()->Reset( s );
+
+ break;
+ }
+ }
+
+ // update vehicle rating
+ //
+ this->UpdateVehicleRating( player_slot );
+}
+
+void
+CGuiScreenMiniMenu::OnCharacterSelected( int playerID, bool isSelected )
+{
+ rAssert( playerID != -1 );
+ rAssert( m_playerMenus[ playerID ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ] != NULL );
+
+ // show/hide character selection done indicator
+ //
+ rAssert( m_playerMenus[ playerID ].m_characterSelectedIcon != NULL );
+ m_playerMenus[ playerID ].m_characterSelectedIcon->SetAlpha( isSelected ? 1.0f : 0.0f );
+
+ // swap selected character bitmap
+ //
+ int characterIndex = m_playerMenus[ playerID ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->GetSelection();
+ m_playerMenus[ playerID ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->SetSelectionValue( characterIndex, isSelected ? CHARACTER_SELECTED : CHARACTER_NOT_SELECTED );
+
+ // disable selection made delay
+ //
+ if( isSelected )
+ {
+ m_playerMenus[ playerID ].m_pMenu[ PlayerMenu::MENU_CHARACTERS ]->MakeSelection( false );
+ }
+}
+
+void
+CGuiScreenMiniMenu::OnVehicleSelected( int playerID, bool isSelected )
+{
+ rAssert( playerID != -1 );
+ rAssert( m_playerMenus[ playerID ].m_pMenu[ PlayerMenu::MENU_VEHICLES ] != NULL );
+
+ // show/hide vehicle selection done indicator
+ //
+ rAssert( m_playerMenus[ playerID ].m_vehicleSelectedIcon != NULL );
+ m_playerMenus[ playerID ].m_vehicleSelectedIcon->SetAlpha( isSelected ? 1.0f : 0.0f );
+
+ // disable selection made delay
+ //
+ if( isSelected )
+ {
+ m_playerMenus[ playerID ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->MakeSelection( false );
+ }
+}
+
+void
+CGuiScreenMiniMenu::AddRewardVehicle( Reward* pReward )
+{
+ rAssert( pReward != NULL );
+ if( pReward->RewardStatus() || // if reward is unlocked
+ CommandLineOptions::Get( CLO_SKIP_FE ) ||
+// GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_CARDS ) ||
+ GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_UNLOCK_VEHICLES ) )
+ {
+ rAssert( m_numUnlockedVehicles < MAX_NUM_VEHICLES );
+
+ m_unlockedVehicles[ m_numUnlockedVehicles ] = pReward;
+ m_numUnlockedVehicles++;
+ }
+}
+
+void
+CGuiScreenMiniMenu::PrepareVehicleSelections()
+{
+ for( int level = 0; level < RenderEnums::numLevels; level++ )
+ {
+ Reward* pReward = NULL;
+
+ for( int i = Reward::eBlank + 1; i < Reward::NUM_QUESTS; i++ )
+ {
+ pReward = GetRewardsManager()->GetReward( level, static_cast<Reward::eQuestType>( i ) );
+ if( pReward != NULL )
+ {
+ if( pReward->GetRewardType() == Reward::ALT_PLAYERCAR )
+ {
+ this->AddRewardVehicle( pReward );
+ }
+ }
+ }
+
+ for( pReward = GetRewardsManager()->FindFirstMerchandise( level, Merchandise::SELLER_GIL );
+ pReward != NULL;
+ pReward = GetRewardsManager()->FindNextMerchandise( level, Merchandise::SELLER_GIL ) )
+ {
+ this->AddRewardVehicle( pReward );
+ }
+
+ for( pReward = GetRewardsManager()->FindFirstMerchandise( level, Merchandise::SELLER_SIMPSON );
+ pReward != NULL;
+ pReward = GetRewardsManager()->FindNextMerchandise( level, Merchandise::SELLER_SIMPSON ) )
+ {
+ this->AddRewardVehicle( pReward );
+ }
+ }
+}
+
+void
+CGuiScreenMiniMenu::UpdateVehicleDisplayImages( int playerID, Scrooby::Sprite* vehicleImage )
+{
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ rAssert( vehicleImage != NULL );
+ for( int i = 0; i < m_numUnlockedVehicles; i++ )
+ {
+ rAssert( m_unlockedVehicles[ i ] != NULL );
+ vehicleImage->SetImage( i, m_unlockedVehicles[ i ]->GetName() );
+ }
+
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+}
+
+void
+CGuiScreenMiniMenu::UpdateVehicleRating( int playerID )
+{
+ if( m_playerMenus[ playerID ].m_vehicleRating != NULL )
+ {
+ int vehicleIndex = m_playerMenus[ playerID ].m_pMenu[ PlayerMenu::MENU_VEHICLES ]->GetSelectionValue( 0 );
+
+ rAssert( m_unlockedVehicles[ vehicleIndex ] != NULL );
+ CarAttributeRecord* carStats = GetRewardsManager()->GetCarAttributeRecord( m_unlockedVehicles[ vehicleIndex ]->GetName() );
+ if( carStats != NULL )
+ {
+ int rating = (int)( GetRewardsManager()->ComputeOverallCarRating( carStats ) );
+
+ rAssertMsg( rating >= 0 && rating < m_playerMenus[ playerID ].m_vehicleRating->GetNumOfImages(),
+ "Invalid vehicle rating (either negative or too high)!" );
+
+ m_playerMenus[ playerID ].m_vehicleRating->SetIndex( rating );
+ }
+ }
+}
+
+void
+CGuiScreenMiniMenu::SetTimerEnabled( bool enable )
+{
+ // show/hide timer overlay
+ //
+ rAssert( m_timerOverlay != NULL );
+ m_timerOverlay->SetVisible( enable );
+
+ if( !enable )
+ {
+ // reset timer
+ //
+ m_remainingTime = TIMER_WAIT_TIME;
+ }
+}
+
+int
+CGuiScreenMiniMenu::GetPlayerMenuID( int controllerID ) const
+{
+ // search for player menu w/ associated controller ID
+ //
+ for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ )
+ {
+ if( m_playerMenus[ i ].m_controllerID == controllerID )
+ {
+ // found it! return player menu ID
+ //
+ return i;
+ }
+ }
+
+ // player menu not found, return -1
+ //
+ return -1;
+}
+
diff --git a/game/code/presentation/gui/minigame/guiscreenminimenu.h b/game/code/presentation/gui/minigame/guiscreenminimenu.h
new file mode 100644
index 0000000..356233a
--- /dev/null
+++ b/game/code/presentation/gui/minigame/guiscreenminimenu.h
@@ -0,0 +1,210 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMiniMenu
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/24 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMINIMENU_H
+#define GUISCREENMINIMENU_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+#include <presentation/gui/utility/numerictext.h>
+
+#include <supersprint/supersprintdata.h>
+
+//#define MINI_MENU_SHOW_3D_CHARACTERS
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class CGuiMenu;
+class Reward;
+
+struct PlayerMenu
+{
+ enum eSubMenu
+ {
+ MENU_CHARACTERS,
+ MENU_VEHICLES,
+
+ NUM_SUB_MENUS
+ };
+
+ CGuiMenu* m_pMenu[ NUM_SUB_MENUS ];
+ int m_currentSubMenu;
+ int m_controllerID;
+
+ Scrooby::Text* m_pressStart;
+ Scrooby::Sprite* m_vehicleRating;
+ Scrooby::Drawable* m_characterSelectedIcon;
+ Scrooby::Drawable* m_vehicleSelectedIcon;
+
+ PlayerMenu();
+
+ void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ CGuiMenu* GetCurrentSubMenu() const;
+ void SetActive( bool isActive, int controllerID = -1 );
+ bool IsActive() const;
+ bool IsDone() const;
+
+};
+
+inline bool PlayerMenu::IsActive() const
+{
+ return( m_controllerID != -1 );
+}
+
+inline bool PlayerMenu::IsDone() const
+{
+ return( m_currentSubMenu >= NUM_SUB_MENUS );
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMiniMenu : public CGuiScreen
+{
+public:
+ CGuiScreenMiniMenu( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenMiniMenu();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+ virtual CGuiMenu* HasMenu() { return m_pTrackMenu; }
+#ifdef RAD_WIN32
+ virtual eFEHotspotType CheckCursorAgainstHotspots( float x, float y );
+#endif
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ void UpdateCharacterSlots();
+
+ void SetTrackSelectionEnabled( bool enable );
+ void MoveTrackCursor( int previousIndex, int nextIndex );
+ void OnTrackSelected();
+
+ void ActivateNewPlayer( int controllerID );
+
+ void OnCharacterSelected( int playerID, bool isSelected );
+ void OnVehicleSelected( int playerID, bool isSelected );
+
+ void AddRewardVehicle( Reward* pReward );
+ void PrepareVehicleSelections();
+ void UpdateVehicleDisplayImages( int playerID, Scrooby::Sprite* vehicleImage );
+ void UpdateVehicleRating( int playerID );
+
+ void SetTimerEnabled( bool enable );
+
+ int GetPlayerMenuID( int controllerID ) const;
+
+ static const int NUM_TRACKS = 7;
+ static const int MAX_NUM_VEHICLES = 64;
+
+#ifdef RAD_DEBUG
+ static const int TIMER_WAIT_TIME = 5000; // in msec
+#else
+ static const int TIMER_WAIT_TIME = 10000; // in msec
+#endif
+
+ enum eScreenState
+ {
+ SCREEN_STATE_NORMAL,
+ SCREEN_STATE_OPTIONS,
+
+ NUM_SCREEN_STATES
+ };
+
+ enum eCharacter
+ {
+ CHARACTER_LISA,
+ CHARACTER_BART,
+ CHARACTER_HOMER,
+ CHARACTER_MARGE,
+ CHARACTER_APU,
+
+ NUM_CHARACTERS
+ };
+
+ enum eCharacterSelectionState
+ {
+ CHARACTER_NOT_SELECTED = 0,
+ CHARACTER_SELECTED = 1,
+
+ NUM_CHARACTER_SELECTION_STATES
+ };
+
+/*
+ enum eOptionsMenuItem
+ {
+ MENU_ITEM_NUM_LAPS,
+ MENU_ITEM_REVERSE_DIRECTION,
+
+ NUM_OPTIONS_MENU_ITEMS
+ };
+
+ eScreenState m_screenState;
+*/
+
+ CGuiMenu* m_pTrackMenu;
+ Scrooby::Sprite* m_trackDirection;
+ Scrooby::Text* m_trackNumLaps;
+ Scrooby::Sprite* m_trackNumLapsArrowU;
+ Scrooby::Sprite* m_trackNumLapsArrowD;
+ Scrooby::Polygon* m_trackCursorBgd;
+ unsigned int m_elapsedTime;
+
+ Scrooby::Text* m_backLabel;
+
+ PlayerMenu m_playerMenus[ SuperSprintData::NUM_PLAYERS ];
+ int m_numActivePlayers;
+ int m_numActivePlayersDone;
+ short m_characterSlots; // bit-mask
+
+#ifdef MINI_MENU_SHOW_3D_CHARACTERS
+ Scrooby::Pure3dObject* m_3dCharacters[ NUM_CHARACTERS ];
+#endif
+
+#ifdef RAD_WIN32
+ int m_currentTrack;
+ bool m_bTrackSelected;
+#endif
+
+ Reward* m_unlockedVehicles[ MAX_NUM_VEHICLES ];
+ int m_numUnlockedVehicles;
+
+ Scrooby::Group* m_optionsButton;
+/*
+ Scrooby::Layer* m_optionsOverlay;
+ CGuiMenu* m_optionsMenu;
+*/
+
+ Scrooby::Group* m_characterSelectInfo;
+
+ Scrooby::Group* m_timerOverlay;
+ NumericText<Scrooby::Text> m_timer;
+ int m_remainingTime;
+
+};
+
+#endif // GUISCREENMINIMENU_H
diff --git a/game/code/presentation/gui/minigame/guiscreenminipause.cpp b/game/code/presentation/gui/minigame/guiscreenminipause.cpp
new file mode 100644
index 0000000..db37e0c
--- /dev/null
+++ b/game/code/presentation/gui/minigame/guiscreenminipause.cpp
@@ -0,0 +1,297 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMiniPause
+//
+// Description: Implementation of the CGuiScreenMiniPause class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/24 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/minigame/guiscreenminipause.h>
+#include <presentation/gui/minigame/guiscreenminihud.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guimenu.h>
+
+#include <contexts/supersprint/supersprintcontext.h>
+#include <gameflow/gameflow.h>
+#include <input/inputmanager.h>
+#include <sound/soundmanager.h>
+
+#include <screen.h>
+#include <page.h>
+#include <group.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenMiniPause::CGuiScreenMiniPause
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMiniPause::CGuiScreenMiniPause
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MINI_PAUSE ),
+ m_pMenu( NULL )
+{
+ // Retrieve the Scrooby drawing elements (from MiniPause page).
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "MiniPause" );
+ rAssert( pPage != NULL );
+
+ // create menu
+ //
+ m_pMenu = new CGuiMenu( this, NUM_MENU_ITEMS );
+ rAssert( m_pMenu != NULL );
+
+ Scrooby::Group* pGroup = pPage->GetGroup( "Menu" );
+ rAssert( pGroup != NULL );
+ m_pMenu->AddMenuItem( pGroup->GetText( "Continue" ) );
+ m_pMenu->AddMenuItem( pGroup->GetText( "Quit" ) );
+
+ // Retrieve the Scrooby drawing elements (from PauseFgd page).
+ //
+ pPage = m_pScroobyScreen->GetPage( "PauseFgd" );
+ if( pPage != NULL )
+ {
+ // Wrap "Press Start" help text
+ //
+ Scrooby::Text* pressStart = pPage->GetText( "PressStartResumePlay" );
+ if( pressStart != NULL )
+ {
+ pressStart->SetTextMode( Scrooby::TEXT_WRAP );
+
+ // add text outline
+ //
+ pressStart->SetDisplayOutline( true );
+
+ // set platform-specific text
+ //
+ pressStart->SetIndex( PLATFORM_TEXT_INDEX );
+ }
+ }
+
+ this->AutoScaleFrame( m_pScroobyScreen->GetPage( "XSmallBoard" ) );
+
+ this->SetZoomingEnabled( true );
+}
+
+
+//===========================================================================
+// CGuiScreenMiniPause::~CGuiScreenMiniPause
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMiniPause::~CGuiScreenMiniPause()
+{
+ if( m_pMenu != NULL )
+ {
+ delete m_pMenu;
+ m_pMenu = NULL;
+ }
+}
+
+
+//===========================================================================
+// CGuiScreenMiniPause::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniPause::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ if( this->IsControllerMessage( message ) &&
+ static_cast<int>( param1 ) != CGuiScreenMiniHud::s_pausedControllerID )
+ {
+ // ignore controller messages if not from user who paused mini-game
+ //
+ return;
+ }
+
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_START:
+ {
+ if( !m_pMenu->HasSelectionBeenMade() )
+ {
+ this->ResumeGame();
+ }
+
+ break;
+ }
+ case GUI_MSG_CONTROLLER_BACK:
+ {
+#ifdef RAD_WIN32
+ this->ResumeGame();
+ break;
+#else
+ // don't allow user to back out of pause menu
+ //
+ return;
+#endif
+ }
+ case GUI_MSG_MENU_SELECTION_MADE:
+ {
+ if( param1 == MENU_ITEM_CONTINUE )
+ {
+ this->ResumeGame();
+ }
+ else if( param1 == MENU_ITEM_QUIT )
+ {
+ this->QuitGame();
+ }
+ else
+ {
+ rAssertMsg( false, "Invalid menu selection!" );
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ // relay message to menu
+ //
+ rAssert( m_pMenu != NULL );
+ m_pMenu->HandleMessage( message, param1, param2 );
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenMiniPause::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniPause::InitIntro()
+{
+ rAssert( m_pMenu != NULL );
+ m_pMenu->Reset(); // default to 'Continue'
+
+ GetSoundManager()->OnPauseStart();
+
+#ifdef RAD_WIN32
+ GetInputManager()->GetFEMouse()->SetInGameMode( false );
+#endif
+}
+
+
+//===========================================================================
+// CGuiScreenMiniPause::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniPause::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenMiniPause::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniPause::InitOutro()
+{
+ GetSoundManager()->OnPauseEnd();
+
+#ifdef RAD_WIN32
+ GetInputManager()->GetFEMouse()->SetInGameMode( true );
+#endif
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenMiniPause::ResumeGame()
+{
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN, GUI_SCREEN_ID_MINI_HUD, CLEAR_WINDOW_HISTORY );
+}
+
+void
+CGuiScreenMiniPause::QuitGame()
+{
+ // quit mini-game and return to mini-game FE
+ //
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ GUI_SCREEN_ID_MINI_MENU,
+ CLEAR_WINDOW_HISTORY );
+
+ GetGameFlow()->SetContext( CONTEXT_SUPERSPRINT_FE );
+}
+
diff --git a/game/code/presentation/gui/minigame/guiscreenminipause.h b/game/code/presentation/gui/minigame/guiscreenminipause.h
new file mode 100644
index 0000000..543ab36
--- /dev/null
+++ b/game/code/presentation/gui/minigame/guiscreenminipause.h
@@ -0,0 +1,66 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMiniPause
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/24 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMINIPAUSE_H
+#define GUISCREENMINIPAUSE_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+class CGuiMenu;
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMiniPause : public CGuiScreen
+{
+public:
+ CGuiScreenMiniPause( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenMiniPause();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+ virtual CGuiMenu* HasMenu() { return m_pMenu; }
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ void ResumeGame();
+ void QuitGame();
+
+ enum eMenuItem
+ {
+ MENU_ITEM_CONTINUE,
+ MENU_ITEM_QUIT,
+
+ NUM_MENU_ITEMS
+ };
+
+ CGuiMenu* m_pMenu;
+
+};
+
+#endif // GUISCREENMINIPAUSE_H
diff --git a/game/code/presentation/gui/minigame/guiscreenminisummary.cpp b/game/code/presentation/gui/minigame/guiscreenminisummary.cpp
new file mode 100644
index 0000000..4841d93
--- /dev/null
+++ b/game/code/presentation/gui/minigame/guiscreenminisummary.cpp
@@ -0,0 +1,539 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMiniSummary
+//
+// Description: Implementation of the CGuiScreenMiniSummary class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/24 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/minigame/guiscreenminisummary.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guiscreenprompt.h>
+#include <presentation/gui/guitextbible.h>
+
+#include <contexts/supersprint/supersprintcontext.h>
+#include <events/eventmanager.h>
+#include <gameflow/gameflow.h>
+#include <input/inputmanager.h>
+#include <sound/soundmanager.h>
+
+#include <screen.h>
+#include <page.h>
+#include <group.h>
+#include <sprite.h>
+#include <text.h>
+#include <polygon.h>
+
+#include <supersprint/supersprintmanager.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+const float MINI_SUMMARY_CHARACTER_SCALE_BIG = 0.9f;
+const float MINI_SUMMARY_CHARACTER_SCALE_SMALL = 0.7f;
+const float MINI_SUMMARY_KING_ICON_SCALE = 0.75f;
+
+void
+CGuiScreenMiniSummary::PlayerDisplayInfo::SetVisible( bool isVisible )
+{
+ rAssert( m_face != NULL );
+ m_face->SetVisible( isVisible );
+ rAssert( m_ranking != NULL );
+ m_ranking->SetVisible( isVisible );
+ rAssert( m_numWins != NULL );
+ m_numWins->SetVisible( isVisible );
+ rAssert( m_numPoints != NULL );
+ m_numPoints->SetVisible( isVisible );
+ rAssert( m_totalTime != NULL );
+ m_totalTime->SetVisible( isVisible );
+ rAssert( m_bestLap != NULL );
+ m_bestLap->SetVisible( isVisible );
+ rAssert( m_rowBgd != NULL );
+ m_rowBgd->SetVisible( isVisible );
+}
+
+int
+CGuiScreenMiniSummary::PlayerRanking::CompareScores( int points1, int wins1,
+ int points2, int wins2 )
+{
+ if( points1 > points2 )
+ {
+ return 1;
+ }
+ else if( points1 == points2 )
+ {
+ if( wins1 > wins2 )
+ {
+ return 1;
+ }
+ else if( wins1 == wins2 )
+ {
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CGuiScreenMiniSummary::CGuiScreenMiniSummary
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMiniSummary::CGuiScreenMiniSummary
+(
+ Scrooby::Screen* pScreen,
+ CGuiEntity* pParent
+)
+: CGuiScreen( pScreen, pParent, GUI_SCREEN_ID_MINI_SUMMARY ),
+ m_totalTimeKingIcon( NULL ),
+ m_bestLapKingIcon( NULL )
+{
+ // Retrieve the Scrooby drawing elements.
+ //
+ Scrooby::Page* pPage = m_pScroobyScreen->GetPage( "MiniSummary" );
+ rAssert( pPage != NULL );
+
+ Scrooby::Text* raceSummary = pPage->GetText( "RaceSummary" );
+ if( raceSummary != NULL )
+ {
+ raceSummary->SetTextMode( Scrooby::TEXT_WRAP );
+ }
+
+ Scrooby::Group* pGroupFaces = pPage->GetGroup( "Faces" );
+ rAssert( pGroupFaces != NULL );
+ Scrooby::Group* pGroupRanks = pPage->GetGroup( "Ranks" );
+ rAssert( pGroupRanks != NULL );
+ Scrooby::Group* pGroupPlayers = pPage->GetGroup( "Players" );
+ rAssert( pGroupPlayers != NULL );
+ Scrooby::Group* pGroupWins = pPage->GetGroup( "Wins" );
+ rAssert( pGroupWins != NULL );
+ Scrooby::Group* pGroupPoints = pPage->GetGroup( "Points" );
+ rAssert( pGroupPoints != NULL );
+ Scrooby::Group* pGroupTotalTime = pPage->GetGroup( "TotalTime" );
+ rAssert( pGroupTotalTime != NULL );
+ Scrooby::Group* pGroupBestLap = pPage->GetGroup( "BestLap" );
+ rAssert( pGroupBestLap != NULL );
+ Scrooby::Group* pGroupRows = pPage->GetGroup( "Rows" );
+ rAssert( pGroupRows != NULL );
+
+ char name[ 32 ];
+ for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ )
+ {
+ sprintf( name, "Face%d", i );
+ m_displayInfo[ i ].m_face = pGroupFaces->GetSprite( name );
+
+ sprintf( name, "Rank%d", i );
+ m_displayInfo[ i ].m_ranking = pGroupRanks->GetText( name );
+
+ sprintf( name, "Player%d", i );
+ m_displayInfo[ i ].m_playerIndicator = pGroupPlayers->GetText( name );
+
+ sprintf( name, "NumWins%d", i );
+ m_displayInfo[ i ].m_numWins = pGroupWins->GetText( name );
+
+ sprintf( name, "NumPoints%d", i );
+ m_displayInfo[ i ].m_numPoints = pGroupPoints->GetText( name );
+
+ sprintf( name, "TotalTime%d", i );
+ m_displayInfo[ i ].m_totalTime = pGroupTotalTime->GetText( name );
+
+ sprintf( name, "BestLap%d", i );
+ m_displayInfo[ i ].m_bestLap = pGroupBestLap->GetText( name );
+
+ sprintf( name, "Row%d", i );
+ m_displayInfo[ i ].m_rowBgd = pGroupRows->GetPolygon( name );
+ }
+
+ // text wrap "Total Time" and "Best Lap"
+ //
+ Scrooby::Text* pText = pGroupTotalTime->GetText( "TotalTime" );
+ rAssert( pText != NULL );
+ pText->SetTextMode( Scrooby::TEXT_WRAP );
+
+ pText = pGroupBestLap->GetText( "BestLap" );
+ rAssert( pText != NULL );
+ pText->SetTextMode( Scrooby::TEXT_WRAP );
+
+ // get king icons
+ //
+ m_totalTimeKingIcon = pGroupTotalTime->GetSprite( "TotalTimeKingIcon" );
+ m_bestLapKingIcon = pGroupBestLap->GetSprite( "BestLapKingIcon" );
+
+#ifdef RAD_WIN32
+ m_totalTimeKingIcon->ScaleAboutCenter( 0.5f );
+ m_bestLapKingIcon->ScaleAboutCenter( 0.5f );
+ pGroupRanks->GetSprite( "RankKingIcon" )->ScaleAboutCenter( 0.5f );
+#endif
+
+ // TC: [TEMP] hide these for now until I have time to implement the
+ // functionality
+ //
+ rAssert( m_totalTimeKingIcon != NULL );
+ m_totalTimeKingIcon->SetVisible( false );
+ rAssert( m_bestLapKingIcon != NULL );
+ m_bestLapKingIcon->SetVisible( false );
+
+ this->AutoScaleFrame( m_pScroobyScreen->GetPage( "BigBoard" ) );
+}
+
+
+//===========================================================================
+// CGuiScreenMiniSummary::~CGuiScreenMiniSummary
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CGuiScreenMiniSummary::~CGuiScreenMiniSummary()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenMiniSummary::HandleMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniSummary::HandleMessage
+(
+ eGuiMessage message,
+ unsigned int param1,
+ unsigned int param2
+)
+{
+ if( message == GUI_MSG_MENU_PROMPT_RESPONSE )
+ {
+ rAssert( param1 == PROMPT_CONFIRM_RACE_AGAIN );
+
+ switch( param2 )
+ {
+ case (CGuiMenuPrompt::RESPONSE_YES):
+ {
+ // ok, letz start another race
+ //
+ GetGameFlow()->GetContext( CONTEXT_SUPERSPRINT )->Resume();
+
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ GUI_SCREEN_ID_MINI_HUD,
+ CLEAR_WINDOW_HISTORY );
+
+ GetSSM()->Reset();
+
+ GetSoundManager()->RestartSupersprintMusic();
+
+ break;
+ }
+ case (CGuiMenuPrompt::RESPONSE_NO):
+ {
+ // quit mini-game and return to mini-game FE
+ //
+ m_pParent->HandleMessage( GUI_MSG_GOTO_SCREEN,
+ GUI_SCREEN_ID_MINI_MENU,
+ CLEAR_WINDOW_HISTORY );
+
+ GetGameFlow()->SetContext( CONTEXT_SUPERSPRINT_FE );
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( 0, "WARNING: *** Invalid prompt response!\n" );
+
+ break;
+ }
+ }
+
+ GetSoundManager()->OnStoreScreenEnd();
+ }
+
+ if( m_state == GUI_WINDOW_STATE_RUNNING )
+ {
+ switch( message )
+ {
+ case GUI_MSG_CONTROLLER_SELECT:
+ {
+ // display 'race again' prompt
+ //
+ m_guiManager->DisplayPrompt( PROMPT_CONFIRM_RACE_AGAIN,
+ this,
+ PROMPT_TYPE_YES_NO,
+ false );
+
+ GetEventManager()->TriggerEvent( EVENT_FE_MENU_SELECT );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ // Propogate the message up the hierarchy.
+ //
+ CGuiScreen::HandleMessage( message, param1, param2 );
+}
+
+
+//===========================================================================
+// CGuiScreenMiniSummary::InitIntro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniSummary::InitIntro()
+{
+ this->ResetCurrentRankings();
+
+ // rank players by points and wins
+ //
+ for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ )
+ {
+// if( GetSSM()->GetVehicleData( i )->mIsHuman )
+ {
+ this->InsertPlayerRanking( i );
+ }
+ }
+
+ // update display info
+ //
+ for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ )
+ {
+ this->UpdateDisplayInfo( i, m_currentRankings[ i ].m_playerID );
+ }
+
+ //
+ // This isn't a store, but it's a handy set of ducking values
+ //
+ GetSoundManager()->OnStoreScreenStart( false );
+}
+
+
+//===========================================================================
+// CGuiScreenMiniSummary::InitRunning
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniSummary::InitRunning()
+{
+}
+
+
+//===========================================================================
+// CGuiScreenMiniSummary::InitOutro
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+void CGuiScreenMiniSummary::InitOutro()
+{
+#ifdef RAD_WIN32
+ GetInputManager()->GetFEMouse()->SetInGameMode( false );
+#endif
+}
+
+
+//---------------------------------------------------------------------
+// Private Functions
+//---------------------------------------------------------------------
+
+void
+CGuiScreenMiniSummary::UpdateDisplayInfo( int rankIndex, int playerID )
+{
+ rAssert( rankIndex >= 0 && rankIndex < SuperSprintData::NUM_PLAYERS );
+
+ if( playerID != -1 )
+ {
+ m_displayInfo[ rankIndex ].SetVisible( true );
+
+ const SuperSprintData::PlayerData* playerData = GetSSM()->GetPlayerData( playerID );
+ rAssert( playerData != NULL );
+
+ HeapMgr()->PushHeap( GMA_LEVEL_HUD );
+
+ // set character face
+ //
+ rAssert( m_displayInfo[ rankIndex ].m_face != NULL );
+ m_displayInfo[ rankIndex ].m_face->SetIndex( playerData->mCharacterIndex );
+ m_displayInfo[ rankIndex ].m_face->ResetTransformation();
+ if( rankIndex == 0 )
+ {
+ m_displayInfo[ rankIndex ].m_face->ScaleAboutCenter( MINI_SUMMARY_CHARACTER_SCALE_BIG );
+ }
+ else
+ {
+ m_displayInfo[ rankIndex ].m_face->ScaleAboutCenter( MINI_SUMMARY_CHARACTER_SCALE_SMALL );
+ }
+
+ // set ranking colour
+ //
+ rAssert( m_displayInfo[ rankIndex ].m_ranking != NULL );
+ m_displayInfo[ rankIndex ].m_ranking->SetColour( SuperSprintData::PLAYER_COLOURS[ playerID ] );
+
+ // set player ID indicator and colour
+ //
+ rAssert( m_displayInfo[ rankIndex ].m_playerIndicator != NULL );
+ if( GetSSM()->GetVehicleData( playerID )->mIsHuman )
+ {
+ m_displayInfo[ rankIndex ].m_playerIndicator->SetVisible( true );
+ m_displayInfo[ rankIndex ].m_playerIndicator->SetIndex( playerID );
+ m_displayInfo[ rankIndex ].m_playerIndicator->SetColour( SuperSprintData::PLAYER_COLOURS[ playerID ] );
+ }
+ else
+ {
+ m_displayInfo[ rankIndex ].m_playerIndicator->SetVisible( false );
+ }
+
+ char buffer[ 16 ];
+ UnicodeString unicodeString;
+
+ // set num wins
+ //
+ sprintf( buffer, "%d", playerData->mWins );
+ rAssert( m_displayInfo[ rankIndex ].m_numWins != NULL );
+ m_displayInfo[ rankIndex ].m_numWins->SetString( 0, buffer );
+
+ // set num points
+ //
+ sprintf( buffer, "%d", playerData->mPoints );
+ rAssert( m_displayInfo[ rankIndex ].m_numPoints != NULL );
+ m_displayInfo[ rankIndex ].m_numPoints->SetString( 0, buffer );
+
+ // set total time
+ //
+ if( playerData->mPosition > 0 )
+ {
+ sprintf( buffer, "%.2f", playerData->mRaceTime / 1000000.0f );
+ unicodeString.ReadAscii( buffer );
+ }
+ else
+ {
+ unicodeString.ReadUnicode( GetTextBibleString( "DNF" ) );
+ }
+ rAssert( m_displayInfo[ rankIndex ].m_totalTime != NULL );
+ m_displayInfo[ rankIndex ].m_totalTime->SetString( 0, unicodeString );
+
+ // set best lap
+ //
+ if( playerData->mRaceTime > 0 )
+ {
+ sprintf( buffer, "%.2f", playerData->mBestLap / 1000000.0f );
+ unicodeString.ReadAscii( buffer );
+ }
+ else
+ {
+ unicodeString.ReadUnicode( GetTextBibleString( "DNF" ) );
+ }
+ rAssert( m_displayInfo[ rankIndex ].m_bestLap != NULL );
+ m_displayInfo[ rankIndex ].m_bestLap->SetString( 0, unicodeString );
+
+ HeapMgr()->PopHeap( GMA_LEVEL_HUD );
+ }
+ else
+ {
+ m_displayInfo[ rankIndex ].SetVisible( false );
+ }
+}
+
+void
+CGuiScreenMiniSummary::ResetCurrentRankings()
+{
+ for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ )
+ {
+ m_currentRankings[ i ].m_playerID = -1;
+ m_currentRankings[ i ].m_playerPoints = -1;
+ m_currentRankings[ i ].m_playerWins = -1;
+ }
+}
+
+void
+CGuiScreenMiniSummary::InsertPlayerRanking( int playerID )
+{
+ const SuperSprintData::PlayerData* playerData = GetSSM()->GetPlayerData( playerID );
+ rAssert( playerData != NULL );
+
+ for( int i = 0; i < SuperSprintData::NUM_PLAYERS; i++ )
+ {
+ if( PlayerRanking::CompareScores( playerData->mPoints, playerData->mWins,
+ m_currentRankings[ i ].m_playerPoints, m_currentRankings[ i ].m_playerWins ) > 0 )
+ {
+ // move everyone else down a spot
+ //
+ for( int j = SuperSprintData::NUM_PLAYERS - 1; j > i; j-- )
+ {
+ m_currentRankings[ j ].m_playerID = m_currentRankings[ j - 1 ].m_playerID;
+ m_currentRankings[ j ].m_playerPoints = m_currentRankings[ j - 1 ].m_playerPoints;
+ m_currentRankings[ j ].m_playerWins = m_currentRankings[ j - 1 ].m_playerWins;
+ }
+
+ // insert here
+ //
+ m_currentRankings[ i ].m_playerID = playerID;
+ m_currentRankings[ i ].m_playerPoints = playerData->mPoints;
+ m_currentRankings[ i ].m_playerWins = playerData->mWins;
+
+ break;
+ }
+ }
+}
+
diff --git a/game/code/presentation/gui/minigame/guiscreenminisummary.h b/game/code/presentation/gui/minigame/guiscreenminisummary.h
new file mode 100644
index 0000000..231fcf9
--- /dev/null
+++ b/game/code/presentation/gui/minigame/guiscreenminisummary.h
@@ -0,0 +1,87 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CGuiScreenMiniSummary
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/24 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef GUISCREENMINISUMMARY_H
+#define GUISCREENMINISUMMARY_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <presentation/gui/guiscreen.h>
+
+#include <supersprint/supersprintdata.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CGuiScreenMiniSummary : public CGuiScreen
+{
+public:
+ CGuiScreenMiniSummary( Scrooby::Screen* pScreen, CGuiEntity* pParent );
+ virtual ~CGuiScreenMiniSummary();
+
+ virtual void HandleMessage( eGuiMessage message,
+ unsigned int param1 = 0,
+ unsigned int param2 = 0 );
+
+protected:
+ void InitIntro();
+ void InitRunning();
+ void InitOutro();
+
+private:
+ void UpdateDisplayInfo( int rankIndex, int playerID );
+
+ void ResetCurrentRankings();
+ void InsertPlayerRanking( int playerID );
+
+ struct PlayerDisplayInfo
+ {
+ Scrooby::Sprite* m_face;
+ Scrooby::Text* m_ranking;
+ Scrooby::Text* m_playerIndicator;
+ Scrooby::Text* m_numWins;
+ Scrooby::Text* m_numPoints;
+ Scrooby::Text* m_totalTime;
+ Scrooby::Text* m_bestLap;
+ Scrooby::Polygon* m_rowBgd;
+
+ void SetVisible( bool isVisible );
+ };
+
+ PlayerDisplayInfo m_displayInfo[ SuperSprintData::NUM_PLAYERS ];
+
+ struct PlayerRanking
+ {
+ int m_playerID;
+ int m_playerPoints;
+ int m_playerWins;
+
+ static int CompareScores( int points1, int wins1,
+ int points2, int wins2 );
+ };
+
+ PlayerRanking m_currentRankings[ SuperSprintData::NUM_PLAYERS ];
+
+ Scrooby::Sprite* m_totalTimeKingIcon;
+ Scrooby::Sprite* m_bestLapKingIcon;
+
+};
+
+#endif // GUISCREENMINISUMMARY_H
diff --git a/game/code/presentation/gui/utility/allutility.cpp b/game/code/presentation/gui/utility/allutility.cpp
new file mode 100644
index 0000000..f9cbf09
--- /dev/null
+++ b/game/code/presentation/gui/utility/allutility.cpp
@@ -0,0 +1,8 @@
+#include <presentation/gui/utility/hudmapcam.cpp>
+#include <presentation/gui/utility/hudmap.cpp>
+#include <presentation/gui/utility/numerictext.cpp>
+#include <presentation/gui/utility/slider.cpp>
+#include <presentation/gui/utility/specialfx.cpp>
+#include <presentation/gui/utility/teletypetext.cpp>
+#include <presentation/gui/utility/transitions.cpp>
+#include <presentation/gui/utility/scrollingtext.cpp>
diff --git a/game/code/presentation/gui/utility/colourutility.h b/game/code/presentation/gui/utility/colourutility.h
new file mode 100644
index 0000000..af8a24f
--- /dev/null
+++ b/game/code/presentation/gui/utility/colourutility.h
@@ -0,0 +1,63 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: .h
+//
+// Description: this file contains some operators for colors *, +, -, etc
+//
+// History: 29/01/2003 + Created -- Ian Gipson
+//
+//=============================================================================
+
+#ifndef _COLOURUTILITY_H_
+#define _COLOURUTILITY_H_
+
+#include <p3d/p3dtypes.hpp>
+
+//==============================================================================
+// operator+
+//==============================================================================
+// Description: addition of two colors
+//
+// Parameters: a, b, the two colors to add
+//
+// Return: the added version of the two colors
+//
+//==============================================================================
+inline tColour operator+( const tColour a, const tColour b )
+{
+ int rr = a.Red() + b.Red();
+ int gg = a.Green() + b.Green();
+ int bb = a.Blue() + b.Blue();
+ int aa = a.Alpha() + b.Alpha();
+ return( tColour( rr, gg, bb, aa ) );
+}
+
+//==============================================================================
+// operator*
+//==============================================================================
+// Description: multiplication of a color by a constant
+//
+// Parameters: a, the color
+// f, the float
+//
+// Return: the scaled version of the colour
+//
+//==============================================================================
+inline tColour operator*( const tColour a, const float f )
+{
+ int rr = static_cast< int >( a.Red() * f );
+ int gg = static_cast< int >( a.Green() * f );
+ int bb = static_cast< int >( a.Blue() * f );
+ int aa = static_cast< int >( a.Alpha() * f );
+ return tColour( rr, gg, bb, aa );
+}
+
+inline tColour operator*( const float f, const tColour a )
+{
+ return operator*( a, f);
+}
+
+#endif
+
+
diff --git a/game/code/presentation/gui/utility/hudmap.cpp b/game/code/presentation/gui/utility/hudmap.cpp
new file mode 100644
index 0000000..dcd4a07
--- /dev/null
+++ b/game/code/presentation/gui/utility/hudmap.cpp
@@ -0,0 +1,1914 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CHudMap
+//
+// Description: Implementation of the CHudMap class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/01 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/utility/hudmap.h>
+#include <presentation/gui/utility/hudmapcam.h>
+#include <presentation/gui/utility/specialfx.h>
+#include <presentation/gui/guiscreen.h>
+
+#include <ai/vehicle/vehicleai.h>
+#include <interiors/interiormanager.h>
+#include <memory/srrmemory.h>
+#include <meta/zoneeventlocator.h>
+#include <mission/gameplaymanager.h>
+#include <render/intersectmanager/intersectmanager.h>
+#include <roads/geometry.h>
+#include <roads/road.h>
+#include <roads/intersection.h>
+#include <roads/roadmanager.h>
+#include <worldsim/avatarmanager.h>
+#include <worldsim/avatar.h>
+#include <worldsim/hitnrunmanager.h>
+#include <worldsim/redbrick/vehicle.h>
+
+#include <p3d/utility.hpp>
+
+#include <raddebug.hpp> // Foundation
+
+#include <page.h>
+#include <group.h>
+#include <pure3dobject.h>
+#include <sprite.h>
+#include <polygon.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+#define SHOW_HUD_MAP
+#define CIRCULAR_HUD_MAP
+
+#ifdef CIRCULAR_HUD_MAP
+ #define SMARTER_ICON_LOCATIONS // only works for circular hud map
+#endif
+
+// This is for smooth camera height transitions, to prevent any sudden
+// camera cuts.
+//
+#define SMOOTH_CAMERA_HEIGHT_TRANSITIONS
+
+const int NUM_AMORTIZED_UPDATE_FRAMES = 5; // for DetermineOnRoadLocation()
+
+#ifdef DEBUGWATCH
+ #include <raddebugwatch.hpp>
+
+ static const char* WATCHER_NAMESPACE = "GUI System - HUD Map";
+
+ float MIN_CAMERA_HEIGHT = 50.0f;
+ float MAX_CAMERA_HEIGHT = 150.0f;
+
+ float MAX_CAMERA_HEIGHT_TRANSITION = 10.0f;
+
+ float CHASE_FLASH_DISTANCE_THRESHOLD = 0.5f;
+ float CHASE_FADE_DISTANCE_THRESHOLD = 0.75f;
+ float RADAR_VISIBLE_RADIUS = 150.0f; // in metres
+#else
+ const float MIN_CAMERA_HEIGHT = 50.0f;
+ const float MAX_CAMERA_HEIGHT = 150.0f;
+
+ const float MAX_CAMERA_HEIGHT_TRANSITION = 10.0f;
+
+ const float CHASE_FLASH_DISTANCE_THRESHOLD = 0.5f;
+ const float CHASE_FADE_DISTANCE_THRESHOLD = 0.75f;
+ const float RADAR_VISIBLE_RADIUS = 150.0f; // in metres
+#endif
+
+const float DEFAULT_CAMERA_HEIGHT = 150.0f; // in metres
+
+const float MAX_RADAR_CONE_ALPHA = 0.35f;
+
+enum eVisibilityMode
+{
+ VISIBLE_IN_SUNDAY_DRIVE = 1,
+ VISIBLE_IN_MISSION = 2,
+
+ NUM_VISIBILITY_MODES
+};
+
+const tColour HIT_N_RUN_COLOUR_RED( 255, 0, 0 );
+const tColour HIT_N_RUN_COLOUR_BLUE( 0, 0, 255 );
+
+HudMapIcon CHudMap::s_registeredIcons[ MAX_NUM_REGISTERED_ICONS ];
+int CHudMap::s_numRegisteredIcons = 0;
+int CHudMap::s_fpIconID = -1;
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+void
+HudMapIcon::ApplyAICarIconColour()
+{
+ rAssert( m_iconImage != NULL );
+
+ switch( m_type )
+ {
+ case ICON_AI_HIT_N_RUN:
+ {
+ m_iconImage->SetColour( HIT_N_RUN_COLOUR_RED );
+
+ break;
+ }
+ case ICON_AI_CHASE:
+ {
+ m_iconImage->SetColour( tColour( 255, 128, 0 ) );
+
+ break;
+ }
+ case ICON_AI_RACE:
+ {
+ m_iconImage->SetColour( tColour( 255, 255, 0 ) );
+
+ break;
+ }
+ case ICON_AI_EVADE:
+ {
+ m_iconImage->SetColour( tColour( 255, 255, 0 ) );
+
+ break;
+ }
+ case ICON_AI_TARGET:
+ {
+ m_iconImage->SetColour( tColour( 255, 0, 0 ) );
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Invalid AI car icon type!" );
+
+ break;
+ }
+ }
+}
+
+//===========================================================================
+// CHudMap::CHudMap
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CHudMap::CHudMap( Scrooby::Page* pPage, int playerID, const char* p3dFile )
+: m_playerID( playerID ),
+ m_p3dMap( NULL ),
+ m_p3dHole( NULL ),
+ m_originalPosX( 0 ),
+ m_originalPosY( 0 ),
+ m_originalWidth( 0 ),
+ m_originalHeight( 0 ),
+ m_isVisible( false ),
+ m_radar( NULL ),
+ m_radarCone( NULL ),
+ m_iconsGroup( NULL ),
+ m_hudMapCam( NULL ),
+ m_currentCameraHeight( DEFAULT_CAMERA_HEIGHT ),
+ m_fixedCameraHeight( 0.0f ),
+ m_currentAICarDistance( 0.0f ),
+ m_maxAICarDistance( 0.0f ),
+ m_elapsedTime( 0 ),
+ m_lastRoadSeg( NULL ),
+ m_lastOnRoadLocation( 0.0f, 0.0f, 0.0f ),
+ m_frameCount( -1 )
+{
+MEMTRACK_PUSH_GROUP( "CHudMap" );
+ memset( m_icons, 0, sizeof( m_icons ) );
+
+ m_hudMapCam = new HudMapCam( m_playerID );
+ rAssert( m_hudMapCam );
+ m_hudMapCam->AddRef();
+
+ m_currentCameraHeight = this->CalculateCameraHeight( RADAR_VISIBLE_RADIUS );
+
+ char name[ 16 ];
+ rAssert( pPage != NULL );
+
+ // get 3D HUD map
+ //
+ sprintf( name, "Map%d", playerID );
+ m_p3dMap = pPage->GetPure3dObject( name );
+ rAssert( m_p3dMap != NULL );
+ m_p3dMap->SetCamera( m_hudMapCam->GetCamera() );
+
+ // store original hud map position and size
+ //
+ m_p3dMap->GetOriginPosition( m_originalPosX, m_originalPosY );
+ m_p3dMap->GetBoundingBoxSize( m_originalWidth, m_originalHeight );
+
+#ifdef SHOW_HUD_MAP
+ if( p3dFile != NULL )
+ {
+ // set pure3d file for hud map
+ //
+ m_p3dMap->Add3dModel( p3dFile );
+ }
+
+ // get 3D HUD hole
+ //
+ sprintf( name, "Hole%d", playerID );
+ m_p3dHole = pPage->GetPure3dObject( name );
+ rAssert( m_p3dHole != NULL );
+ m_p3dHole->SetCamera( m_hudMapCam->GetCamera() );
+ m_p3dHole->SetColourWrite( false );
+
+ if( CGuiScreen::IsWideScreenDisplay() )
+ {
+ m_p3dMap->SetWideScreenCorrectionEnabled( true );
+ m_p3dHole->SetWideScreenCorrectionEnabled( true );
+ }
+#else
+ m_p3dMap->SetVisible( false );
+#endif
+
+/*
+ sprintf( name, "RadarLight%d", playerID );
+ m_radarLight = pPage->GetSprite( name );
+ rAssert( m_radarLight != NULL );
+
+ // hide radar light temporarily
+ //
+ m_radarLight->SetVisible( false );
+*/
+
+ // get radar & radar cone
+ //
+ sprintf( name, "Radar%d", playerID );
+ m_radar = pPage->GetGroup( name );
+ rAssert( m_radar != NULL );
+
+ sprintf( name, "RadarCone%d", playerID );
+ m_radarCone = pPage->GetGroup( name );
+ rAssert( m_radarCone != NULL );
+
+ Scrooby::Polygon* radarConePolygon = m_radarCone->GetPolygon( name );
+ rAssert( radarConePolygon != NULL );
+ radarConePolygon->SetAlpha( MAX_RADAR_CONE_ALPHA );
+
+ // get icons group
+ //
+ sprintf( name, "Icons%d", playerID );
+ m_iconsGroup = pPage->GetGroup( name );
+ rAssert( m_iconsGroup != NULL );
+
+#ifdef DEBUGWATCH
+ ::radDbgWatchAddFloat( &MIN_CAMERA_HEIGHT,
+ "Mininum Camera Height",
+ WATCHER_NAMESPACE,
+ NULL, NULL, 30.0f, 90.0f );
+
+ ::radDbgWatchAddFloat( &MAX_CAMERA_HEIGHT,
+ "Maximum Camera Height",
+ WATCHER_NAMESPACE,
+ NULL, NULL, 100.0f, 1000.0f );
+
+ ::radDbgWatchAddFloat( &MAX_CAMERA_HEIGHT_TRANSITION,
+ "Maximum Camera Height Change",
+ WATCHER_NAMESPACE,
+ NULL, NULL, 1.0f, 50.0f );
+
+ ::radDbgWatchAddFloat( &RADAR_VISIBLE_RADIUS,
+ "Radar Visible Radius",
+ WATCHER_NAMESPACE,
+ NULL, NULL, 0.0f, 1000.0f );
+
+ ::radDbgWatchAddFloat( &CHASE_FLASH_DISTANCE_THRESHOLD,
+ "Chase Flash Distance (%)",
+ WATCHER_NAMESPACE );
+
+ ::radDbgWatchAddFloat( &CHASE_FADE_DISTANCE_THRESHOLD,
+ "Chase Fade Distance (%)",
+ WATCHER_NAMESPACE );
+#endif
+MEMTRACK_POP_GROUP("CHudMap");
+}
+
+//===========================================================================
+// CHudMap::~CHudMap
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CHudMap::~CHudMap()
+{
+#ifdef DEBUGWATCH
+ ::radDbgWatchDelete( &MIN_CAMERA_HEIGHT );
+ ::radDbgWatchDelete( &MAX_CAMERA_HEIGHT );
+ ::radDbgWatchDelete( &MAX_CAMERA_HEIGHT_TRANSITION );
+ ::radDbgWatchDelete( &RADAR_VISIBLE_RADIUS );
+ ::radDbgWatchDelete( &CHASE_FLASH_DISTANCE_THRESHOLD );
+ ::radDbgWatchDelete( &CHASE_FADE_DISTANCE_THRESHOLD );
+#endif
+
+ if( m_hudMapCam != NULL )
+ {
+ m_hudMapCam->Release();
+ m_hudMapCam = NULL;
+ }
+}
+
+//===========================================================================
+// CHudMap::SetCameraTarget
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void
+CHudMap::SetCameraTarget( ISuperCamTarget* target )
+{
+ rAssert( m_hudMapCam );
+ m_hudMapCam->SetTarget( target );
+}
+
+void
+CHudMap::EnableFixedCameraHeight( bool enable, float visibleRadius )
+{
+/*
+ if( !enable )
+ {
+ rWarningMsg( false, "Can't disable fixed camera height in new radar implementation!" );
+
+ // ignore request to disable fixed camera height
+ //
+ return;
+ }
+*/
+ m_fixedCameraHeight = enable ?
+ visibleRadius / rmt::Tan( m_hudMapCam->GetFOV() / 2.0f ) :
+ 0.0f;
+}
+
+//===========================================================================
+// CHudMap::Update
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void
+CHudMap::Update( unsigned int elapsedTime )
+{
+ if( GetInteriorManager()->IsInside() )
+ {
+ this->SetVisible( false );
+ }
+
+ if( !m_isVisible )
+ {
+ // no need to update if not visible
+ //
+ return;
+ }
+
+/*
+ // update radar light (just rotate about radar center point)
+ //
+ static float RADAR_ROTATION_PERIOD = 2000.0f; // in msec
+ float rotation = (elapsedTime / RADAR_ROTATION_PERIOD) * 360.0f;
+ rAssert( m_radarLight != NULL );
+ m_radarLight->RotateAboutCenter( rotation );
+*/
+
+ // get current hud map position and size
+ //
+ int mapX = 0;
+ int mapY = 0;
+ int mapWidth = 0;
+ int mapHeight = 0;
+
+ rAssert( m_p3dMap != NULL );
+ m_p3dMap->GetOriginPosition( mapX, mapY );
+ m_p3dMap->GetBoundingBoxSize( mapWidth, mapHeight );
+
+ float newCameraHeight = DEFAULT_CAMERA_HEIGHT;
+ if( m_fixedCameraHeight != 0.0f ) // fixed camera height enabled
+ {
+ newCameraHeight = m_fixedCameraHeight;
+ }
+ else
+ {
+ if( s_fpIconID != -1 )
+ {
+ HudMapIcon* focalPointIcon = &(s_registeredIcons[ s_fpIconID ]);
+ rAssert( focalPointIcon->m_iconImage );
+
+ if( focalPointIcon->m_dynamicLocator != NULL )
+ {
+ focalPointIcon->m_dynamicLocator->GetPosition( &(focalPointIcon->m_location) );
+ }
+
+ newCameraHeight = this->CalculateCameraHeight( s_registeredIcons[ 0 ].m_location,
+ focalPointIcon->m_location );
+ }
+ }
+
+#ifdef SMOOTH_CAMERA_HEIGHT_TRANSITIONS
+ // for smoother camera height transitions
+ //
+ float cameraHeightChange = newCameraHeight - m_currentCameraHeight;
+ if( rmt::Abs( cameraHeightChange ) > MAX_CAMERA_HEIGHT_TRANSITION )
+ {
+ m_currentCameraHeight += rmt::Sign( cameraHeightChange ) * MAX_CAMERA_HEIGHT_TRANSITION;
+// rTunePrintf( "Current camera height = %f m\n", m_currentCameraHeight );
+ }
+ else
+#endif
+ {
+ m_currentCameraHeight = newCameraHeight;
+ }
+
+ // update hud map camera
+ //
+ rAssert( m_hudMapCam != NULL );
+ m_hudMapCam->SetHeight( m_currentCameraHeight );
+ m_hudMapCam->SetAspect( (float)mapWidth / (float)mapHeight );
+ m_hudMapCam->Update( elapsedTime );
+
+ rmt::Vector hudMapCenter;
+ m_hudMapCam->GetPosition( &hudMapCenter );
+
+#ifdef CIRCULAR_HUD_MAP
+ // update hud hole
+ //
+ if( m_p3dHole != NULL )
+ {
+ static float awayFromCam = 4.5f;
+ m_p3dHole->SetDrawableTranslation( hudMapCenter.x,
+ hudMapCenter.y - awayFromCam,
+ hudMapCenter.z );
+ }
+#endif
+
+ // update registered icons
+ //
+ int iconPosX = 0;
+ int iconPosY = 0;
+ int iconWidth = 0;
+ int iconHeight = 0;
+
+ const unsigned int PULSE_PERIOD = 500;
+// bool iconBlinked = false;
+
+// rWarningMsg( s_fpIconID != -1, "No active focal point icon on hud map!" );
+
+ for( unsigned int i = 0; i < MAX_NUM_REGISTERED_ICONS; i++ )
+ {
+ if( s_registeredIcons[ i ].m_iconImage != NULL )
+ {
+ // check if visible in current gameplay mode
+ //
+ if( GetGameplayManager()->IsSundayDrive() )
+ {
+ if( (s_registeredIcons[ i ].m_visibilityMask & VISIBLE_IN_SUNDAY_DRIVE) == 0 )
+ {
+ s_registeredIcons[ i ].m_iconImage->SetVisible( false );
+ continue;
+ }
+ }
+ else
+ {
+ if( (s_registeredIcons[ i ].m_visibilityMask & VISIBLE_IN_MISSION) == 0 )
+ {
+ s_registeredIcons[ i ].m_iconImage->SetVisible( false );
+ continue;
+ }
+ }
+
+ // hide icons that are not visible when player is in car
+ //
+ if( s_registeredIcons[ i ].m_type == HudMapIcon::ICON_PHONE_BOOTH ||
+ s_registeredIcons[ i ].m_type == HudMapIcon::ICON_PLAYER_CAR )
+ {
+ Avatar* player = GetAvatarManager()->GetAvatarForPlayer( m_playerID );
+ rAssert( player != NULL );
+ if( player->IsInCar() )
+ {
+ s_registeredIcons[ i ].m_iconImage->SetVisible( false );
+ continue;
+ }
+ }
+
+// s_registeredIcons[ i ].m_iconImage->SetAlpha( 1.0f );
+
+ // center icon in hud map first
+ //
+ s_registeredIcons[ i ].m_iconImage->GetBoundingBoxSize( iconWidth, iconHeight );
+ iconPosX = (mapX + mapWidth / 2) - (iconWidth / 2);
+ iconPosY = (mapY + mapHeight / 2) - (iconHeight / 2);
+ s_registeredIcons[ i ].m_iconImage->SetPosition( iconPosX, iconPosY );
+
+ s_registeredIcons[ i ].m_iconImage->ResetTransformation();
+
+ // update current location for dynamic icons
+ if( s_registeredIcons[ i ].m_dynamicLocator != NULL )
+ {
+ s_registeredIcons[ i ].m_dynamicLocator->GetPosition( &s_registeredIcons[ i ].m_location );
+
+ // place icon object at sea level
+ s_registeredIcons[ i ].m_location.y = 0;
+
+ if( s_registeredIcons[ i ].IsAICarIcon() ||
+ s_registeredIcons[ i ].m_type == HudMapIcon::ICON_PLAYER ||
+ s_registeredIcons[ i ].m_type == HudMapIcon::ICON_PLAYER_CAR )
+ {
+ rmt::Vector heading( 0, 0, 0 );
+ s_registeredIcons[ i ].m_dynamicLocator->GetHeading( &heading );
+
+ this->UpdateIconHeading( s_registeredIcons[ i ].m_iconImage, &heading );
+ }
+ }
+
+ rmt::Vector iconLocInWorld = s_registeredIcons[ i ].m_location;
+
+#ifdef SMARTER_ICON_LOCATIONS
+ if( static_cast< int >( i ) == s_fpIconID )
+ {
+ // TC: [TODO] need to determine this from the maximum camera height and the
+ // clipping boundary value
+ //
+ static float visibleRadius = 120.0f;
+
+ this->DetermineOnRoadLocation( hudMapCenter,
+ iconLocInWorld,
+ visibleRadius );
+ }
+#endif
+
+ rmt::Vector iconLoc( 0, 0, 0 );
+ rAssert( m_p3dMap->GetCamera() );
+ m_p3dMap->GetCamera()->WorldToView( iconLocInWorld, &iconLoc );
+ iconLoc.z = 0.0f;
+
+ static float CLIPPING_BOUNDARY = 0.40f;
+ float iconScale = 1.0f;
+
+#ifdef CIRCULAR_HUD_MAP
+ // apply view clipping (for circular view)
+ //
+ float iconLength = iconLoc.Magnitude();
+ if( iconLength > CLIPPING_BOUNDARY )
+ {
+ iconScale = CLIPPING_BOUNDARY / iconLength;
+ iconLoc.Scale( iconScale );
+ }
+#else
+ // apply view clipping (for rectangular view)
+ //
+
+ // x-clipping
+ float xScale = 1.0f;
+ if( iconLoc.x > CLIPPING_BOUNDARY )
+ {
+ xScale = CLIPPING_BOUNDARY / iconLoc.x;
+ iconLoc.Scale( xScale, xScale, 1 );
+ }
+ else if( iconLoc.x < -CLIPPING_BOUNDARY )
+ {
+ xScale = -CLIPPING_BOUNDARY / iconLoc.x;
+ iconLoc.Scale( xScale, xScale, 1 );
+ }
+
+ // y-clipping
+ float yScale = 1.0f;
+ if( iconLoc.y > CLIPPING_BOUNDARY )
+ {
+ yScale = CLIPPING_BOUNDARY / iconLoc.y;
+ iconLoc.Scale( yScale, yScale, 1 );
+ }
+ else if( iconLoc.y < -CLIPPING_BOUNDARY )
+ {
+ yScale = -CLIPPING_BOUNDARY / iconLoc.y;
+ iconLoc.Scale( yScale, yScale, 1 );
+ }
+
+ iconScale = xScale * yScale;
+#endif
+
+ bool isIconClipped = (iconScale < 1.0f);
+
+ rAssert( m_radarCone != NULL );
+ m_radarCone->SetVisible( s_fpIconID != -1 );
+
+ if( static_cast< int >( i ) == s_fpIconID ) // for focal point icon ...
+ {
+ // update radar cone direction
+ //
+ m_radarCone->ResetTransformation();
+ m_radarCone->RotateAboutCenter( rmt::RadianToDeg( this->CalculatRadarConeAngle( iconLoc ) ) );
+
+ if( !isIconClipped || s_registeredIcons[ i ].IsAICarIcon() )
+ {
+ m_radarCone->SetAlpha( iconScale );
+ }
+ else
+ {
+ const float MINIMUM_ICON_SCALE = 0.75f;
+ float alpha = (iconScale - MINIMUM_ICON_SCALE) / (1.0f - MINIMUM_ICON_SCALE);
+ m_radarCone->SetAlpha( alpha > 0.0f ? alpha : 0.0f );
+ }
+/*
+ // apply alpha if focal point icon is clipped on boundary
+ //
+ if( iconScale < 1.0f )
+ {
+ if( iconScale < 0.3f )
+ {
+ s_registeredIcons[ i ].m_iconImage->SetAlpha( 0.3f );
+ }
+ else
+ {
+ s_registeredIcons[ i ].m_iconImage->SetAlpha( iconScale );
+ }
+ }
+ else
+ {
+ s_registeredIcons[ i ].m_iconImage->SetAlpha( 1.0f );
+ }
+*/
+
+#ifdef SMARTER_ICON_LOCATIONS
+ s_registeredIcons[ i ].m_iconImage->SetVisible( true );
+#else
+ if( !s_registeredIcons[ i ].IsAICarIcon() )
+ {
+ // hide non-AI car icons if clipped on boundary
+ //
+ s_registeredIcons[ i ].m_iconImage->SetVisible( !isIconClipped );
+ }
+#endif
+
+ // special cases
+ //
+ if( s_registeredIcons[ i ].m_type == HudMapIcon::ICON_MISSION )
+ {
+ static float SCALE_AMPLITUDE = 0.25f;
+
+ float scale = GuiSFX::Pulse( (float)m_elapsedTime,
+ (float)PULSE_PERIOD,
+ 1.0f + SCALE_AMPLITUDE,
+ SCALE_AMPLITUDE );
+
+/*
+ float scale = 1.0f + (float)m_elapsedTime / PULSE_PERIOD * SCALE_AMPLITUDE;
+ float alpha = 1.0f - (float)m_elapsedTime / PULSE_PERIOD * ALPHA_AMPLITUDE;
+
+ s_registeredIcons[ i ].m_iconImage->SetAlpha( alpha );
+*/
+ s_registeredIcons[ i ].m_iconImage->ScaleAboutCenter( scale );
+ }
+/*
+ else if( s_registeredIcons[ i ].m_type == HudMapIcon::ICON_AI_CAR )
+ {
+ // if focal point is AI car icon, fade out when near
+ // distance limit
+ //
+ if( m_maxAICarDistance > 0.0f )
+ {
+ float distanceRatio = m_currentAICarDistance / m_maxAICarDistance;
+ rAssert( distanceRatio <= 1.0f );
+
+ if( distanceRatio > CHASE_FLASH_DISTANCE_THRESHOLD )
+ {
+ // blink icon
+ //
+ iconBlinked = GuiSFX::Blink( s_registeredIcons[ i ].m_iconImage,
+ (float)m_elapsedTime,
+ (float)BLINKING_PERIOD );
+
+ if( distanceRatio > CHASE_FADE_DISTANCE_THRESHOLD )
+ {
+ float iconAlpha = (1.0f - distanceRatio) /
+ (1.0f - CHASE_FADE_DISTANCE_THRESHOLD);
+
+ s_registeredIcons[ i ].m_iconImage->SetAlpha( iconAlpha );
+ }
+ else
+ {
+ s_registeredIcons[ i ].m_iconImage->SetAlpha( 1.0f );
+ }
+ }
+ else
+ {
+ s_registeredIcons[ i ].m_iconImage->SetVisible( true );
+ }
+ }
+ }
+*/
+ }
+ else // for non-focal point icons ...
+ {
+ if( !s_registeredIcons[ i ].IsAICarIcon() )
+ {
+ // hide non-AI car icons if clipped on boundary
+ //
+ s_registeredIcons[ i ].m_iconImage->SetVisible( !isIconClipped );
+ }
+/*
+ // for phone booth icons
+ //
+ if( s_registeredIcons[ i ].m_type == HudMapIcon::ICON_PHONE_BOOTH )
+ {
+ // only show if within visible radius
+ //
+ rmt::Vector playerToPhone;
+ playerToPhone.Sub( s_registeredIcons[ i ].m_location,
+ s_registeredIcons[ 0 ].m_location );
+
+ float distanceRatio = playerToPhone.Magnitude() / PHONE_BOOTH_VISIBLE_RADIUS;
+ bool isWithinRadius = (distanceRatio < 1.0f);
+
+ // fade out nicely to prevent popping
+ //
+ const float FADE_OUT_THRESHOLD = 0.9f;
+ if( !isIconClipped && isWithinRadius )
+ {
+ if( distanceRatio > FADE_OUT_THRESHOLD )
+ {
+ float iconAlpha = (1.0f - distanceRatio) / (1.0f - FADE_OUT_THRESHOLD);
+ s_registeredIcons[ i ].m_iconImage->SetAlpha( iconAlpha );
+ }
+ else
+ {
+ s_registeredIcons[ i ].m_iconImage->SetAlpha( 1.0f );
+ }
+ }
+ else
+ {
+ s_registeredIcons[ i ].m_iconImage->SetAlpha( 0.0f );
+ }
+ }
+*/
+ }
+
+ if( s_registeredIcons[ i ].m_type == HudMapIcon::ICON_AI_HIT_N_RUN )
+ {
+ if( GetHitnRunManager()->IsHitnRunActive() )
+ {
+ s_registeredIcons[ i ].m_iconImage->SetVisible( true );
+
+ // modulate icon colour
+ //
+ tColour iconColour;
+ GuiSFX::ModulateColour( &iconColour,
+ (float)m_elapsedTime,
+ (float)PULSE_PERIOD,
+ HIT_N_RUN_COLOUR_RED,
+ HIT_N_RUN_COLOUR_BLUE );
+
+ s_registeredIcons[ i ].m_iconImage->SetColour( iconColour );
+ }
+ else
+ {
+ // hide icon if H&R is not active
+ //
+ s_registeredIcons[ i ].m_iconImage->SetVisible( false );
+ }
+ }
+
+ // translate the icon (in screen space wrt. hud map center)
+ //
+ int iconX = static_cast<int>( iconLoc.x * mapWidth );
+ int iconY = static_cast<int>( iconLoc.y * mapHeight );
+
+ s_registeredIcons[ i ].m_iconImage->Translate( iconX, iconY );
+ }
+ }
+/*
+ if( iconBlinked )
+ {
+ m_elapsedTime %= PULSE_PERIOD;
+ }
+*/
+ m_elapsedTime = (m_elapsedTime + elapsedTime) % PULSE_PERIOD;
+}
+
+//===========================================================================
+// CHudMap::AddIconToInventory
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void
+CHudMap::AddIconToInventory( HudMapIcon::eIconType type, Scrooby::Sprite* image )
+{
+ if( image == NULL )
+ {
+ return;
+ }
+
+ unsigned int i = 0;
+
+ for( i = 0; i < MAX_NUM_ICONS_PER_TYPE; i++ )
+ {
+ // find first empty slot in inventory to add icon
+ //
+ if( m_icons[ type ][ i ] == NULL )
+ {
+ m_icons[ type ][ i ] = image;
+
+ // hide icon image
+ //
+ image->SetVisible( false );
+
+ break;
+ }
+ }
+
+ rAssertMsg( i < MAX_NUM_ICONS_PER_TYPE,
+ "ERROR: *** Exceeded maximum number of icons per type!\n" );
+}
+
+//===========================================================================
+// CHudMap::RemoveIconFromInventory
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+Scrooby::Sprite*
+CHudMap::RemoveIconFromInventory( HudMapIcon::eIconType type )
+{
+ Scrooby::Sprite* iconImage = NULL;
+
+ // find an available icon of specified type in inventory
+ //
+ for( unsigned int i = 0; i < MAX_NUM_ICONS_PER_TYPE; i++ )
+ {
+ if( m_icons[ type ][ i ] != NULL )
+ {
+ iconImage = m_icons[ type ][ i ];
+ iconImage->SetVisible( true );
+
+ // free up slot in inventory
+ //
+ m_icons[ type ][ i ] = NULL;
+
+ break;
+ }
+ }
+
+ return iconImage;
+}
+
+//===========================================================================
+// CHudMap::RegisterIcon
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+int
+CHudMap::RegisterIcon( HudMapIcon::eIconType type,
+ rmt::Vector location,
+ IHudMapIconLocator* hudMapIconLocator,
+ bool newFocalPoint )
+{
+ rAssert( s_numRegisteredIcons < static_cast<int>( MAX_NUM_REGISTERED_ICONS ) );
+
+ int iconID = -1;
+
+ Scrooby::Sprite* iconImage = this->RemoveIconFromInventory( type );
+ if( iconImage == NULL )
+ {
+ rAssertMsg( false, "WARNING: *** No more available icons of this type! Please tell Tony." );
+
+ return -1;
+ }
+
+ // convert locations in interiors to world-space location of the interior
+ //
+ tName interiorName = GetInteriorManager()->ClassifyPoint( location );
+ if( interiorName.GetUID() != static_cast< tUID >( 0 ) )
+ {
+ ZoneEventLocator* locator = p3d::find<ZoneEventLocator>( interiorName.GetUID() );
+ locator->GetPosition( &location );
+
+ if( hudMapIconLocator != NULL )
+ {
+ hudMapIconLocator = locator;
+ }
+ }
+
+#ifdef RAD_DEBUG
+ // check if there's already a static icon of the same type
+ // registered at exactly the same location
+ //
+ for( unsigned int j = 0; j < MAX_NUM_REGISTERED_ICONS; j++ )
+ {
+ if( s_registeredIcons[ j ].m_iconImage != NULL &&
+ s_registeredIcons[ j ].m_type == type )
+ {
+ rAssertMsg( s_registeredIcons[ j ].m_dynamicLocator != NULL ||
+ s_registeredIcons[ j ].m_location != location,
+ "WARNING: *** Another icon of this type has already been registered at this location. Is this by design??" );
+ }
+ }
+#endif // RAD_DEBUG
+
+ for( unsigned int i = 0; i < MAX_NUM_REGISTERED_ICONS; i++ )
+ {
+ if( i == 0 && type != HudMapIcon::ICON_PLAYER )
+ {
+ // icon ID = 0 is reserved for player icon
+ continue;
+ }
+
+ // find first empty slot to register icon
+ if( s_registeredIcons[ i ].m_iconImage == NULL )
+ {
+ iconID = i;
+ s_numRegisteredIcons++;
+
+ // place icon object at sea level
+ location.y = 0;
+
+ s_registeredIcons[ iconID ].m_iconImage = iconImage;
+ s_registeredIcons[ iconID ].m_type = type;
+ s_registeredIcons[ iconID ].m_location = location;
+ s_registeredIcons[ iconID ].m_dynamicLocator = hudMapIconLocator;
+
+ // set visible in sunday drive mode for these icon types
+ //
+ if( type == HudMapIcon::ICON_PLAYER ||
+ type == HudMapIcon::ICON_PLAYER_CAR ||
+ type == HudMapIcon::ICON_MISSION ||
+ type == HudMapIcon::ICON_BONUS_MISSION ||
+ type == HudMapIcon::ICON_STREET_RACE ||
+ type == HudMapIcon::ICON_WAGER_RACE ||
+ type == HudMapIcon::ICON_PURCHASE_CENTRE ||
+ type == HudMapIcon::ICON_PHONE_BOOTH ||
+ type == HudMapIcon::ICON_AI_HIT_N_RUN )
+ {
+ s_registeredIcons[ i ].m_visibilityMask |= VISIBLE_IN_SUNDAY_DRIVE;
+ }
+
+ // set visible in mission mode for these icon types
+ //
+ if( type == HudMapIcon::ICON_PLAYER ||
+ type == HudMapIcon::ICON_PLAYER_CAR ||
+ type == HudMapIcon::ICON_FLAG_CHECKERED ||
+ type == HudMapIcon::ICON_FLAG_WAYPOINT ||
+ type == HudMapIcon::ICON_COLLECTIBLE ||
+ type == HudMapIcon::ICON_MISSION ||
+ s_registeredIcons[ i ].IsAICarIcon() )
+ {
+ s_registeredIcons[ i ].m_visibilityMask |= VISIBLE_IN_MISSION;
+ }
+
+ // colour code AI car icons
+ //
+ if( s_registeredIcons[ i ].IsAICarIcon() )
+ {
+ s_registeredIcons[ i ].ApplyAICarIconColour();
+ }
+
+ break;
+ }
+ }
+
+ rAssertMsg( iconID != -1, "ERROR: *** There should have been an empty slot!\n" );
+
+ if( newFocalPoint )
+ {
+ // set as new focal point icon
+ //
+ s_fpIconID = iconID;
+
+ // whenever the target changes, we want to recompute its closest road segment
+ m_lastRoadSeg = NULL;
+
+ m_frameCount = -1; // reset frame count
+ }
+
+
+ return iconID;
+}
+
+//===========================================================================
+// CHudMap::UnregisterIcon
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void
+CHudMap::UnregisterIcon( int iconID )
+{
+ if( iconID != -1 )
+ {
+ rAssert( iconID < static_cast<int>( MAX_NUM_REGISTERED_ICONS ) );
+
+ if( s_registeredIcons[ iconID ].m_iconImage != NULL )
+ {
+ // return icon to inventory
+ //
+ this->AddIconToInventory( s_registeredIcons[ iconID ].m_type,
+ s_registeredIcons[ iconID ].m_iconImage );
+
+ s_registeredIcons[ iconID ].m_iconImage = NULL;
+ s_registeredIcons[ iconID ].m_visibilityMask = 0;
+ s_numRegisteredIcons--;
+
+ if( s_fpIconID == iconID )
+ {
+ s_fpIconID = -1;
+ }
+ }
+ }
+ else
+ {
+ rAssertMsg( false, "This should only happen if you didn't get a valid icon ID upon registration!" );
+ }
+}
+
+//=============================================================================
+// CHudMap::ChangeIconType
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( HudMapIcon::eIconType type, int iconID )
+//
+// Return: void
+//
+//=============================================================================
+int
+CHudMap::ChangeIconType( int iconID, HudMapIcon::eIconType type )
+{
+ int newIconID = -1;
+
+ if( iconID != -1 )
+ {
+ bool isFocalPointIcon = (iconID == s_fpIconID);
+
+ // save a copy of old icon
+ //
+ HudMapIcon* oldIcon = &s_registeredIcons[ iconID ];
+
+ // unregister it first
+ //
+ this->UnregisterIcon( iconID );
+
+ // re-registered icon of new type
+ //
+ newIconID = this->RegisterIcon( type, oldIcon->m_location, oldIcon->m_dynamicLocator, isFocalPointIcon );
+ }
+
+ return newIconID;
+}
+
+//===========================================================================
+// CHudMap::SetFocalPointIcon
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void
+CHudMap::SetFocalPointIcon( int iconID )
+{
+ if( iconID != -1 )
+ {
+ rAssert( iconID < static_cast< int >( MAX_NUM_REGISTERED_ICONS ) );
+ s_fpIconID = iconID;
+
+ // whenever the target changes, we want to recompute its closest road segment
+ m_lastRoadSeg = NULL;
+
+ m_frameCount = -1; // reset frame count
+ }
+}
+
+//===========================================================================
+// CHudMap::FindIcon
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+HudMapIcon*
+CHudMap::FindIcon( HudMapIcon::eIconType type ) const
+{
+ const HudMapIcon* icon = NULL;
+
+ for( unsigned int i = 0; i < MAX_NUM_REGISTERED_ICONS; i++ )
+ {
+ if( s_registeredIcons[ i ].m_iconImage != NULL &&
+ s_registeredIcons[ i ].m_type == type )
+ {
+ // found it!
+ //
+ icon = &(s_registeredIcons[ i ]);
+
+ break;
+ }
+ }
+
+ return const_cast<HudMapIcon*>( icon );
+}
+
+//===========================================================================
+// CHudMap::Translate
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CHudMap::Translate( int x, int y )
+{
+ rAssert( m_p3dMap );
+
+ m_originalPosX += x;
+ m_originalPosY += y;
+ m_p3dMap->SetPosition( m_originalPosX, m_originalPosY );
+ if( m_p3dHole != NULL )
+ {
+ m_p3dHole->SetPosition( m_originalPosX, m_originalPosY );
+ }
+
+ this->Update( 0 );
+}
+
+//===========================================================================
+// CHudMap::Reset
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CHudMap::Reset()
+{
+ rAssert( m_p3dMap != NULL );
+
+ // restore hud map position and size
+ //
+ m_p3dMap->SetPosition( m_originalPosX, m_originalPosY );
+ m_p3dMap->SetBoundingBoxSize( m_originalWidth, m_originalHeight );
+
+ if( m_p3dHole != NULL )
+ {
+ m_p3dHole->SetPosition( m_originalPosX, m_originalPosY );
+ m_p3dHole->SetBoundingBoxSize( m_originalWidth, m_originalHeight );
+ }
+
+ // restore hud map camera
+ //
+ m_p3dMap->SetCamera( m_hudMapCam->GetCamera() );
+
+ m_elapsedTime = 0;
+
+ this->Update( 0 );
+}
+
+//===========================================================================
+// CHudMap::SetVisible
+//===========================================================================
+// Description: Toggle visibility of 3D map.
+//
+// Constraints: None.
+//
+// Parameters: visibility
+//
+// Return:
+//
+//===========================================================================
+void CHudMap::SetVisible( bool isVisible )
+{
+ m_isVisible = isVisible;
+
+ rAssert( m_p3dMap != NULL );
+ m_p3dMap->SetVisible( isVisible );
+
+ rAssert( m_radar != NULL );
+ m_radar->SetVisible( isVisible );
+
+ rAssert( m_iconsGroup != NULL );
+ m_iconsGroup->SetVisible( isVisible );
+}
+
+void
+CHudMap::RestoreAllRegisteredIcons()
+{
+ if( s_numRegisteredIcons > 0 )
+ {
+ int numIconsRestored = 0;
+
+ for( unsigned int i = 0; i < MAX_NUM_REGISTERED_ICONS; i++ )
+ {
+ if( s_registeredIcons[ i ].m_iconImage != NULL )
+ {
+ s_registeredIcons[ i ].m_iconImage = this->RemoveIconFromInventory( s_registeredIcons[ i ].m_type );
+ rAssert( s_registeredIcons[ i ].m_iconImage != NULL );
+
+ if( s_registeredIcons[ i ].IsAICarIcon() )
+ {
+ s_registeredIcons[ i ].ApplyAICarIconColour();
+ }
+
+ numIconsRestored++;
+ }
+ }
+
+ rAssertMsg( numIconsRestored == s_numRegisteredIcons, "Not all registered icons were restored!" );
+ }
+}
+
+void
+CHudMap::ClearAllRegisteredIcons()
+{
+ memset( s_registeredIcons, 0, sizeof( s_registeredIcons ) );
+ s_numRegisteredIcons = 0;
+ s_fpIconID = -1;
+}
+
+//===========================================================================
+// Private Member Functions
+//===========================================================================
+
+//===========================================================================
+// CHudMap::CalculateDistanceBetweenPoints
+//===========================================================================
+// Description: Calculates the scalar distance between 2 points in 3D-space.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+float
+CHudMap::CalculateDistanceBetweenPoints( rmt::Vector& a, rmt::Vector& b )
+{
+ rmt::Vector displacement( 0.0f, 0.0f, 0.0f );
+ displacement.Sub( a, b );
+
+ return displacement.Magnitude();
+}
+
+//===========================================================================
+// CHudMap::UpdateIconHeading
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void
+CHudMap::UpdateIconHeading( Scrooby::Sprite* iconImage, rmt::Vector* iconHeading )
+{
+ rmt::Vector objectHeading( iconHeading->x, 0, iconHeading->z );
+
+ rmt::Vector camHeading;
+ tPointCamera* camera = (tPointCamera*)m_p3dMap->GetCamera();
+ rAssert( camera );
+ camera->GetVUp( &camHeading );
+ camHeading.y = 0.0f;
+
+ if( camHeading.MagnitudeSqr() > 0.0f && objectHeading.MagnitudeSqr() > 0.0f )
+ {
+ float ratio = camHeading.Dot( objectHeading ) /
+ (camHeading.Magnitude() * objectHeading.Magnitude());
+
+ float rotation = 0.0f;
+
+ if( ratio > 1.0f )
+ {
+ rotation = 0.0f;
+ }
+ else if( ratio < -1.0f )
+ {
+ rotation = rmt::PI;
+ }
+ else
+ {
+ rotation = rmt::ACos( ratio );
+ }
+
+ rAssert( !rmt::IsNan( rotation ) );
+
+ rmt::Vector normal = camHeading;
+ normal.CrossProduct( objectHeading );
+ if( normal.y < 0 )
+ {
+ rotation = -rotation;
+ }
+
+ rAssert( iconImage );
+ iconImage->RotateAboutCenter( rmt::RadianToDeg( rotation ) );
+ }
+}
+
+//===========================================================================
+// CHudMap::CalculateCameraHeight
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+float
+CHudMap::CalculateCameraHeight( rmt::Vector& player, rmt::Vector& mission ) const
+{
+ // fix locations at sea level
+ //
+ player.y = 0;
+ mission.y = 0;
+
+ float distance = CalculateDistanceBetweenPoints( player, mission );
+
+ // calculate camera height based on distance
+ //
+ float cameraHeight = this->CalculateCameraHeight( distance * 1.5f );
+
+ if( cameraHeight < MIN_CAMERA_HEIGHT )
+ {
+ cameraHeight = MIN_CAMERA_HEIGHT;
+ }
+ else if( cameraHeight > MAX_CAMERA_HEIGHT )
+ {
+ cameraHeight = MAX_CAMERA_HEIGHT;
+ }
+
+ return cameraHeight;
+}
+
+//===========================================================================
+// CHudMap::CalculateCameraHeight
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+float
+CHudMap::CalculateCameraHeight( float visibleRadius ) const
+{
+ float cameraHeight = visibleRadius;
+ if( rmt::Abs( m_hudMapCam->GetFOV() - rmt::PI_BY2 ) > 0.001f )
+ {
+ cameraHeight = visibleRadius / rmt::Tan( m_hudMapCam->GetFOV() / 2.0f );
+ }
+
+ return cameraHeight;
+}
+
+//===========================================================================
+// CHudMap::CalculatRadarConeAngle
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+float
+CHudMap::CalculatRadarConeAngle( rmt::Vector& iconLoc ) const
+{
+ float radarConeAngle = 0.0f; // zero angle by default
+
+ if( iconLoc.y > 0.0f ) // icon is located in either Quadrant I or II
+ {
+ radarConeAngle = rmt::ATan( iconLoc.x / iconLoc.y );
+ }
+ else if( iconLoc.y < 0.0f ) // icon is located in either Quadrant III or IV
+ {
+ radarConeAngle = rmt::ATan( iconLoc.x / iconLoc.y ) + rmt::PI;
+ }
+ else // icon is located somewhere along the X-axis
+ {
+ if( iconLoc.x > 0.0f )
+ {
+ radarConeAngle = rmt::PI_BY2;
+ }
+ else if( iconLoc.x < 0.0f )
+ {
+ radarConeAngle = -rmt::PI_BY2;
+ }
+ }
+
+ return radarConeAngle;
+}
+
+//===========================================================================
+// CHudMap::DetermineOnRoadLocation
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+
+// We return the target vector (where we want to direct the navigation cone)
+void
+CHudMap::DetermineOnRoadLocation( rmt::Vector& source, rmt::Vector& target, float visibleRadius )
+{
+ // place source and target at sea level
+ //
+ source.y = 0;
+ target.y = 0;
+
+ float distance = CalculateDistanceBetweenPoints( source, target );
+ if( distance <= visibleRadius )
+ {
+ // no need to do any calculations if target is within 'visibleRadius' from source
+ //
+ return;
+ }
+
+ // check to see if we should skip this update and return cached information instead
+ //
+ m_frameCount = (m_frameCount + 1) % NUM_AMORTIZED_UPDATE_FRAMES;
+ if( m_frameCount != 0 )
+ {
+ target = m_lastOnRoadLocation;
+
+ return;
+ }
+
+ // get reference to road manager
+ //
+ RoadManager* roadManager = RoadManager::GetInstance();
+ rAssert( roadManager != NULL );
+
+ //////////////
+ // find path between source and target
+ //
+ bool isPathElementFound = false;
+ float searchRadius = 200.0f;
+ float dummy;
+
+ // Find source's closest path element
+ RoadSegment* sourceSeg = NULL;
+ float sourceSegT = 0.0f;
+ RoadManager::PathElement sourceElem;
+ float sourceRoadT = 0.0f;
+
+ isPathElementFound = VehicleAI::FindClosestPathElement( source,
+ sourceElem, sourceSeg, sourceSegT, sourceRoadT, false ); // don't want shortcuts on hudmap
+
+ if( !isPathElementFound )
+ {
+ GetIntersectManager()->FindClosestRoad( source, searchRadius, sourceSeg, dummy ); // ignore shortcuts
+ rAssertMsg( sourceSeg, "Should always find a nearby road seg! Increase search radius!" );
+ if( !sourceSeg )
+ {
+ return;
+ }
+
+ sourceElem.type = RoadManager::ET_NORMALROAD;
+ sourceElem.elem = sourceSeg->GetRoad();
+ sourceSegT = roadManager->DetermineSegmentT( source, sourceSeg );
+ sourceRoadT = roadManager->DetermineRoadT( sourceSeg, sourceSegT );
+ }
+ rAssert( sourceElem.elem );
+
+
+ // Find target's closest path element
+ RoadSegment* targetSeg = NULL;
+ float targetSegT = 0.0f;
+ RoadManager::PathElement targetElem;
+ float targetRoadT = 0.0f;
+
+ isPathElementFound = VehicleAI::FindClosestPathElement( target,
+ targetElem, targetSeg, targetSegT, targetRoadT, false ); // don't want shortcuts on hudmap
+
+ if( !isPathElementFound )
+ {
+ RoadSegment* closestRoadSeg = NULL;
+ if( m_lastRoadSeg )
+ {
+ closestRoadSeg = m_lastRoadSeg;
+ }
+ else
+ {
+ GetIntersectManager()->FindClosestRoad( target, searchRadius, closestRoadSeg, dummy );
+ rAssertMsg( closestRoadSeg, "Should always find a nearby road seg! Increase search radius!" );
+ if( !closestRoadSeg )
+ {
+ return;
+ }
+ m_lastRoadSeg = closestRoadSeg;
+ }
+ targetElem.type = RoadManager::ET_NORMALROAD;
+ targetElem.elem = closestRoadSeg->GetRoad();
+ targetSeg = closestRoadSeg;
+ targetSegT = roadManager->DetermineSegmentT( target, targetSeg );
+ targetRoadT = roadManager->DetermineRoadT( targetSeg, targetSegT );
+ }
+ else
+ {
+ // need to make this check cuz FindClosestPathElement could return an intersection
+ if( targetSeg )
+ {
+ m_lastRoadSeg = targetSeg;
+ }
+ }
+ rAssert( targetElem.elem );
+
+
+ HeapMgr()->PushHeap( GMA_TEMP );
+
+ SwapArray<RoadManager::PathElement> pathElements;
+ pathElements.Allocate( roadManager->GetMaxPathElements() );
+
+ RoadManager::PathElement tmpSrcElem = sourceElem;
+ float roadDistance = roadManager->FindPathElementsBetween( false,
+ tmpSrcElem, sourceRoadT, source,
+ targetElem, targetRoadT, target,
+ pathElements );
+
+ rAssert( pathElements.mUseSize > 0 );
+
+ // Temp stuff we use over and over again
+ RoadManager::PathElement* prevElem = &(pathElements[0]);
+ bool isRoadBackwards = false;
+ int numIntersects = 0;
+ rmt::Vector intPts[2];
+
+ rmt::Sphere visibleSphere( source, visibleRadius ); // this is the hud map circle
+
+ // find closest path element that intersects visible sphere (or circle, really)
+ //
+ bool isClosestPathElementFound = false;
+
+ if( pathElements.mUseSize == 1 )
+ {
+ // if only one element returned
+ if( pathElements[0].type == RoadManager::ET_INTERSECTION )
+ {
+ // if the only elem is an intersection, just point to target
+ numIntersects = IntersectLineSphere( source, target, visibleSphere, intPts );
+ rAssert( numIntersects == 1 );
+ target = intPts[0];
+ }
+ else // the only element is a road
+ {
+ Road* theRoad = (Road*) targetElem.elem;
+
+ // we know here that one element returned is either cuz:
+ // A) source and target lie on same road
+ // or
+ // B) source and target lie on opposite roads that
+ // describe the same physical road (target road is returned)
+
+ // case B
+ if( sourceElem != targetElem )
+ {
+ // iterate through target road's segments to find the closest seg
+ // to source, the t value of this segment will tell us whether to
+ // traverse the segments backwards or forwards...
+ //
+ rmt::Vector closestPos;
+ float closestDist;
+ int closestSegIndex;
+
+ RoadManager::FindClosestPointOnRoad( theRoad, source, closestPos, closestDist, closestSegIndex );
+
+ rAssert( 0 <= closestSegIndex && closestSegIndex < (int) theRoad->GetNumRoadSegments() );
+ RoadSegment* closestSeg = theRoad->GetRoadSegment( (unsigned int) closestSegIndex );
+ rAssert( closestSeg );
+
+ sourceElem.elem = theRoad;
+ sourceSeg = closestSeg;
+ sourceSegT = RoadManager::DetermineSegmentT( closestPos, closestSeg );
+ sourceRoadT = RoadManager::DetermineRoadT( sourceSeg, sourceSegT );
+ }
+
+ rAssert( sourceElem == targetElem );
+
+ // this should now work for either A or B
+ if( sourceRoadT > targetRoadT )
+ {
+ isRoadBackwards = true;
+ }
+
+ unsigned int startIndex = sourceSeg->GetSegmentIndex();
+ unsigned int endIndex = targetSeg->GetSegmentIndex();
+
+ bool foundIntersect = false;
+ if( !isRoadBackwards )
+ {
+ for( unsigned int i=startIndex; i<=endIndex; i++ )
+ {
+ RoadSegment* seg = theRoad->GetRoadSegment( i );
+
+ rmt::Vector vec0, vec1, vec2, vec3, start, end;
+ seg->GetCorner( 0, vec0 );
+ seg->GetCorner( 1, vec1 );
+ seg->GetCorner( 2, vec2 );
+ seg->GetCorner( 3, vec3 );
+
+ start = (vec0 + vec3) * 0.5f;
+ start.y = 0.0f;
+ end = (vec1 + vec2) * 0.5f;
+ end.y = 0.0f;
+
+ int numIntersects = IntersectLineSphere( start, end, visibleSphere, intPts );
+ rAssert( 0 <= numIntersects && numIntersects <= 1 );
+
+ if( numIntersects == 1 )
+ {
+ target = intPts[0];
+ isClosestPathElementFound = true;
+
+ break;
+ }
+ }
+ }
+ else
+ {
+ for( int i=(int)startIndex; i>=(int)endIndex; i-- )
+ {
+ RoadSegment* seg = theRoad->GetRoadSegment( (unsigned int)i );
+
+ rmt::Vector vec0, vec1, vec2, vec3, start, end;
+ seg->GetCorner( 0, vec0 );
+ seg->GetCorner( 1, vec1 );
+ seg->GetCorner( 2, vec2 );
+ seg->GetCorner( 3, vec3 );
+
+ start = (vec0 + vec3) * 0.5f;
+ start.y = 0.0f;
+ end = (vec1 + vec2) * 0.5f;
+ end.y = 0.0f;
+
+ int numIntersects = IntersectLineSphere( start, end, visibleSphere, intPts );
+ rAssert( 0 <= numIntersects && numIntersects <= 1 );
+
+ if( numIntersects == 1 )
+ {
+ target = intPts[0];
+ isClosestPathElementFound = true;
+
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // At this point, we're dealing with multiple path elements
+ //
+ Intersection* previousIntersection = NULL;
+ for( int i = 0; i < pathElements.mUseSize; i++ )
+ {
+ if( isClosestPathElementFound )
+ {
+ // we're done! we found the closest path element
+ //
+ break;
+ }
+
+ RoadManager::PathElement* currentPathElement = &( pathElements[ i ] );
+ rAssert( currentPathElement != NULL );
+
+ switch( currentPathElement->type )
+ {
+ case RoadManager::ET_NORMALROAD:
+ {
+ Road* road = static_cast<Road*>( currentPathElement->elem );
+ rAssert( road != NULL );
+
+ int numRoadSegments = static_cast<int>( road->GetNumRoadSegments() );
+
+ // determine which direction to iterate over all road segments
+ //
+ bool isRoadBackwards = false;
+
+ if( i == 0 ) // special case if first path element is a road
+ {
+ for( int j = 1; j < pathElements.mUseSize; j++ )
+ {
+ RoadManager::PathElement* pathElement = &( pathElements[ j ] );
+ rAssert( pathElement != NULL );
+
+ if( pathElement->type == RoadManager::ET_INTERSECTION )
+ {
+ isRoadBackwards = ( road->GetSourceIntersection() == static_cast<Intersection*>( pathElement->elem ) );
+
+ break;
+ }
+ }
+ }
+ else
+ {
+ isRoadBackwards = ( road->GetSourceIntersection() != previousIntersection );
+ }
+
+ int currentRoadSegmentIndex = isRoadBackwards ? numRoadSegments - 1 : 0;
+
+ while( currentRoadSegmentIndex >= 0 && currentRoadSegmentIndex < numRoadSegments )
+ {
+ RoadSegment* currentRoadSegment = road->GetRoadSegment( currentRoadSegmentIndex );
+ rmt::Vector vec0, vec1, vec2, vec3, start, end;
+
+ currentRoadSegment->GetCorner( 0, vec0 );
+ currentRoadSegment->GetCorner( 1, vec1 );
+ currentRoadSegment->GetCorner( 2, vec2 );
+ currentRoadSegment->GetCorner( 3, vec3 );
+
+ start = (vec0 + vec3) * 0.5f;
+ start.y = 0.0f;
+ end = (vec1 + vec2) * 0.5f;
+ end.y = 0.0f;
+
+ rmt::Vector intersectPoints[ 2 ];
+ int numIntersectPoints = IntersectLineSphere( start, end, visibleSphere, intersectPoints );
+ if( numIntersectPoints > 0 )
+ {
+ rmt::Vector closestIntersectPoint = intersectPoints[ 0 ];
+
+ // TC [TODO]: if more than one intersection points, need to determine which
+ // one is closest to source
+ //
+ if( numIntersectPoints > 1 )
+ {
+ rTuneWarningMsg( false, "Multiple intersection points not yet handled properly, but this should not happen here!" );
+ }
+
+ // check to make sure that this point is, in fact, closer to the target than the source
+ //
+ if( i == 0 ) // only need to check this for the first path element
+ {
+ float roadSegT = roadManager->DetermineSegmentT( closestIntersectPoint, const_cast<RoadSegment*>( currentRoadSegment ) );
+ float intersectRoadT = roadManager->DetermineRoadT( const_cast<RoadSegment*>( currentRoadSegment ), roadSegT );
+
+ if( ( isRoadBackwards && intersectRoadT < sourceRoadT) ||
+ (!isRoadBackwards && intersectRoadT > sourceRoadT) )
+ {
+ target = closestIntersectPoint;
+ isClosestPathElementFound = true;
+
+ break; // stop iterating over road segments
+ }
+ else
+ {
+ int dummy = 0;
+ }
+ }
+ else
+ {
+ target = closestIntersectPoint;
+ isClosestPathElementFound = true;
+
+ break; // stop iterating over road segments
+ }
+ }
+
+ currentRoadSegmentIndex += isRoadBackwards ? -1 : +1;
+ }
+
+ break;
+ }
+ case RoadManager::ET_INTERSECTION:
+ {
+ Intersection* intersection = static_cast<Intersection*>( currentPathElement->elem );
+ rAssert( intersection != NULL );
+
+ // keep track of previous intersection
+ //
+ previousIntersection = intersection;
+
+ rmt::Vector intersectionLocation;
+ intersection->GetLocation( intersectionLocation );
+ intersectionLocation.y = 0.0f;
+ float distance = CalculateDistanceBetweenPoints( source, intersectionLocation );
+
+ if( rmt::Abs( distance - visibleRadius ) <= intersection->GetRadius() )
+ {
+ // project target onto radar edge, on a point that is closest to the
+ // intersection center point
+ //
+ rmt::Vector sourceToIntersection;
+ sourceToIntersection.Sub( intersectionLocation, source );
+ sourceToIntersection.Scale( visibleRadius / distance );
+
+ target.Add( source, sourceToIntersection );
+
+ isClosestPathElementFound = true;
+ }
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Invalid path element type!" );
+
+ break;
+ }
+ }
+ }
+ }
+
+ HeapMgr()->PopHeap( GMA_TEMP );
+
+ target.y = 0.0f;
+ m_lastOnRoadLocation = target;
+
+#ifndef RAD_RELEASE
+ if( !isClosestPathElementFound )
+ {
+ // TC: [INVESTIGATE] if closest path element is not found, there must be some discontinuity
+ // in the closest path found
+ //
+ rTuneWarningMsg( false, "Closest path element not found! Please go tell Tony." );
+ }
+#endif
+}
+
diff --git a/game/code/presentation/gui/utility/hudmap.h b/game/code/presentation/gui/utility/hudmap.h
new file mode 100644
index 0000000..cb8b9ec
--- /dev/null
+++ b/game/code/presentation/gui/utility/hudmap.h
@@ -0,0 +1,240 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CHudMap
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/01 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef HUDMAP_H
+#define HUDMAP_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <p3d/p3dtypes.hpp>
+#include <radmath/radmath.hpp>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+#ifndef NULL
+ #define NULL 0
+#endif
+
+const unsigned int MAX_NUM_REGISTERED_ICONS = 64;
+const unsigned int MAX_NUM_ICONS_PER_TYPE = 32;
+
+struct HudMapCam;
+class ISuperCamTarget;
+class tPointCamera;
+class RoadSegment;
+
+namespace Scrooby
+{
+ class Page;
+ class Group;
+ class Pure3dObject;
+ class Sprite;
+}
+
+// pure virtual interface for dynamic hud map icons
+//
+struct IHudMapIconLocator
+{
+ virtual void GetPosition( rmt::Vector* currentLoc ) = 0;
+ virtual void GetHeading( rmt::Vector* heading ) = 0;
+};
+
+struct HudMapIcon
+{
+ enum eIconType
+ {
+ UNKNOWN_ICON_TYPE = -1,
+
+ ICON_PLAYER,
+ ICON_PLAYER_CAR,
+
+ ICON_AI_TYPES_BEGIN = ICON_PLAYER_CAR, // not an icon type
+ ICON_AI_HIT_N_RUN,
+ ICON_AI_CHASE,
+ ICON_AI_RACE,
+ ICON_AI_EVADE,
+ ICON_AI_TARGET,
+ ICON_AI_TYPES_END, // not an icon type
+
+ ICON_FLAG_CHECKERED = ICON_AI_TYPES_END,
+ ICON_FLAG_WAYPOINT,
+ ICON_COLLECTIBLE,
+ ICON_MISSION,
+ ICON_BONUS_MISSION,
+ ICON_PHONE_BOOTH,
+ ICON_PURCHASE_CENTRE,
+ ICON_STREET_RACE,
+ ICON_WAGER_RACE,
+
+ NUM_ICON_TYPES
+ };
+
+ Scrooby::Sprite* m_iconImage;
+ eIconType m_type;
+ rmt::Vector m_location;
+ IHudMapIconLocator* m_dynamicLocator;
+ unsigned int m_visibilityMask;
+
+ HudMapIcon()
+ : m_iconImage( NULL ),
+ m_type( UNKNOWN_ICON_TYPE ),
+ m_location( 0, 0, 0 ),
+ m_dynamicLocator( NULL ),
+ m_visibilityMask( 0 )
+ {
+ }
+
+ bool IsAICarIcon() const
+ {
+ return( static_cast<int>( m_type ) > ICON_AI_TYPES_BEGIN &&
+ static_cast<int>( m_type ) < ICON_AI_TYPES_END );
+ }
+
+ void ApplyAICarIconColour();
+
+};
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CHudMap
+{
+public:
+ CHudMap( Scrooby::Page* pPage, int playerID, const char* p3dFile = NULL );
+ virtual ~CHudMap();
+
+ // Camera Target must be set before doing anything else!
+ //
+ void SetCameraTarget( ISuperCamTarget* target );
+
+ // enable/disable fixed camera height (if enabling, the fixed camera
+ // height will be calculated from the visible radius)
+ //
+ void EnableFixedCameraHeight( bool enable,
+ float visibleRadius = 50.0f );
+
+ // Update
+ //
+ void Update( unsigned int elapsedTime );
+
+ // for AI Car icons only
+ //
+ void UpdateAICarDistance( float currentDistance, float maxDistance );
+
+ // Map Icons
+ //
+ void AddIconToInventory( HudMapIcon::eIconType type, Scrooby::Sprite* image );
+ Scrooby::Sprite* RemoveIconFromInventory( HudMapIcon::eIconType type );
+
+ int RegisterIcon( HudMapIcon::eIconType type, rmt::Vector location,
+ IHudMapIconLocator* hudMapIconLocator = NULL,
+ bool newFocalPoint = false );
+
+ void UnregisterIcon( int iconID );
+
+ int ChangeIconType( int iconID, HudMapIcon::eIconType type );
+ void SetFocalPointIcon( int iconID );
+ HudMapIcon* FindIcon( HudMapIcon::eIconType type ) const;
+
+ // Reset position and size to original settings
+ //
+ void Translate( int x, int y );
+ void Reset();
+
+ void SetVisible( bool isVisible );
+
+ // Accessors
+ //
+ Scrooby::Pure3dObject* GetMap() const { return m_p3dMap; }
+ Scrooby::Pure3dObject* GetHole() const { return m_p3dHole; }
+ HudMapCam* GetHudMapCam() const { return m_hudMapCam; }
+
+ void RestoreAllRegisteredIcons();
+ static void ClearAllRegisteredIcons();
+
+private:
+
+ //---------------------------------------------------------------------
+ // Private Functions
+ //---------------------------------------------------------------------
+
+ // No copying or asignment. Declare but don't define.
+ //
+ CHudMap( const CHudMap& );
+ CHudMap& operator= ( const CHudMap& );
+
+ static float CalculateDistanceBetweenPoints( rmt::Vector& a, rmt::Vector& b );
+
+ void UpdateIconHeading( Scrooby::Sprite* iconImage, rmt::Vector* iconHeading );
+
+ float CalculateCameraHeight( rmt::Vector& player, rmt::Vector& mission ) const;
+ float CalculateCameraHeight( float visibleRadius ) const;
+ float CalculatRadarConeAngle( rmt::Vector& iconLoc ) const;
+
+ void DetermineOnRoadLocation( rmt::Vector& source, rmt::Vector& target, float visibleRadius );
+
+ //---------------------------------------------------------------------
+ // Private Data
+ //---------------------------------------------------------------------
+
+ int m_playerID;
+
+ Scrooby::Pure3dObject* m_p3dMap;
+ Scrooby::Pure3dObject* m_p3dHole;
+ int m_originalPosX;
+ int m_originalPosY;
+ int m_originalWidth;
+ int m_originalHeight;
+
+ bool m_isVisible : 1;
+ Scrooby::Group* m_radar;
+ Scrooby::Group* m_radarCone;
+ Scrooby::Group* m_iconsGroup;
+
+ HudMapCam* m_hudMapCam;
+ float m_currentCameraHeight;
+ float m_fixedCameraHeight;
+
+ Scrooby::Sprite* m_icons[ HudMapIcon::NUM_ICON_TYPES ][ MAX_NUM_ICONS_PER_TYPE ];
+
+ // for AI Car icons only
+ //
+ float m_currentAICarDistance;
+ float m_maxAICarDistance;
+
+ unsigned int m_elapsedTime;
+
+ RoadSegment* m_lastRoadSeg;
+ rmt::Vector m_lastOnRoadLocation;
+ int m_frameCount;
+
+ // gameplay-persistent data
+ //
+ static HudMapIcon s_registeredIcons[ MAX_NUM_REGISTERED_ICONS ];
+ static int s_numRegisteredIcons;
+ static int s_fpIconID;
+
+};
+
+inline void CHudMap::UpdateAICarDistance( float currentDistance, float maxDistance )
+{
+ m_currentAICarDistance = currentDistance;
+ m_maxAICarDistance = maxDistance;
+}
+
+#endif // HUDMAP_H
diff --git a/game/code/presentation/gui/utility/hudmapcam.cpp b/game/code/presentation/gui/utility/hudmapcam.cpp
new file mode 100644
index 0000000..b83396b
--- /dev/null
+++ b/game/code/presentation/gui/utility/hudmapcam.cpp
@@ -0,0 +1,113 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudMapCam
+//
+// Description: Implementation of the CHudMap class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/10 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/utility/hudmapcam.h>
+
+#include <camera/supercammanager.h>
+#include <camera/supercamcentral.h>
+
+#include <raddebug.hpp>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+HudMapCam::HudMapCam( int playerID )
+: KullCam(),
+ m_camera( NULL ),
+ m_originalHeading( -1, 0, 0 )
+{
+ SetPlayerID( playerID );
+ mIgnoreDebugController = true;
+
+ m_camera = new tPointCamera;
+ m_camera->AddRef();
+ SetCamera( m_camera );
+
+ // override default KullCam parameters
+ mElevation = 0.0f;
+ mMagnitude = 150.0f;
+
+ // fix hud map cam FOV
+ //
+ this->SetFOV( rmt::PI_BY2 );
+}
+
+HudMapCam::~HudMapCam()
+{
+ if( m_camera != NULL )
+ {
+ m_camera->Release();
+ m_camera = NULL;
+ }
+}
+
+void
+HudMapCam::Update( unsigned int milliseconds )
+{
+ // adjust kull cam rotation to match main camera heading
+ //
+ rmt::Vector camHeading;
+ GetSuperCamManager()->GetSCC( this->GetPlayerID() )->GetActiveSuperCam()->GetHeading( &camHeading );
+ camHeading.y = 0;
+
+ if( camHeading.MagnitudeSqr() > 0 )
+ {
+ float ratio = camHeading.DotProduct( m_originalHeading ) / camHeading.Magnitude();
+ if( ratio > 1.0f )
+ {
+ mRotation = 0.0f;
+ }
+ else if( ratio < -1.0f )
+ {
+ mRotation = rmt::PI;
+ }
+ else
+ {
+ mRotation = rmt::ACos( ratio );
+ }
+
+ rAssert( !rmt::IsNan( mRotation ) );
+
+ rmt::Vector normal = camHeading;
+ normal.CrossProduct( m_originalHeading );
+ if( normal.y < 0 )
+ {
+ mRotation = -mRotation;
+ }
+ }
+
+ KullCam::Update( milliseconds );
+
+ // fix hud map cam at 'mMagnitude' above sea level
+ //
+ rmt::Vector camPosition = m_camera->GetPosition();
+ camPosition.y = mMagnitude;
+ m_camera->SetPosition( camPosition );
+}
+
+void
+HudMapCam::SetHeight( float height )
+{
+ rAssert( height > 0.0f );
+ mMagnitude = height;
+}
+
diff --git a/game/code/presentation/gui/utility/hudmapcam.h b/game/code/presentation/gui/utility/hudmapcam.h
new file mode 100644
index 0000000..21db768
--- /dev/null
+++ b/game/code/presentation/gui/utility/hudmapcam.h
@@ -0,0 +1,40 @@
+//===========================================================================
+// Copyright (C) 2003 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: HudMapCam
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2003/03/10 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef HUDMAPCAM_H
+#define HUDMAPCAM_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <camera/kullcam.h>
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+struct HudMapCam : public KullCam
+{
+ HudMapCam( int playerID );
+ virtual ~HudMapCam();
+
+ void Update( unsigned int milliseconds );
+ void SetHeight( float height );
+
+ tPointCamera* m_camera;
+ rmt::Vector m_originalHeading;
+
+};
+
+#endif // HUDMAPCAM_H
diff --git a/game/code/presentation/gui/utility/numerictext.cpp b/game/code/presentation/gui/utility/numerictext.cpp
new file mode 100644
index 0000000..6dafdcc
--- /dev/null
+++ b/game/code/presentation/gui/utility/numerictext.cpp
@@ -0,0 +1,27 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: NumericText
+//
+// Description: Implementation of the NumericText class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/19 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/utility/numerictext.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
diff --git a/game/code/presentation/gui/utility/numerictext.h b/game/code/presentation/gui/utility/numerictext.h
new file mode 100644
index 0000000..04bf24c
--- /dev/null
+++ b/game/code/presentation/gui/utility/numerictext.h
@@ -0,0 +1,197 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: NumericText
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/07 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef NUMERICTEXT_H
+#define NUMERICTEXT_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+
+#include <raddebug.hpp> // Foundation
+#include <group.h>
+#include <text.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+namespace Scrooby
+{
+ class Group;
+ class Page;
+ class Text;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+template <class Digit>
+struct NumericText
+{
+ enum eDigits
+ {
+ DIGIT_ONES,
+ DIGIT_TENS,
+ DIGIT_HUNDREDS,
+
+ MAX_NUM_DIGITS
+ };
+
+ enum eAlignment
+ {
+ ALIGN_RIGHT,
+ ALIGN_LEFT,
+
+ NUM_ALIGNMENTS
+ };
+
+ Digit* m_digits[ MAX_NUM_DIGITS ];
+ Scrooby::Group* m_group;
+ int m_numDigits;
+ bool m_showLeadingZeros;
+ eAlignment m_alignment;
+
+ NumericText()
+ : m_group( NULL ),
+ m_numDigits( 0 ),
+ m_showLeadingZeros( false ),
+ m_alignment( ALIGN_RIGHT )
+ {
+ memset( m_digits, 0, sizeof( m_digits ) );
+ }
+
+ void SetScroobyText( Scrooby::Group* pGroup, const char* name )
+ {
+ m_group = pGroup;
+ m_numDigits = 0;
+
+ char objectName[ 32 ];
+ for( int i = 0; i < MAX_NUM_DIGITS; i++ )
+ {
+ sprintf( objectName, "%s_%d", name, i );
+
+ Digit* pDrawable = dynamic_cast<Digit*>( pGroup->GetText( objectName ) );
+ if( pDrawable == NULL )
+ {
+ pDrawable = dynamic_cast<Digit*>( pGroup->GetSprite( objectName ) );
+ }
+
+ if( pDrawable != NULL )
+ {
+ m_digits[ i ] = pDrawable;
+
+ // increment number of digits
+ //
+ m_numDigits++;
+ }
+ else
+ {
+ // break, assuming no more digits to follow
+ //
+ break;
+ }
+ }
+
+ // set value to zero by default
+ //
+ this->SetValue( 0 );
+ }
+
+ void SetValue( unsigned int value, unsigned int offset = 0 )
+ {
+ for( int i = 0; i < m_numDigits; i++ )
+ {
+ // set current digit value
+ rAssert( m_digits[ i ] );
+
+ m_digits[ i ]->SetIndex( value % 10 + offset );
+
+ // show leading zeros, if enabled
+ if( m_showLeadingZeros )
+ {
+ m_digits[ i ]->SetVisible( true );
+ }
+ else
+ {
+ m_digits[ i ]->SetVisible( value > 0 || i == 0 );
+ }
+
+ // shift value one digit to the right
+ value = value / 10;
+ }
+
+ if( m_alignment == ALIGN_LEFT )
+ {
+ // align numeric text to the left (TC: Can this be improved??)
+ for( int j = m_numDigits - 1; j >= 0; j-- )
+ {
+ if( m_digits[ j ]->IsVisible() )
+ {
+ // found leading digit = j, now shift digits to the left
+ //
+ for( int k = m_numDigits - 1; k >= 0; k-- )
+ {
+ if( j >= 0 )
+ {
+ m_digits[ k ]->SetIndex( m_digits[ j ]->GetIndex() );
+ m_digits[ k ]->SetVisible( true );
+
+ j--;
+ }
+ else
+ {
+ m_digits[ k ]->SetVisible( false );
+ }
+ }
+
+ // done, break out of loop
+ break;
+ }
+ }
+ }
+ }
+
+ void SetVisible( bool isVisible )
+ {
+ if( m_group != NULL )
+ {
+ m_group->SetVisible( isVisible );
+ }
+ else
+ {
+ for( int i = 0; i < MAX_NUM_DIGITS; i++ )
+ {
+ if( m_digits[ i ] != NULL )
+ {
+ m_digits[ i ]->SetVisible( isVisible );
+ }
+ }
+ }
+ }
+
+ void SetColour( tColour colour )
+ {
+ for( int i = 0; i < MAX_NUM_DIGITS; i++ )
+ {
+ if( m_digits[ i ] != NULL )
+ {
+ m_digits[ i ]->SetColour( colour );
+ }
+ }
+ }
+
+};
+
+#endif // NUMERICTEXT_H
diff --git a/game/code/presentation/gui/utility/scrollingtext.cpp b/game/code/presentation/gui/utility/scrollingtext.cpp
new file mode 100644
index 0000000..3c44e8c
--- /dev/null
+++ b/game/code/presentation/gui/utility/scrollingtext.cpp
@@ -0,0 +1,280 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: ScrollingText
+//
+// Description: Implementation of the ScrollingText class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/11/21 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <p3d/font.hpp>
+#include <presentation/gui/utility/scrollingtext.h>
+
+#include <raddebug.hpp> // Foundation
+#include <app.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// ScrollingText::ScrollingText
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+ScrollingText::ScrollingText( Scrooby::Text* pText )
+: m_pText( pText ),
+ m_originalString( NULL ),
+ m_x0( 0 ),
+ m_y0( 0 ),
+ m_x1( 0 ),
+ m_y1( 0 ),
+ m_currentPos( 0.0f ),
+ m_state( STATE_IDLE ),
+ m_numPixelsPerSecond( 90 ),
+ m_isCyclic( false )
+{
+ rAssert( m_pText != NULL );
+
+ // set text mode to clip on right boundary
+ //
+ m_pText->SetTextMode( Scrooby::TEXT_CLIP );
+
+ // get scroll box boundary
+ //
+ m_pText->GetBoundingBox( m_x0, m_y0, m_x1, m_y1 );
+
+ // hide text until scrolling is started
+ //
+ m_pText->SetVisible( false );
+
+ // save reference to original string buffer
+ //
+ m_originalString = m_pText->GetStringBuffer();
+
+/*
+ // save copy of original string
+ //
+ P3D_UNICODE* originalString = static_cast<P3D_UNICODE*>( m_pText->GetStringBuffer() );
+ rAssert( originalString != NULL );
+ p3d::UnicodeStrCpy( originalString,
+ m_originalString,
+ p3d::UnicodeStrLen( originalString ) + 1 );
+*/
+}
+
+//===========================================================================
+// ScrollingText::~ScrollingText
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+ScrollingText::~ScrollingText()
+{
+}
+
+void
+ScrollingText::RestoreText()
+{
+ // restore position and size
+ //
+ m_pText->SetPosition( m_x0, m_y0 );
+ m_pText->SetBoundingBoxSize( m_x1 - m_x0, m_y1 - m_y0 );
+
+ // restore original string buffer
+ //
+ m_pText->SetStringBuffer( m_originalString );
+
+ // restore visibility
+ //
+ m_pText->SetVisible( true );
+}
+
+void
+ScrollingText::SetTextIndex( int index )
+{
+ rAssert( m_state == STATE_IDLE );
+
+ m_pText->SetIndex( index );
+
+ // update reference to original string buffer
+ //
+ m_originalString = m_pText->GetStringBuffer();
+}
+
+void
+ScrollingText::Start()
+{
+ m_state = STATE_SCROLLING;
+
+ m_currentPos = (float)m_x1;
+ this->ClipText( (int)m_currentPos, m_y0 );
+
+ // show text
+ //
+ m_pText->SetVisible( true );
+}
+
+void
+ScrollingText::Stop()
+{
+ m_state = STATE_IDLE;
+
+ m_pText->SetPosition( m_x0, m_y0 );
+
+ // restore original string buffer
+ //
+ m_pText->SetStringBuffer( m_originalString );
+
+ // hide text
+ //
+ m_pText->SetVisible( false );
+
+/*
+ P3D_UNICODE* originalString = static_cast<P3D_UNICODE*>( m_pText->GetStringBuffer() );
+ rAssert( originalString != NULL );
+ p3d::UnicodeStrCpy( m_originalString,
+ originalString,
+ p3d::UnicodeStrLen( m_originalString ) + 1 );
+*/
+}
+
+void
+ScrollingText::Update( unsigned int elapsedTime )
+{
+ if( m_state == STATE_SCROLLING )
+ {
+ // advance text towards the left
+ //
+ m_currentPos -= (m_numPixelsPerSecond * elapsedTime) / 1000.0f;
+
+ // apply text clipping for current position
+ //
+ this->ClipText( (int)m_currentPos, m_y0 );
+ }
+}
+
+//===========================================================================
+// Private Member Functions
+//===========================================================================
+
+void
+ScrollingText::ClipText( int x, int y )
+{
+ if( x >= m_x1 ) // *** origin beyond right boundary
+ {
+ m_pText->SetPosition( x, y );
+ m_pText->SetBoundingBoxSize( 0, m_y1 - y );
+ }
+ else if( x >= m_x0 ) // *** origin within both boundaries
+ {
+ m_pText->SetPosition( x, y );
+ m_pText->SetBoundingBoxSize( m_x1 - x, m_y1 - y );
+
+#ifdef RAD_WIN32
+ // TC: for PC sku, the source fonts are actually twice as big (for higher resolution display),
+ // so we need to stretch the bounding box accordingly for proper text clipping
+ //
+ m_pText->StretchBoundingBox( 2.0f, 1.0f );
+#endif
+ }
+ else // *** origin beyond left boundary
+ {
+ m_pText->SetBoundingBoxSize( m_x1 - m_x0, m_y1 - y );
+
+#ifdef RAD_WIN32
+ // TC: for PC sku, the source fonts are actually twice as big (for higher resolution display),
+ // so we need to stretch the bounding box accordingly for proper text clipping
+ //
+ m_pText->StretchBoundingBox( 2.0f, 1.0f );
+#endif
+
+ tFont* textFont = m_pText->GetFont();
+ if( textFont != NULL )
+ {
+ bool doneClipping = false;
+
+ for( UnicodeChar* currentString = m_pText->GetStringBuffer();
+ !doneClipping;
+ currentString++ )
+ {
+ UnicodeChar tempChar = currentString[ 0 ];
+ currentString[ 0 ] = '\0';
+
+ float clippedTextWidth = textFont->GetTextWidth( static_cast<P3D_UNICODE*>( m_originalString ) ) *
+ Scrooby::App::GetInstance()->GetScreenWidth() /
+ Scrooby::App::GetInstance()->GetScreenHeight();
+
+#ifdef RAD_WIN32
+ // TC: for PC sku, the source fonts are actually twice as big (for higher resolution display),
+ // so the width of the current text string is only half as wide
+ //
+ clippedTextWidth /= 2.0f;
+#endif
+
+ currentString[ 0 ] = tempChar;
+
+ int amountClipped = static_cast<int>( clippedTextWidth ) - (m_x0 - x);
+ if( amountClipped >= 0 )
+ {
+ m_pText->SetPosition( m_x0 + amountClipped, y );
+ m_pText->SetStringBuffer( currentString );
+ doneClipping = true;
+ }
+
+ if( currentString[ 0 ] == '\0' )
+ {
+ // done scrolling
+ //
+ this->Stop();
+
+ if( m_isCyclic )
+ {
+ // start over again
+ //
+ this->Start();
+ }
+
+ // make sure we break out of the loop; otherwise, there's
+ // a small chance that 'amountClipped' may be slightly less
+ // than 0 and so we might not be done clipping
+ //
+ break;
+ }
+ }
+ }
+ else
+ {
+ rWarningMsg( false, "No font for clipping text!" );
+
+ this->Stop();
+ }
+ }
+}
+
diff --git a/game/code/presentation/gui/utility/scrollingtext.h b/game/code/presentation/gui/utility/scrollingtext.h
new file mode 100644
index 0000000..c1f75c3
--- /dev/null
+++ b/game/code/presentation/gui/utility/scrollingtext.h
@@ -0,0 +1,110 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: ScrollingText
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/11/21 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef SCROLLINGTEXT_H
+#define SCROLLINGTEXT_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <strings/unicodestring.h>
+
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class Text;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class ScrollingText
+{
+public:
+ ScrollingText( Scrooby::Text* pText );
+ virtual ~ScrollingText();
+
+ void RestoreText();
+ void SetTextIndex( int index );
+
+ void Start();
+ void Stop();
+ void Pause();
+ void Resume();
+
+ void Update( unsigned int elapsedTime );
+
+ enum eScrollState
+ {
+ STATE_IDLE,
+ STATE_SCROLLING,
+ STATE_PAUSED,
+
+ NUM_SCROLL_STATES
+ };
+
+ eScrollState GetCurrentState() const { return m_state; }
+
+ void SetSpeed( int numPixelsPerSecond ) { m_numPixelsPerSecond = numPixelsPerSecond; }
+
+ void SetCyclic( bool isCyclic ) { m_isCyclic = isCyclic; }
+ bool IsCyclic() const { return m_isCyclic; }
+
+protected:
+ //---------------------------------------------------------------------
+ // Protected Functions
+ //---------------------------------------------------------------------
+
+ //---------------------------------------------------------------------
+ // Protected Data
+ //---------------------------------------------------------------------
+
+private:
+ //---------------------------------------------------------------------
+ // Private Functions
+ //---------------------------------------------------------------------
+
+ // No copying or asignment. Declare but don't define.
+ //
+ ScrollingText( const ScrollingText& );
+ ScrollingText& operator= ( const ScrollingText& );
+
+ void ClipText( int x, int y );
+
+ //---------------------------------------------------------------------
+ // Private Data
+ //---------------------------------------------------------------------
+
+ Scrooby::Text* m_pText;
+ UnicodeChar* m_originalString;
+
+ int m_x0;
+ int m_y0;
+ int m_x1;
+ int m_y1;
+ float m_currentPos;
+
+ eScrollState m_state;
+
+ int m_numPixelsPerSecond;
+ bool m_isCyclic;
+
+};
+
+#endif // SCROLLINGTEXT_H
diff --git a/game/code/presentation/gui/utility/slider.cpp b/game/code/presentation/gui/utility/slider.cpp
new file mode 100644
index 0000000..ac86521
--- /dev/null
+++ b/game/code/presentation/gui/utility/slider.cpp
@@ -0,0 +1,246 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: Slider
+//
+// Description: Implementation of the Slider class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/19 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/utility/slider.h>
+
+#include <raddebug.hpp> // Foundation
+#include <polygon.h>
+#include <sprite.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+Slider::Slider( eSliderType type )
+: m_type( type ),
+ m_pPolygon( NULL ),
+ m_value( 1 ),
+ m_pImage( NULL ),
+ x0( 19820602 ), // some arbitrarily big integer
+ y0( 19780627 ), // some arbitrarily big integer
+ x1( 0 ),
+ y1( 0 )
+{
+}
+
+void
+Slider::SetScroobyPolygon( Scrooby::Polygon* pPolygon, Scrooby::Sprite* pImage )
+{
+ rAssert( pPolygon );
+ m_pPolygon = pPolygon;
+ m_pImage = pImage;
+
+ for( int i = 0; i < m_pPolygon->GetNumOfVertexes(); i++ )
+ {
+ int x = 0;
+ int y = 0;
+ m_pPolygon->GetVertexLocation( i, x, y );
+
+ if( x < x0 ) x0 = x;
+ if( y < y0 ) y0 = y;
+ if( x > x1 ) x1 = x;
+ if( y > y1 ) y1 = y;
+ }
+
+ m_pPolygon->SetVertexLocation( VERTEX_BOTTOM_LEFT, x0, y0 );
+ m_pPolygon->SetVertexLocation( VERTEX_TOP_LEFT, x0, y1 );
+ m_pPolygon->SetVertexLocation( VERTEX_TOP_RIGHT, x1, y1 );
+ m_pPolygon->SetVertexLocation( VERTEX_BOTTOM_RIGHT, x1, y0 );
+}
+
+void
+Slider::SetValue( float value )
+{
+ rAssert( value >= 0.0f && value <= 1.0f );
+ m_value = value;
+
+ rAssert( m_pPolygon );
+
+ int x = x0;
+ int y = y0;
+
+ switch( m_type )
+ {
+ case HORIZONTAL_SLIDER_LEFT:
+ {
+ x = x0 + static_cast<int>( (x1 - x0) * value );
+ m_pPolygon->SetVertexLocation( VERTEX_BOTTOM_RIGHT, x, y0 );
+ m_pPolygon->SetVertexLocation( VERTEX_TOP_RIGHT, x, y1 );
+
+ if( m_pImage != NULL )
+ {
+ m_pImage->ResetTransformation();
+ m_pImage->Translate( x - x1, 0 );
+ }
+
+ break;
+ }
+ case HORIZONTAL_SLIDER_RIGHT:
+ {
+ x = x1 + static_cast<int>( (x0 - x1) * value );
+ m_pPolygon->SetVertexLocation( VERTEX_BOTTOM_LEFT, x, y0 );
+ m_pPolygon->SetVertexLocation( VERTEX_TOP_LEFT, x, y1 );
+
+ if( m_pImage != NULL )
+ {
+ m_pImage->ResetTransformation();
+ m_pImage->Translate( x - x0, 0 );
+ }
+
+ break;
+ }
+ case VERTICAL_SLIDER_BOTTOM:
+ {
+ y = y0 + static_cast<int>( (y1 - y0) * value );
+ m_pPolygon->SetVertexLocation( VERTEX_TOP_LEFT, x0, y );
+ m_pPolygon->SetVertexLocation( VERTEX_TOP_RIGHT, x1, y );
+
+ if( m_pImage != NULL )
+ {
+ m_pImage->ResetTransformation();
+ m_pImage->Translate( 0, y - y1 );
+ }
+
+ break;
+ }
+ case VERTICAL_SLIDER_TOP:
+ {
+ y = y1 + static_cast<int>( (y0 - y1) * value );
+ m_pPolygon->SetVertexLocation( VERTEX_BOTTOM_LEFT, x0, y );
+ m_pPolygon->SetVertexLocation( VERTEX_BOTTOM_RIGHT, x1, y );
+
+ if( m_pImage != NULL )
+ {
+ m_pImage->ResetTransformation();
+ m_pImage->Translate( 0, y - y0 );
+ }
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( 0, "ERROR: *** Invalid slider type!" );
+
+ break;
+ }
+ }
+}
+
+//===========================================================================
+// Public Member Functions (for ImageSlider)
+//===========================================================================
+
+ImageSlider::ImageSlider( eSliderType type )
+: Slider( type )
+{
+}
+
+void
+ImageSlider::SetScroobyImage( Scrooby::Sprite* pImage )
+{
+ rAssert( pImage );
+ m_pImage = pImage;
+}
+
+void
+ImageSlider::SetValue( float value, bool resetTransformation )
+{
+ rAssert( value >= 0.0f && value <= 1.0f );
+ m_value = value;
+
+ rAssert( m_pImage );
+
+ if( resetTransformation )
+ {
+ m_pImage->ResetTransformation();
+ }
+
+ int posX = 0;
+ int posY = 0;
+ m_pImage->GetOriginPosition( posX, posY );
+
+ int width = 0;
+ int height = 0;
+ m_pImage->GetBoundingBoxSize( width, height );
+
+ switch( m_type )
+ {
+ case HORIZONTAL_SLIDER_LEFT:
+ {
+ m_pImage->Translate( -posX, 0 );
+ m_pImage->Scale( value, 1.0f, 1.0f );
+ m_pImage->Translate( posX, 0 );
+
+ break;
+ }
+ case HORIZONTAL_SLIDER_RIGHT:
+ {
+ m_pImage->Translate( -posX, 0 );
+ m_pImage->Scale( value, 1.0f, 1.0f );
+ m_pImage->Translate( posX, 0 );
+
+ // right align image
+ //
+ m_pImage->Translate( (int)( width * (1.0f - value) ), 0 );
+
+ break;
+ }
+ case HORIZONTAL_SLIDER_ABOUT_CENTER:
+ {
+ m_pImage->ScaleAboutCenter( value, 1.0f, 1.0f );
+
+ break;
+ }
+ case VERTICAL_SLIDER_BOTTOM:
+ {
+ m_pImage->Translate( 0, -posY );
+ m_pImage->Scale( 1.0f, value, 1.0f );
+ m_pImage->Translate( 0, posY );
+
+ break;
+ }
+ case VERTICAL_SLIDER_TOP:
+ {
+ m_pImage->Translate( 0, -posY );
+ m_pImage->Scale( 1.0f, value, 1.0f );
+ m_pImage->Translate( 0, posY );
+
+ // top align image
+ //
+ m_pImage->Translate( 0, (int)( height * (1.0f - value) ) );
+
+ break;
+ }
+ case VERTICAL_SLIDER_ABOUT_CENTER:
+ {
+ m_pImage->ScaleAboutCenter( 1.0f, value, 1.0f );
+
+ break;
+ }
+ default:
+ {
+ rAssertMsg( 0, "ERROR: *** Invalid slider type!" );
+
+ break;
+ }
+ }
+}
+
diff --git a/game/code/presentation/gui/utility/slider.h b/game/code/presentation/gui/utility/slider.h
new file mode 100644
index 0000000..31df284
--- /dev/null
+++ b/game/code/presentation/gui/utility/slider.h
@@ -0,0 +1,94 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: Slider
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/07 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef SLIDER_H
+#define SLIDER_H
+
+#ifndef NULL
+ #define NULL 0
+#endif
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class Polygon;
+ class Sprite;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+struct Slider
+{
+ enum eSliderType
+ {
+ HORIZONTAL_SLIDER_LEFT,
+ HORIZONTAL_SLIDER_ABOUT_CENTER,
+ HORIZONTAL_SLIDER_RIGHT,
+
+ VERTICAL_SLIDER_BOTTOM,
+ VERTICAL_SLIDER_ABOUT_CENTER,
+ VERTICAL_SLIDER_TOP,
+
+ NUM_SLIDER_TYPES
+ };
+
+ eSliderType m_type;
+
+ enum eVertex
+ {
+ VERTEX_BOTTOM_LEFT,
+ VERTEX_TOP_LEFT,
+ VERTEX_TOP_RIGHT,
+ VERTEX_BOTTOM_RIGHT,
+
+ NUM_VERTICES
+ };
+
+ Scrooby::Polygon* m_pPolygon;
+ float m_value;
+
+ // optional image to tag onto the end of the slider
+ Scrooby::Sprite* m_pImage;
+
+ // bottom-left and top-right vertex co-ordinates
+ int x0;
+ int y0;
+ int x1;
+ int y1;
+
+ Slider( eSliderType type = HORIZONTAL_SLIDER_LEFT );
+ void SetScroobyPolygon( Scrooby::Polygon* pPolygon, Scrooby::Sprite* pImage = NULL );
+ virtual void SetValue( float value );
+
+};
+
+struct ImageSlider : public Slider
+{
+ ImageSlider( eSliderType type = HORIZONTAL_SLIDER_LEFT );
+
+ void SetScroobyImage( Scrooby::Sprite* pImage );
+ virtual void SetValue( float value, bool resetTransformation = true );
+
+};
+
+#endif // SLIDER_H
diff --git a/game/code/presentation/gui/utility/specialfx.cpp b/game/code/presentation/gui/utility/specialfx.cpp
new file mode 100644
index 0000000..b306653
--- /dev/null
+++ b/game/code/presentation/gui/utility/specialfx.cpp
@@ -0,0 +1,401 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: SpecialFX
+//
+// Description: Implementation of the SpecialFX class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/30 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/utility/specialfx.h>
+#include <boundeddrawable.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+bool GuiSFX::Flash
+(
+ Scrooby::BoundedDrawable* drawable,
+ float elapsedTime,
+ float durationTime,
+ int zoomRate,
+ float maxScale,
+ float thresholdScale
+)
+{
+ if( elapsedTime > durationTime )
+ {
+ return true;
+ }
+
+ rAssert( drawable != NULL );
+ rAssert( elapsedTime >= 0 && durationTime > 0 );
+
+ float scale = (float)elapsedTime / (float)durationTime;
+ for( int i = 0; i < zoomRate; i++ )
+ {
+ scale = rmt::Sqrt( scale );
+ }
+
+ scale *= maxScale;
+
+ drawable->ResetTransformation();
+ drawable->ScaleAboutCenter( scale, scale, 1.0f );
+
+ if( scale > thresholdScale )
+ {
+ drawable->SetAlpha( 1.0f - ((scale - thresholdScale) /
+ (maxScale - thresholdScale)) );
+ }
+ else
+ {
+ drawable->SetAlpha( 1.0f );
+ }
+
+ return false;
+}
+
+bool GuiSFX::Blink
+(
+ Scrooby::Drawable* drawable,
+ float elapsedTime,
+ float blinkingPeriod,
+ bool usingAlpha
+)
+{
+ rAssert( drawable );
+
+ if( elapsedTime > blinkingPeriod )
+ {
+ if( usingAlpha )
+ {
+ // toggle drawable visiblity (using alpha)
+ //
+ float newAlpha = (drawable->GetAlpha() > 0.5f) ? 0.0f : 1.0f;
+ drawable->SetAlpha( newAlpha );
+ }
+ else
+ {
+ // toggle drawable visibility
+ //
+ drawable->SetVisible( !drawable->IsVisible() );
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+float GuiSFX::Pulse
+(
+ float elapsedTime,
+ float period,
+ float center,
+ float amplitude,
+ float thetaOffset
+)
+{
+ float theta = rmt::PI_2 * elapsedTime / period - thetaOffset;
+
+ return( amplitude * rmt::Sin( theta ) + center );
+}
+
+void GuiSFX::ModulateColour
+(
+ tColour* currentColour,
+ float elapsedTime,
+ float period,
+ tColour startColour,
+ tColour endColour,
+ float thetaOffset
+)
+{
+ float modValue = GuiSFX::Pulse( elapsedTime, period, 0.5f, 0.5f, thetaOffset );
+
+ rAssert( currentColour != NULL );
+
+ currentColour->SetRed( startColour.Red() +
+ (int)( modValue * (endColour.Red() - startColour.Red()) ) );
+
+ currentColour->SetGreen( startColour.Green() +
+ (int)( modValue * (endColour.Green() - startColour.Green()) ) );
+
+ currentColour->SetBlue( startColour.Blue() +
+ (int)( modValue * (endColour.Blue() - startColour.Blue()) ) );
+
+ currentColour->SetAlpha( startColour.Alpha() +
+ (int)( modValue * (endColour.Alpha() - startColour.Alpha()) ) );
+}
+
+float GuiSFX::Pendulum
+(
+ Scrooby::BoundedDrawable* drawable,
+ float deltaTime,
+ float length,
+ float currentAngle,
+ float initialAngle,
+ float gravity
+)
+{
+ rAssertMsg( 0, "WARNING: *** Not yet implemented!" );
+
+ return 0.0f;
+/*
+ rAssert( drawable );
+
+ float root = (2 * gravity / length) *
+ (rmt::Cos( initialAngle ) - rmt::Cos( currentAngle ));
+
+ int rootSign = root > 0 ? 1 : -1;
+
+ // update current angle
+ if( currentAngle > 0.0f )
+ {
+ currentAngle -= rmt::Sqrt( root * rootSign )
+ * (deltaTime / 1000.0f);
+ }
+ else
+ {
+ currentAngle += rmt::Sqrt( root * rootSign )
+ * (deltaTime / 1000.0f);
+ }
+
+ // rotate pendulum arm
+ drawable->ResetTransformation();
+ drawable->RotateAboutCenter( rmt::RadianToDeg( currentAngle ) );
+
+ return currentAngle;
+*/
+}
+
+bool GuiSFX::Spiral
+(
+ Scrooby::BoundedDrawable* drawable,
+ float elapsedTime,
+ float durationTime,
+ float rotationPeriod,
+ float startScale,
+ float endScale,
+ bool withFading
+)
+{
+ if( elapsedTime > durationTime )
+ {
+ drawable->ResetTransformation();
+ drawable->ScaleAboutCenter( endScale );
+
+ if( withFading )
+ {
+ drawable->SetAlpha( 1.0f );
+ }
+
+ return true;
+ }
+
+ float spiralValue = elapsedTime / durationTime;
+
+ // calculate current scale factor
+ //
+ float scale = startScale +
+ spiralValue * (endScale - startScale);
+
+ // slow down rotation when nearing end of spiral effect
+ //
+ rotationPeriod += spiralValue * rotationPeriod;
+
+ // calculate current rotation angle
+ //
+ float rotation = elapsedTime / rotationPeriod * rmt::PI_2;
+
+ // scale and rotate drawable
+ //
+ rAssert( drawable );
+ drawable->ResetTransformation();
+ drawable->ScaleAboutCenter( scale );
+ drawable->RotateAboutCenter( rmt::RadianToDeg( rotation ) );
+
+ // if enabled, fade in the drawable as well
+ if( withFading )
+ {
+ drawable->SetAlpha( spiralValue );
+ }
+
+ return false;
+}
+
+bool GuiSFX::SlideX
+(
+ Scrooby::Drawable* drawable,
+ float elapsedTime,
+ float durationTime,
+ bool slideInwards,
+ int fromBorder,
+ int screenWidth
+)
+{
+ rAssert( drawable );
+
+ if( elapsedTime > durationTime )
+ {
+ drawable->ResetTransformation();
+
+ return true;
+ }
+
+ int posX = 0;
+ int posY = 0;
+ int width = 0;
+ int height = 0;
+ drawable->GetOriginPosition( posX, posY );
+ drawable->GetBoundingBoxSize( width, height );
+
+ int distanceX = (fromBorder > 0) ? (screenWidth - posX) : (posX + width);
+
+ float translationX = slideInwards ?
+ (1.0f - elapsedTime / durationTime) * distanceX :
+ (elapsedTime / durationTime) * distanceX;
+
+ drawable->ResetTransformation();
+ drawable->Translate( static_cast<int>( translationX ), 0 );
+
+ return false;
+}
+
+bool GuiSFX::SlideY
+(
+ Scrooby::Drawable* drawable,
+ float elapsedTime,
+ float durationTime,
+ bool slideInwards,
+ int fromBorder,
+ int screenHeight
+)
+{
+ rAssert( drawable );
+
+ if( elapsedTime > durationTime )
+ {
+ drawable->ResetTransformation();
+
+ return true;
+ }
+
+ int posX = 0;
+ int posY = 0;
+ int width = 0;
+ int height = 0;
+ drawable->GetOriginPosition( posX, posY );
+ drawable->GetBoundingBoxSize( width, height );
+
+ int distanceY = (fromBorder > 0) ? (screenHeight - posY) : (posY + height);
+
+ float translationY = slideInwards ?
+ (1.0f - elapsedTime / durationTime) * distanceY :
+ (elapsedTime / durationTime) * distanceY;
+
+ drawable->ResetTransformation();
+ drawable->Translate( 0, static_cast<int>( translationY ) );
+
+ return false;
+}
+
+bool GuiSFX::Flip
+(
+ Scrooby::BoundedDrawable* drawable,
+ float elapsedTime,
+ float durationTime,
+ float startAngle,
+ float endAngle,
+ rmt::Vector axis
+)
+{
+ rAssert( drawable );
+ drawable->ResetTransformation();
+
+ if( elapsedTime > durationTime )
+ {
+ return true;
+ }
+
+ // calculate current rotation angle
+ float rotation = startAngle +
+ elapsedTime / durationTime * (endAngle - startAngle);
+
+ // rotate the drawable about specified axis
+ drawable->RotateAboutCenter( rmt::RadianToDeg( rotation ), axis );
+
+ return false;
+}
+
+void GuiSFX::Projectile
+(
+ Scrooby::Drawable* drawable,
+ float elapsedTime,
+ float durationTime,
+ rmt::Vector initVelocity,
+ bool reverse,
+ float gravity
+)
+{
+ if( reverse )
+ {
+ // reverse the elapsed time
+ //
+ elapsedTime = durationTime - elapsedTime;
+ }
+
+ // calculate the current trajectory position
+ //
+ rmt::Vector currentPos;
+ currentPos.x = initVelocity.x * elapsedTime;
+ currentPos.y = initVelocity.y * elapsedTime +
+ 0.5f * gravity * elapsedTime * elapsedTime;
+ currentPos.z = 0.0f;
+
+ // translate the drawable
+ //
+ rAssert( drawable );
+ drawable->Translate( static_cast<int>( currentPos.x ),
+ static_cast<int>( currentPos.y ) );
+}
+
+void GuiSFX::Projectile
+(
+ Scrooby::Drawable* drawable,
+ float elapsedTime,
+ float durationTime,
+ rmt::Vector start,
+ rmt::Vector end,
+ bool reverse,
+ float gravity
+)
+{
+ // calculate the initial velocity
+ //
+ rmt::Vector initVelocity;
+ initVelocity.x = (end.x - start.x) / durationTime;
+ initVelocity.y = (end.y - start.y - 0.5f * gravity * durationTime * durationTime) / durationTime;
+ initVelocity.z = 0.0f;
+
+ GuiSFX::Projectile( drawable,
+ elapsedTime,
+ durationTime,
+ initVelocity,
+ reverse,
+ gravity );
+}
+
diff --git a/game/code/presentation/gui/utility/specialfx.h b/game/code/presentation/gui/utility/specialfx.h
new file mode 100644
index 0000000..12fc6fe
--- /dev/null
+++ b/game/code/presentation/gui/utility/specialfx.h
@@ -0,0 +1,166 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: SpecialFX
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/30 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef SPECIALFX_H
+#define SPECIALFX_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+
+#include <p3d/p3dtypes.hpp>
+#include <radmath/radmath.hpp>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class Drawable;
+ class BoundedDrawable;
+}
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+namespace GuiSFX
+{
+
+bool Flash
+(
+ Scrooby::BoundedDrawable* drawable,
+ float elapsedTime,
+ float durationTime,
+ int zoomRate = 0, // the higher the number, the faster the zoom
+ float maxScale = 1.5f,
+ float thresholdScale = 1.0f
+);
+
+bool Blink
+(
+ Scrooby::Drawable* drawable,
+ float elapsedTime,
+ float blinkingPeriod = 1000.0f,
+ bool usingAlpha = false
+);
+
+float Pulse
+(
+ float elapsedTime,
+ float period,
+ float center = 0.0f,
+ float amplitude = 1.0f,
+ float thetaOffset = 0.0f
+);
+
+void ModulateColour
+(
+ tColour* currentColour,
+ float elapsedTime,
+ float period,
+ tColour startColour,
+ tColour endColour,
+ float thetaOffset = 0.0f
+);
+
+float Pendulum
+(
+ Scrooby::BoundedDrawable* drawable,
+ float deltaTime,
+ float length,
+ float currentAngle,
+ float initialAngle,
+ float gravity = 9.81f
+);
+
+bool Spiral
+(
+ Scrooby::BoundedDrawable* drawable,
+ float elapsedTime,
+ float durationTime,
+ float rotationPeriod,
+ float startScale = 0.0f,
+ float endScale = 1.0f,
+ bool withFading = true
+);
+
+enum eSlideBorderX
+{
+ SLIDE_BORDER_LEFT = -1,
+ SLIDE_BORDER_RIGHT = 1
+};
+
+bool SlideX
+(
+ Scrooby::Drawable* drawable,
+ float elapsedTime,
+ float durationTime,
+ bool slideInwards,
+ int fromBorder,
+ int screenWidth = 640
+);
+
+enum eSlideBorderY
+{
+ SLIDE_BORDER_BOTTOM = -1,
+ SLIDE_BORDER_TOP = 1
+};
+
+bool SlideY
+(
+ Scrooby::Drawable* drawable,
+ float elapsedTime,
+ float durationTime,
+ bool slideInwards,
+ int fromBorder,
+ int screenHeight = 480
+);
+
+bool Flip
+(
+ Scrooby::BoundedDrawable* drawable,
+ float elapsedTime,
+ float durationTime,
+ float startAngle = 0.0f,
+ float endAngle = rmt::PI_2,
+ rmt::Vector axis = rmt::Vector( 1, 0, 0 )
+);
+
+void Projectile
+(
+ Scrooby::Drawable* drawable,
+ float elapsedTime,
+ float durationTime,
+ rmt::Vector initVelocity,
+ bool reverse = false,
+ float gravity = 0.005f
+);
+
+void Projectile
+(
+ Scrooby::Drawable* drawable,
+ float elapsedTime,
+ float durationTime,
+ rmt::Vector start,
+ rmt::Vector end,
+ bool reverse = false,
+ float gravity = 0.005f
+);
+
+} // GuiSFX namespace
+
+#endif // SPECIALFX_H
diff --git a/game/code/presentation/gui/utility/teletypetext.cpp b/game/code/presentation/gui/utility/teletypetext.cpp
new file mode 100644
index 0000000..fea1dc3
--- /dev/null
+++ b/game/code/presentation/gui/utility/teletypetext.cpp
@@ -0,0 +1,318 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CTeleTypeText
+//
+// Description: Implementation of the CTeleTypeText class.
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/19 TChu Created for SRR2
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <presentation/gui/utility/teletypetext.h>
+
+#include <raddebug.hpp> // Foundation
+#include <group.h>
+#include <text.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+//===========================================================================
+// CTeleTypeText::CTeleTypeText
+//===========================================================================
+// Description: Constructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CTeleTypeText::CTeleTypeText( Scrooby::Text* pText,
+ Scrooby::Group* pTextBox,
+ unsigned int numCharsPerSecond,
+ unsigned int numSecondsToDisplay )
+: m_state( STATE_INACTIVE ),
+ m_elapsedTime( 0 ),
+ m_teletypePeriod( 1000 / numCharsPerSecond ),
+ m_displayDuration( numSecondsToDisplay * 1000 ),
+ m_pText( pText ),
+ m_pTextBox( pTextBox ),
+ m_charBuffer( NULL ),
+ m_nextChar( 0 ),
+ m_currentCharIndex( 0 )
+{
+ rAssert( m_pText != NULL );
+
+ // hide by default
+ if( m_pTextBox != NULL )
+ {
+ m_pTextBox->SetVisible( false );
+ }
+ else
+ {
+ m_pText->SetVisible( false );
+ }
+
+ // wrap text by default
+ m_pText->SetTextMode( Scrooby::TEXT_WRAP );
+}
+
+//===========================================================================
+// CTeleTypeText::~CTeleTypeText
+//===========================================================================
+// Description: Destructor.
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//===========================================================================
+CTeleTypeText::~CTeleTypeText()
+{
+}
+
+//===========================================================================
+// CTeleTypeText::Update
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CTeleTypeText::Update( unsigned int elapsedTime )
+{
+ switch( m_state )
+ {
+ case STATE_TELETYPING:
+ {
+ if( m_elapsedTime >= m_teletypePeriod )
+ {
+ this->TypeNextCharacter();
+
+ m_elapsedTime = m_elapsedTime % m_teletypePeriod;
+ }
+
+ // update elapsed time
+ m_elapsedTime += elapsedTime;
+
+ break;
+ }
+ case STATE_DISPLAYING:
+ {
+ // 0 means display forever, until client hides it
+ //
+ if( m_displayDuration > 0 )
+ {
+ if( m_elapsedTime >= m_displayDuration )
+ {
+ this->HideMessage();
+ }
+
+ // update elapsed time
+ m_elapsedTime += elapsedTime;
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+//===========================================================================
+// CTeleTypeText::DisplayMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CTeleTypeText::DisplayMessage()
+{
+// rAssertMsg( m_state == STATE_INACTIVE, "ERROR: Teletype message in progress!\n" );
+ if( m_state != STATE_INACTIVE )
+ {
+ // ignore request if there's already a message in progress
+ return;
+ }
+
+ rAssert( m_pText );
+
+ // show scrooby text
+ if( m_pTextBox != NULL )
+ {
+ m_pTextBox->SetVisible( true );
+ }
+ else
+ {
+ m_pText->SetVisible( true );
+ }
+
+ // get string buffer from text
+ m_charBuffer = m_pText->GetStringBuffer();
+
+ rAssert( m_charBuffer );
+
+ // reset current character index
+ m_currentCharIndex = 0;
+
+ // save next character and terminate buffer
+ m_nextChar = m_charBuffer[ m_currentCharIndex + 1 ];
+ m_charBuffer[ m_currentCharIndex + 1 ] = '\0';
+
+ m_state = STATE_TELETYPING;
+}
+
+//===========================================================================
+// CTeleTypeText::DisplayMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CTeleTypeText::DisplayMessage( int index )
+{
+ rAssert( m_pText );
+
+ if( index >= 0 && index < m_pText->GetNumOfStrings() )
+ {
+ m_pText->SetIndex( index );
+
+ this->DisplayMessage();
+ }
+ else
+ {
+ rAssertMsg( 0, "WARNING: Invalid index for teletype message!\n" );
+ }
+}
+
+//===========================================================================
+// CTeleTypeText::HideMessage
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CTeleTypeText::HideMessage()
+{
+ // if stopped during middle of teletyping
+ if( m_state == STATE_TELETYPING )
+ {
+ // restore character in buffer
+ m_charBuffer[ m_currentCharIndex + 1 ] = m_nextChar;
+ }
+
+ // hide scrooby text
+ if( m_pTextBox != NULL )
+ {
+ m_pTextBox->SetVisible( false );
+ }
+ else
+ {
+ m_pText->SetVisible( false );
+ }
+
+ // reset elapsed time
+ m_elapsedTime = 0;
+
+ m_state = STATE_INACTIVE;
+}
+
+void CTeleTypeText::Pause()
+{
+ if( m_state == STATE_TELETYPING )
+ {
+ // restore character in buffer
+ m_charBuffer[ m_currentCharIndex + 1 ] = m_nextChar;
+
+ // hide scrooby text
+ m_pText->SetVisible( false );
+
+ m_state = STATE_PAUSED;
+ }
+}
+
+void CTeleTypeText::Resume()
+{
+ if( m_state == STATE_PAUSED )
+ {
+ // restore character in buffer
+ m_charBuffer[ m_currentCharIndex + 1 ] = '\0';
+
+ // show scrooby text
+ m_pText->SetVisible( true );
+
+ m_state = STATE_TELETYPING;
+ }
+}
+
+//===========================================================================
+// CTeleTypeText::TypeNextCharacter
+//===========================================================================
+// Description:
+//
+// Constraints: None.
+//
+// Parameters: None.
+//
+// Return:
+//
+//===========================================================================
+void CTeleTypeText::TypeNextCharacter()
+{
+ // increment current character index
+ m_currentCharIndex++;
+
+ // restore character in buffer
+ m_charBuffer[ m_currentCharIndex ] = m_nextChar;
+
+ // save next character and terminate buffer
+ m_nextChar = m_charBuffer[ m_currentCharIndex + 1 ];
+ m_charBuffer[ m_currentCharIndex + 1 ] = '\0';
+
+ // if end of buffer reached
+ if( m_nextChar == '\0' )
+ {
+ m_state = STATE_DISPLAYING;
+ }
+}
+
+//===========================================================================
+// Protected Member Functions
+//===========================================================================
diff --git a/game/code/presentation/gui/utility/teletypetext.h b/game/code/presentation/gui/utility/teletypetext.h
new file mode 100644
index 0000000..ebf9eae
--- /dev/null
+++ b/game/code/presentation/gui/utility/teletypetext.h
@@ -0,0 +1,120 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: CTeleTypeText
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/07/19 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef TELETYPETEXT_H
+#define TELETYPETEXT_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+
+#include <p3d/p3dtypes.hpp>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class Text;
+ class Group;
+}
+
+const unsigned int DEFAULT_TELETYPING_RATE = 8; // in characters/sec
+
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+class CTeleTypeText
+{
+ public:
+
+ CTeleTypeText( Scrooby::Text* pText,
+ Scrooby::Group* pTextBox = NULL,
+ unsigned int numCharsPerSecond = DEFAULT_TELETYPING_RATE,
+ unsigned int numSecondsToDisplay = 0 );
+ virtual ~CTeleTypeText();
+
+ // update teletype text
+ void Update( unsigned int elapsedTime );
+
+ // display message and start teletyping
+ void DisplayMessage();
+ void DisplayMessage( int index );
+
+ // hide message and stop teletyping if still in progress
+ void HideMessage();
+
+ // pause/resume teletyping
+ void Pause();
+ void Resume();
+
+ // accessor to scrooby text object
+ Scrooby::Text* GetText() const
+ {
+ return m_pText;
+ }
+
+ protected:
+
+ //---------------------------------------------------------------------
+ // Protected Functions
+ //---------------------------------------------------------------------
+
+ //---------------------------------------------------------------------
+ // Protected Data
+ //---------------------------------------------------------------------
+
+ private:
+
+ //---------------------------------------------------------------------
+ // Private Functions
+ //---------------------------------------------------------------------
+
+ // No copying or asignment. Declare but don't define.
+ //
+ CTeleTypeText( const CTeleTypeText& );
+ CTeleTypeText& operator= ( const CTeleTypeText& );
+
+ void TypeNextCharacter();
+
+ //---------------------------------------------------------------------
+ // Private Data
+ //---------------------------------------------------------------------
+
+ enum eTeletypeState
+ {
+ STATE_TELETYPING,
+ STATE_DISPLAYING,
+ STATE_PAUSED,
+
+ STATE_INACTIVE
+ };
+
+ eTeletypeState m_state;
+
+ unsigned int m_elapsedTime;
+ unsigned int m_teletypePeriod;
+ unsigned int m_displayDuration;
+
+ Scrooby::Text* m_pText;
+ Scrooby::Group* m_pTextBox;
+ P3D_UNICODE* m_charBuffer;
+ P3D_UNICODE m_nextChar;
+ int m_currentCharIndex;
+
+};
+
+#endif // TELETYPETEXT_H
diff --git a/game/code/presentation/gui/utility/transitions.cpp b/game/code/presentation/gui/utility/transitions.cpp
new file mode 100644
index 0000000..aba8d4b
--- /dev/null
+++ b/game/code/presentation/gui/utility/transitions.cpp
@@ -0,0 +1,2911 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: Transitions.cpp
+//
+// Description: Some transitions for the hud/frontned
+//
+// Authors: Ian Gipson
+//
+//
+//===========================================================================
+
+//===========================================================================
+// Includes
+//===========================================================================
+#include <boundeddrawable.h>
+#include <contexts/gameplay/gameplaycontext.h>
+#include <events/eventmanager.h>
+#include <input/inputmanager.h>
+#include <memory/classsizetracker.h>
+#include <p3d/anim/multicontroller.hpp>
+#include <p3d/utility.hpp>
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/guiwindow.h>
+#include <presentation/gui/utility/colourutility.h>
+#include <presentation/gui/utility/transitions.h>
+#include <radmath/trig.hpp>
+#include <sprite.h>
+
+//===========================================================================
+// Global Data, Local Data, Local Classes
+//===========================================================================
+#define WIDESCREEN_EXTRA_PIXELS 107
+//===========================================================================
+// Public Member Functions
+//===========================================================================
+
+namespace GuiSFX
+{
+
+#ifdef DEBUGWATCH
+ void ActivateCallback( void* userData )
+ {
+ Transition* transition = reinterpret_cast< Transition* >( userData );
+ Chainable* chainable = dynamic_cast< Chainable* >( transition );
+ if( chainable != NULL )
+ {
+ chainable->ResetChain();
+ chainable->Activate();
+ }
+ else
+ {
+ transition->Reset();
+ transition->Activate();
+ }
+ }
+
+ void DeativateCallback( void* userData )
+ {
+ Transition* transition = reinterpret_cast< Transition* >( userData );
+ transition->Deactivate();
+ }
+
+#endif
+
+//==============================================================================
+// Chainable::Chainable
+//==============================================================================
+// Description: constructor
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+Chainable::Chainable()
+{
+}
+
+//==============================================================================
+// Chainable::Chainable
+//==============================================================================
+// Description: constructor
+//
+// Parameters: name - the name of the transition.
+//
+// Return: N/A.
+//
+//==============================================================================
+Chainable::Chainable( const tName& name ):
+ Transition( name )
+{
+ //CLASSTRACKER_CREATE( Chainable );
+}
+
+
+//==============================================================================
+// Chainable1::Chainable1
+//==============================================================================
+// Description: constructor
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+Chainable1::Chainable1():
+ m_NextTransition( NULL )
+{
+ //nothing
+}
+
+//==============================================================================
+// Chainable1::Chainable1
+//==============================================================================
+// Description: constructor
+//
+// Parameters: name - the name of the object
+//
+// Return: N/A.
+//
+//==============================================================================
+Chainable1::Chainable1( const tName& name )
+ : Chainable( name )
+{
+ //nothing
+}
+
+//==============================================================================
+// Chainable1::ContinueChain
+//==============================================================================
+// Description: moves on to the next transition in the chain
+//
+// Parameters: none
+//
+// Return: N/A.
+//
+//==============================================================================
+void Chainable1::ContinueChain()
+{
+ Deactivate();
+ if( m_NextTransition != NULL )
+ {
+ m_NextTransition->Activate();
+ }
+}
+
+//==============================================================================
+// Chainable1::DeactivateChain
+//==============================================================================
+// Description: shuts down the entire chain
+//
+// Parameters: none
+//
+// Return: N/A.
+//
+//==============================================================================
+void Chainable1::DeactivateChain()
+{
+ Deactivate();
+ if( m_NextTransition != NULL )
+ {
+ m_NextTransition->DeactivateChain();
+ }
+}
+
+//==============================================================================
+// Chainable1::IsChainDone
+//==============================================================================
+// Description: determines if the entire chain of transitions is done
+//
+// Parameters: none
+//
+// Return: N/A.
+//
+//==============================================================================
+bool Chainable1::IsChainDone() const
+{
+ if( !IsDone() )
+ {
+ return false;
+ }
+
+ //
+ // Yay recursion!
+ //
+ if( m_NextTransition != NULL )
+ {
+ return m_NextTransition->IsChainDone();
+ }
+ return true;
+}
+
+//==============================================================================
+// Chainable1::operator=
+//==============================================================================
+// Description: assignment operator
+//
+// Parameters: right - the one we're assigning from
+//
+// Return: reference to self
+//
+//==============================================================================
+Chainable1& Chainable1::operator=( const Chainable1& right )
+{
+ if( this == &right )
+ {
+ return *this;
+ }
+ Transition::operator=( right );
+ m_NextTransition = right.m_NextTransition;
+ return *this;
+}
+
+//==============================================================================
+// Chainable1::ResetChain
+//==============================================================================
+// Description: resets the transition, and all subsequent transitions
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+void Chainable1::ResetChain()
+{
+ Reset();
+ if( m_NextTransition != NULL )
+ {
+ return m_NextTransition->ResetChain();
+ }
+
+}
+
+//==============================================================================
+// Chainable1::SetNextTransition
+//==============================================================================
+// Description: sets the next transition in the chain
+//
+// Parameters: transition - the next transition to use
+//
+// Return: N/A.
+//
+//==============================================================================
+void Chainable1::SetNextTransition( Chainable* transition )
+{
+ m_NextTransition = transition;
+}
+
+//==============================================================================
+// Chainable1::SetNextTransition
+//==============================================================================
+// Description: sets the next transition in the chain
+//
+// Parameters: transition - the next transition to use
+//
+// Return: N/A.
+//
+//==============================================================================
+void Chainable1::SetNextTransition( Chainable& transition )
+{
+ m_NextTransition = &transition;
+}
+
+//==============================================================================
+// Chainable2::Chainable2()
+//==============================================================================
+// Description: consturctor
+//
+// Parameters: none
+//
+// Return: N/A.
+//
+//==============================================================================
+Chainable2::Chainable2()
+{
+ m_NextTransition[ 0 ] = NULL;
+ m_NextTransition[ 1 ] = NULL;
+}
+
+//==============================================================================
+// Chainable2::Chainable2()
+//==============================================================================
+// Description: consturctor
+//
+// Parameters: name - the name of the transition
+//
+// Return: N/A.
+//
+//==============================================================================
+Chainable2::Chainable2( const tName& name ):
+ Chainable( name )
+{
+ m_NextTransition[ 0 ] = NULL;
+ m_NextTransition[ 1 ] = NULL;
+}
+
+//==============================================================================
+// Chainable2::ContinueChain()
+//==============================================================================
+// Description: continues the chain of transitions
+//
+// Parameters: name - the name of the transition
+//
+// Return: N/A.
+//
+//==============================================================================
+void Chainable2::ContinueChain()
+{
+ Deactivate();
+ int i;
+ for( i = 0; i < 2; ++i )
+ {
+ if( m_NextTransition[ i ] != NULL )
+ {
+ m_NextTransition[ i ]->Activate();
+ }
+ }
+}
+
+//==============================================================================
+// Chainable2::DeactivateChain()
+//==============================================================================
+// Description: shuts down the entire chain
+//
+// Parameters: none
+//
+// Return: N/A.
+//
+//==============================================================================
+void Chainable2::DeactivateChain()
+{
+ Deactivate();
+ int i;
+ for( i = 0; i < 2; ++i )
+ {
+ if( m_NextTransition[ i ] != NULL )
+ {
+ m_NextTransition[ i ]->DeactivateChain();
+ }
+ }
+}
+
+//==============================================================================
+// Chainable2::IsChainDone
+//==============================================================================
+// Description: determines if the entire chain of transitions is done
+//
+// Parameters: none
+//
+// Return: N/A.
+//
+//==============================================================================
+bool Chainable2::IsChainDone() const
+{
+ if( !IsDone() )
+ {
+ return false;
+ }
+
+ //
+ // Yay recursion!
+ //
+ int i;
+ for( i = 0; i < 2; ++i )
+ {
+ if( m_NextTransition[ i ] != NULL )
+ {
+ bool nextDone = m_NextTransition[ i ]->IsChainDone();
+ if( !nextDone )
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+//==============================================================================
+// Chainable2::ResetChain
+//==============================================================================
+// Description: resets the transition, and all subsequent transitions
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+void Chainable2::ResetChain()
+{
+ Reset();
+ if( m_NextTransition[ 0 ] != NULL )
+ {
+ m_NextTransition[ 0 ]->ResetChain();
+ }
+
+ if( m_NextTransition[ 1 ] != NULL )
+ {
+ m_NextTransition[ 1 ]->ResetChain();
+ }
+}
+
+//==============================================================================
+// Chainable2::SetNextTransition
+//==============================================================================
+// Description: sets one of the next transitions triggered by this one
+//
+// Parameters: index - which one of the next transitions to set
+// transition - pointer to the transition
+//
+// Return: N/A.
+//
+//==============================================================================
+void Chainable2::SetNextTransition( const unsigned int index, Chainable* transition )
+{
+ rAssert( index < 2 );
+ m_NextTransition[ index ] = transition;
+}
+
+//==============================================================================
+// Chainable2::SetNextTransition
+//==============================================================================
+// Description: sets one of the next transitions triggered by this one
+//
+// Parameters: index - which one of the next transitions to set
+// transition - pointer to the transition
+//
+// Return: N/A.
+//
+//==============================================================================
+void Chainable2::SetNextTransition( const unsigned int index, Chainable& transition )
+{
+ SetNextTransition( index, &transition );
+}
+
+//==============================================================================
+// Chainable3::Chainable3()
+//==============================================================================
+// Description: consturctor
+//
+// Parameters: none
+//
+// Return: N/A.
+//
+//==============================================================================
+Chainable3::Chainable3()
+{
+ m_NextTransition[ 0 ] = NULL;
+ m_NextTransition[ 1 ] = NULL;
+ m_NextTransition[ 2 ] = NULL;
+}
+
+//==============================================================================
+// Chainable3::Chainable3()
+//==============================================================================
+// Description: consturctor
+//
+// Parameters: name - the name of the transition
+//
+// Return: N/A.
+//
+//==============================================================================
+Chainable3::Chainable3( const tName& name ):
+ Chainable( name )
+{
+ m_NextTransition[ 0 ] = NULL;
+ m_NextTransition[ 1 ] = NULL;
+ m_NextTransition[ 2 ] = NULL;
+}
+
+//==============================================================================
+// Chainable3::ContinueChain()
+//==============================================================================
+// Description: continues the chain of transitions
+//
+// Parameters: name - the name of the transition
+//
+// Return: N/A.
+//
+//==============================================================================
+void Chainable3::ContinueChain()
+{
+ Deactivate();
+ int i;
+ for( i = 0; i < 3; ++i )
+ {
+ if( m_NextTransition[ i ] != NULL )
+ {
+ m_NextTransition[ i ]->Activate();
+ }
+ }
+}
+
+//==============================================================================
+// Chainable3::DeactivateChain()
+//==============================================================================
+// Description: shuts down the entire chain
+//
+// Parameters: none
+//
+// Return: N/A.
+//
+//==============================================================================
+void Chainable3::DeactivateChain()
+{
+ Deactivate();
+ int i;
+ for( i = 0; i < 3; ++i )
+ {
+ if( m_NextTransition[ i ] != NULL )
+ {
+ m_NextTransition[ i ]->DeactivateChain();
+ }
+ }
+}
+
+
+//==============================================================================
+// Chainable3::IsChainDone
+//==============================================================================
+// Description: determines if the entire chain of transitions is done
+//
+// Parameters: none
+//
+// Return: N/A.
+//
+//==============================================================================
+bool Chainable3::IsChainDone() const
+{
+ if( !IsDone() )
+ {
+ return false;
+ }
+
+ //
+ // Yay recursion!
+ //
+ int i;
+ for( i = 0; i < 3; ++i )
+ {
+ if( m_NextTransition[ i ] != NULL )
+ {
+ bool nextDone = m_NextTransition[ i ]->IsChainDone();
+ if( !nextDone )
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+//==============================================================================
+// Chainable3::ResetChain
+//==============================================================================
+// Description: resets the transition, and all subsequent transitions
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+void Chainable3::ResetChain()
+{
+ Reset();
+ if( m_NextTransition[ 0 ] != NULL )
+ {
+ m_NextTransition[ 0 ]->ResetChain();
+ }
+
+ if( m_NextTransition[ 1 ] != NULL )
+ {
+ m_NextTransition[ 1 ]->ResetChain();
+ }
+
+ if( m_NextTransition[ 2 ] != NULL )
+ {
+ m_NextTransition[ 2 ]->ResetChain();
+ }
+}
+
+//==============================================================================
+// Chainable3::SetNextTransition
+//==============================================================================
+// Description: sets one of the next transitions triggered by this one
+//
+// Parameters: index - which one of the next transitions to set
+// transition - pointer to the transition
+//
+// Return: N/A.
+//
+//==============================================================================
+void Chainable3::SetNextTransition( const unsigned int index, Chainable* transition )
+{
+ rAssert( index < 3 );
+ m_NextTransition[ index ] = transition;
+}
+
+//==============================================================================
+// Chainable3::SetNextTransition
+//==============================================================================
+// Description: sets one of the next transitions triggered by this one
+//
+// Parameters: index - which one of the next transitions to set
+// transition - pointer to the transition
+//
+// Return: N/A.
+//
+//==============================================================================
+void Chainable3::SetNextTransition( const unsigned int index, Chainable& transition )
+{
+ SetNextTransition( index, &transition );
+}
+
+//==============================================================================
+// ColorChange::ColorChange
+//==============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+ColorChange::ColorChange()
+{
+}
+
+//==============================================================================
+// ColorChange::ColorChange
+//==============================================================================
+// Description: constructor
+//
+// Parameters: name - the name of the object
+//
+// Return: N/A.
+//
+//==============================================================================
+ColorChange::ColorChange( const tName& name ):
+ Chainable1( name )
+{
+}
+
+//==============================================================================
+// ColorChange::SetStartColour
+//==============================================================================
+// Description: sets the starting color for the color transition
+//
+// Parameters: transition - the next transition to use
+//
+// Return: N/A.
+//
+//==============================================================================
+void ColorChange::SetStartColour( const tColour c )
+{
+ m_StartColor = c;
+}
+
+//==============================================================================
+// ColorChange::SetEndColour
+//==============================================================================
+// Description: sets the end color for the transition
+//
+// Parameters: transition - the next transition to use
+//
+// Return: N/A.
+//
+//==============================================================================
+void ColorChange::SetEndColour( const tColour c )
+{
+ m_EndColor = c;
+}
+
+//==============================================================================
+// ColorChange::Update
+//==============================================================================
+// Description: updates the color change transition
+//
+// Parameters: transition - the next transition to use
+//
+// Return: N/A.
+//
+//==============================================================================
+void ColorChange::Update( const float deltaT )
+{
+ if( this->IsActive() )
+ {
+ Transition::Update( deltaT );
+ float spillover = rmt::Max( m_ElapsedTime - m_TimeInterval, 0.0f );
+ m_ElapsedTime = rmt::Min( m_ElapsedTime, m_TimeInterval );
+
+ float percent = m_ElapsedTime / m_TimeInterval;
+ tColour color = m_StartColor * ( 1.0f - percent ) + m_EndColor * percent;
+ if( m_Drawable != NULL )
+ {
+ m_Drawable->SetColour( color );
+ }
+
+ if( spillover > 0 )
+ {
+ ContinueChain();
+ }
+ }
+}
+
+//==============================================================================
+// ColorChange::Watch
+//==============================================================================
+// Description: Adds this transition to the watcher
+//
+// Parameters: nameSpace - the name of the group in the watcher
+//
+// Return: N/A.
+//
+//==============================================================================
+#ifdef DEBUGWATCH
+void ColorChange::Watch( const char* nameSpace )
+{
+ char output[ 1024 ];
+ sprintf( output, "%s\\%s", nameSpace, m_Name.GetText() );
+ Parent1::Watch( output );
+ Parent2::Watch( output );
+}
+#endif
+
+//==============================================================================
+// Dummy::Dummy
+//==============================================================================
+// Description: Constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+Dummy::Dummy()
+{
+}
+
+//==============================================================================
+// Dummy::Dummy
+//==============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+Dummy::Dummy( const tName& name ):
+ Parent( name )
+{
+}
+
+//==============================================================================
+// Dummy::Activate
+//==============================================================================
+// Description: does nothing, and carrys on
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+void Dummy::Activate()
+{
+ Parent::Activate();
+ ContinueChain();
+}
+
+//=============================================================================
+// GotoScreen::GotoScreen()
+//=============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+GotoScreen::GotoScreen():
+ mScreen( CGuiWindow::GUI_WINDOW_ID_UNDEFINED ),
+ mParam1( 0 ),
+ mParam2( 0 ),
+ mWindowOptions( 0 )
+{
+ //nothing
+}
+
+//=============================================================================
+// GotoScreen::GotoScreen()
+//=============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+GotoScreen::GotoScreen( const tName& name ):
+ Parent( name ),
+ mScreen( CGuiWindow::GUI_WINDOW_ID_UNDEFINED ),
+ mParam1( 0 ),
+ mParam2( 0 ),
+ mWindowOptions( 0 )
+{
+ //nothing
+}
+
+//=============================================================================
+// SendEvent::Activate()
+//=============================================================================
+// Description: fires off the event that we're supposed to send at this point
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+void GotoScreen::Activate()
+{
+ Transition::Activate();
+ rAssert( mScreen != CGuiWindow::GUI_WINDOW_ID_UNDEFINED );
+ GetGuiSystem()->GotoScreen( mScreen, mParam1, mParam2, mWindowOptions );
+ ContinueChain();
+}
+
+//=============================================================================
+// SendEvent::SetEventData
+//=============================================================================
+// Description: sets the event data that we're going to fire off later on
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+void GotoScreen::SetEventData( void* eventData )
+{
+ mEventData = eventData;
+}
+
+//=============================================================================
+// GotoScreen::SetParam1
+//=============================================================================
+// Description: sets the event data that we're going to fire off later on
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+void GotoScreen::SetParam1( const unsigned int param1 )
+{
+ mParam1 = param1;
+}
+
+//=============================================================================
+// GotoScreen::SetParam2
+//=============================================================================
+// Description: sets the event data that we're going to fire off later on
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+void GotoScreen::SetParam2( const unsigned int param2 )
+{
+ mParam2 = param2;
+}
+
+//=============================================================================
+// SendEvent::SetEvent
+//=============================================================================
+// Description: sets the event that we're going to fire off later on
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+void GotoScreen::SetScreen( CGuiWindow::eGuiWindowID screen )
+{
+ mScreen = screen;
+}
+
+//=============================================================================
+// GotoScreen::SetWindowOptions
+//=============================================================================
+// Description: sets the event data that we're going to fire off later on
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+void GotoScreen::SetWindowOptions( const unsigned int windowOptions )
+{
+ mWindowOptions = windowOptions;
+}
+
+//==============================================================================
+// HasMulticontroller::ResetMultiControllerFrames
+//==============================================================================
+// Description: sometimes you screw up the nubmer of frames in a multicontoller
+// calling this function will fix things
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+void HasMulticontroller::ResetMultiControllerFrames()
+{
+ m_MultiController->SetFrameRange( 0.0f, m_NumFrames );
+}
+
+//==============================================================================
+// HasMulticontroller::SetMultiController
+//==============================================================================
+// Description: sets up the multicontroller that this transition requires
+//
+// Parameters: multicontroller - the multicontroller to use
+//
+// Return: N/A.
+//
+//==============================================================================
+void HasMulticontroller::SetMultiController( tMultiController* multicontroller )
+{
+ m_MultiController = multicontroller;
+ m_NumFrames = m_MultiController->GetNumFrames();
+}
+
+//==============================================================================
+// HasTimeInterval::HasTimeInterval
+//==============================================================================
+// Description: constructor
+//
+// Parameters: none
+//
+// Return: N/A.
+//
+//==============================================================================
+HasTimeInterval::HasTimeInterval():
+ m_TimeInterval( 1000.0f )
+{
+ //nothing
+}
+
+//==============================================================================
+// HasTimeInterval::SetTimeInterval
+//==============================================================================
+// Description: sets the time interval that this transition should wait
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+void HasTimeInterval::SetTimeInterval( const float interval )
+{
+ m_TimeInterval = interval;
+}
+
+//==============================================================================
+// HasTimeInterval::Watch
+//==============================================================================
+// Description: Adds this transition to the watcher
+//
+// Parameters: nameSpace - the name of the group in the watcher
+//
+// Return: N/A.
+//
+//==============================================================================
+#ifdef DEBUGWATCH
+void HasTimeInterval::Watch( const char* nameSpace )
+{
+ radDbgWatchDelete( &m_TimeInterval );
+ radDbgWatchAddFloat( &m_TimeInterval, "timeInterval", nameSpace, NULL, NULL, 0.0f, 1000.0f );
+}
+#endif
+
+//==============================================================================
+// Hide::Hide
+//==============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+Hide::Hide()
+{
+ //nothing
+}
+
+//==============================================================================
+// Hide::Hide
+//==============================================================================
+// Description: constructor
+//
+// Parameters: name - the name of the object
+//
+// Return: N/A.
+//
+//==============================================================================
+Hide::Hide( const tName& name ):
+ Chainable1( name )
+{
+}
+
+//==============================================================================
+// Hide::Activate
+//==============================================================================
+// Description: this gets called when a hide transition is triggered
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+void Hide::Activate()
+{
+ Transition::Activate();
+ rAssert( m_Drawable != NULL );
+ if( m_Drawable != NULL )
+ {
+ m_Drawable->SetVisible( false );
+ }
+ ContinueChain();
+}
+
+//==============================================================================
+// ImageCycler::SetDrawable
+//==============================================================================
+// Description: set the period for cycling images
+//
+// Parameters: period - float period in ms
+//
+// Return: N/A.
+//
+//==============================================================================
+void ImageCycler::SetDrawable( Scrooby::Drawable* drawable )
+{
+ Transition::SetDrawable( drawable );
+ m_Sprite = dynamic_cast< Scrooby::Sprite* >( m_Drawable );
+ rAssert( m_Sprite != NULL );
+}
+
+//==============================================================================
+// ImageCycler::SetDrawable
+//==============================================================================
+// Description: set the period for cycling images
+//
+// Parameters: period - float period in ms
+//
+// Return: N/A.
+//
+//==============================================================================
+void ImageCycler::SetDrawable( Scrooby::Drawable& drawable )
+{
+ Transition::SetDrawable( drawable );
+ m_Sprite = dynamic_cast< Scrooby::Sprite* >( m_Drawable );
+ rAssert( m_Sprite != NULL );
+}
+
+//==============================================================================
+// InputStateChange::InputStateChange
+//==============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+InputStateChange::InputStateChange():
+ Parent(),
+ mState( Input::ACTIVE_NONE )
+{
+ //nothing
+}
+
+//==============================================================================
+// InputStateChange::InputStateChange
+//==============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+InputStateChange::InputStateChange( const tName& name ):
+ Parent( name ),
+ mState( Input::ACTIVE_NONE )
+{
+ //nothing
+}
+
+//==============================================================================
+// InputStateChange::Activate
+//==============================================================================
+// Description: called when this transition is activated
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+void InputStateChange::Activate()
+{
+ Parent::Activate();
+ InputManager::GetInstance()->SetGameState( mState );
+ ContinueChain();
+}
+
+//==============================================================================
+// InputStateChange::SetState
+//==============================================================================
+// Description: set the state that this transition will take the input to
+//
+// Parameters: state - what input state should we go to?
+//
+// Return: N/A.
+//
+//==============================================================================
+void InputStateChange::SetState( const Input::ActiveState state )
+{
+ mState = state;
+}
+
+//==============================================================================
+// IrisWipeClose::IrisWipeClose
+//==============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+IrisWipeClose::IrisWipeClose()
+{
+ //none
+}
+
+//==============================================================================
+// IrisWipeClose::IrisWipeClose
+//==============================================================================
+// Description: constructor
+//
+// Parameters: name - the name of the object for debugging
+//
+// Return: N/A.
+//
+//==============================================================================
+IrisWipeClose::IrisWipeClose( const tName& name ):
+ Chainable1( name )
+{
+ //none
+}
+
+//==============================================================================
+// IrisWipeClose::Activate
+//==============================================================================
+// Description: starts the iris wipe transition
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+void IrisWipeClose::Activate()
+{
+ m_MultiController->Reset();
+ m_MultiController->SetFrameRange( 0, m_NumFrames * 0.5f );
+ m_MultiController->SetFrame( 0 );
+ Chainable1::Activate();
+}
+
+void IrisWipeClose::Deactivate()
+{
+ Chainable1::Deactivate();
+}
+
+//==============================================================================
+// IrisWipeOpen::Update
+//==============================================================================
+// Description: needed to check if the irisWipeTransition can move on
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+void IrisWipeClose::Update( const float deltaT )
+{
+ if( IsActive() )
+ {
+ Chainable1::Update( deltaT );
+ if( m_MultiController != NULL )
+ {
+ if( m_MultiController->LastFrameReached() )
+ {
+ m_MultiController->SetFrameRange( 0.0f, m_NumFrames );
+ ResetMultiControllerFrames();
+ ContinueChain();
+ }
+ }
+ }
+}
+
+//==============================================================================
+// IrisWipeOpen::IrisWipeOpen
+//==============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+IrisWipeOpen::IrisWipeOpen()
+{
+ //none
+}
+
+//==============================================================================
+// IrisWipeOpen::IrisWipeOpen
+//==============================================================================
+// Description: constructor
+//
+// Parameters: name - the name of the object for debugging
+//
+// Return: N/A.
+//
+//==============================================================================
+IrisWipeOpen::IrisWipeOpen( const tName& name ):
+ Chainable1( name )
+{
+ //none
+}
+
+//==============================================================================
+// IrisWipeOpen::Activate
+//==============================================================================
+// Description: starts the iris wipe transition
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+void IrisWipeOpen::Activate()
+{
+ tMultiController* multiController = p3d::find< tMultiController >( "IrisController" );
+ rAssert( m_MultiController != NULL );
+ SetMultiController( multiController );
+
+ m_MultiController->Reset();
+ m_MultiController->SetFrameRange( m_NumFrames * 0.5f, m_NumFrames );
+ m_MultiController->SetFrame( m_NumFrames * 0.5f );
+ Chainable1::Activate();
+}
+
+//==============================================================================
+// IrisWipeOpen::Update
+//==============================================================================
+// Description: needed to check if the irisWipeTransition can move on
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+void IrisWipeOpen::Update( const float deltaT )
+{
+ if( IsActive() )
+ {
+ if( m_MultiController->LastFrameReached() )
+ {
+ m_MultiController->SetFrameRange( 0.0f, m_NumFrames );
+ ResetMultiControllerFrames();
+ ContinueChain();
+ }
+ }
+}
+
+//==============================================================================
+// ImageCycler::SetPeriod
+//==============================================================================
+// Description: set the period for cycling images
+//
+// Parameters: period - float period in ms
+//
+// Return: N/A.
+//
+//==============================================================================
+void ImageCycler::SetPeriod( const float period )
+{
+ m_Period = period;
+}
+
+//==============================================================================
+// ImageCycler::Update
+//==============================================================================
+// Description: updates the transition animation
+//
+// Parameters: deltaT - the time elapsed
+//
+// Return: N/A.
+//
+//==============================================================================
+void ImageCycler::Update( const float deltaT )
+{
+ if( IsActive() )
+ {
+ Transition::Update( deltaT );
+ if( m_Sprite != NULL )
+ {
+ int nubmerOfStates = m_Sprite->GetNumOfImages();
+ int periodsElapsed = static_cast< int >( m_ElapsedTime / m_Period );
+ int imageNumber = periodsElapsed % nubmerOfStates;
+ m_Sprite->SetIndex( imageNumber );
+ }
+ }
+}
+
+//==============================================================================
+// Junction2::Activate()
+//==============================================================================
+// Description: activates all the transitions leaving this junction
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+void Junction2::Activate()
+{
+ ContinueChain();
+}
+
+//==============================================================================
+// Junction3::Activate()
+//==============================================================================
+// Description: activates all the transitions leaving this junction
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+void Junction3::Activate()
+{
+ ContinueChain();
+}
+
+//==============================================================================
+// Pause::Pause
+//==============================================================================
+// Description: constructor
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+Pause::Pause()
+{
+ //nothing
+}
+
+//==============================================================================
+// Pause::Pause
+//==============================================================================
+// Description: constructor
+//
+// Parameters: name - the name of the object
+//
+// Return: N/A.
+//
+//==============================================================================
+Pause::Pause( const tName& name ):
+ Chainable1( name )
+{
+}
+
+//==============================================================================
+// Pause::Update
+//==============================================================================
+// Description: Updates the transition
+//
+// Parameters: elapsed time - how much time has passed
+//
+// Return: N/A.
+//
+//==============================================================================
+void Pause::Update( const float deltaT )
+{
+ if( IsActive() )
+ {
+ Transition::Update( deltaT );
+ float spillover = rmt::Max( m_ElapsedTime - m_TimeInterval, 0.0f );
+ m_ElapsedTime = rmt::Min( m_ElapsedTime, m_TimeInterval );
+ if( spillover > 0 )
+ {
+ ContinueChain();
+ }
+ }
+}
+
+//=============================================================================
+// Pause::Watch
+//=============================================================================
+// Description: adds the pause transition object to the watcher
+//
+// Parameters: deleaT - how much time has passed
+//
+// Return: N/A.
+//
+//=============================================================================
+#ifdef DEBUGWATCH
+void Pause::Watch( const char* nameSpace )
+{
+ char output[ 1024 ];
+ sprintf( output, "%s\\%s", nameSpace, m_Name.GetText() );
+ Parent1::Watch( output );
+ Parent2::Watch( output );
+}
+#endif
+
+//==============================================================================
+// PauseInFrames::PauseInFrames
+//==============================================================================
+// Description: constructor
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+PauseInFrames::PauseInFrames():
+ m_FramesToPause( 1 ),
+ m_FramesElapsed( 0 )
+{
+ //nothing
+}
+
+//==============================================================================
+// Pause::Pause
+//==============================================================================
+// Description: constructor
+//
+// Parameters: name - the name of the object
+//
+// Return: N/A.
+//
+//==============================================================================
+PauseInFrames::PauseInFrames( const tName& name ):
+ Parent( name ),
+ m_FramesToPause( 1 ),
+ m_FramesElapsed( 0 )
+{
+ //nothing
+}
+
+//==============================================================================
+// PauseInFrames::Reset
+//==============================================================================
+// Description: Resets the transition
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+void PauseInFrames::Reset()
+{
+ Parent::Reset();
+ m_FramesElapsed = 0;
+}
+
+//==============================================================================
+// PauseInFrames::SetNumberOfFrames
+//==============================================================================
+// Description: How many frames should this transition pause for?
+//
+// Parameters: i - thenubmer of fraems to pause
+//
+// Return: N/A.
+//
+//==============================================================================
+void PauseInFrames::SetNumberOfFrames( const unsigned int i )
+{
+ m_FramesToPause = i;
+}
+
+//==============================================================================
+// PauseInFrames::Update
+//==============================================================================
+// Description: Updates the transition
+//
+// Parameters: elapsed time - how much time has passed
+//
+// Return: N/A.
+//
+//==============================================================================
+void PauseInFrames::Update( const float deltaT )
+{
+ if( IsActive() )
+ {
+ Parent::Update( deltaT );
+
+ if( deltaT > 0.0f )
+ {
+ ++m_FramesElapsed;
+ }
+
+ if( m_FramesElapsed == m_FramesToPause )
+ {
+ ContinueChain();
+ }
+ }
+}
+
+//==============================================================================
+// PauseGame::Activate
+//==============================================================================
+// Description: transition that pauses the game
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+void PauseGame::Activate()
+{
+ GameplayContext::GetInstance()->PauseAllButPresentation( true );
+ ContinueChain();
+}
+
+//==============================================================================
+// PulseScale::PulseScale
+//==============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+PulseScale::PulseScale():
+ Transition(),
+ m_BoundedDrawable( NULL ),
+ m_Amplitude( 0.25f ),
+ m_Frequency( 5.0f )
+{
+}
+
+//==============================================================================
+// PulseScale::PulseScale
+//==============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+PulseScale::PulseScale( const tName& name ):
+ Transition( name ),
+ m_BoundedDrawable( NULL ),
+ m_Amplitude( 0.25f ),
+ m_Frequency( 5.0f )
+{
+}
+
+//==============================================================================
+// PulseScale::MovesDrawable
+//==============================================================================
+// Description: does this transition move a drawable object?
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+bool PulseScale::MovesDrawable() const
+{
+ return true;
+}
+
+//==============================================================================
+// PulseScale::SetAmplitude
+//==============================================================================
+// Description: sets the amplitude of the pulsing
+//
+// Parameters: amplitude - the size of the pulsing
+//
+// Return: N/A.
+//
+//==============================================================================
+void PulseScale::SetAmplitude( const float amplitude )
+{
+ m_Amplitude = amplitude;
+}
+
+//==============================================================================
+// PulseScale::SetDrawable
+//==============================================================================
+// Description: sets the drawable that we'll be pulsing
+//
+// Parameters: drawable
+//
+// Return: N/A.
+//
+//==============================================================================
+void PulseScale::SetDrawable( Scrooby::Drawable& drawable )
+{
+ Transition::SetDrawable( drawable );
+ m_BoundedDrawable = dynamic_cast< Scrooby::BoundedDrawable* >( m_Drawable );
+ rAssert( m_BoundedDrawable != NULL );
+}
+
+//==============================================================================
+// PulseScale::SetDrawable
+//==============================================================================
+// Description: sets the drawable that we'll be pulsing
+//
+// Parameters: drawable
+//
+// Return: N/A.
+//
+//==============================================================================
+void PulseScale::SetDrawable( Scrooby::Drawable* drawable )
+{
+ Transition::SetDrawable( drawable );
+ m_BoundedDrawable = dynamic_cast< Scrooby::HasBoundingBox* >( m_Drawable );
+ rAssert( m_BoundedDrawable != NULL );
+}
+
+//==============================================================================
+// Pulse::SetFrequency
+//==============================================================================
+// Description: sets the frequency of the pulse effect (in Hz)
+//
+// Parameters: frequency - the frequency
+//
+// Return: N/A.
+//
+//==============================================================================
+void PulseScale::SetFrequency( const float frequency )
+{
+ m_Frequency = frequency;
+}
+
+//=============================================================================
+// Pulse::Update
+//=============================================================================
+// Description: causes the bitmap to pulse
+//
+// Parameters: deleaT - how much time has passed
+//
+// Return: N/A.
+//
+//=============================================================================
+void PulseScale::Update( const float deltaT )
+{
+ if( IsActive() )
+ {
+ Transition::Update( deltaT );
+ float period = 1000.0f / m_Frequency;
+ m_ElapsedTime = fmodf( m_ElapsedTime, period );
+ float sin = rmt::Sin( m_ElapsedTime * m_Frequency / 1000.0f * rmt::PI * 2 );
+ float scale = sin * m_Amplitude + 1.0f;
+ m_BoundedDrawable->ScaleAboutCenter( scale );
+ }
+}
+
+//=============================================================================
+// PulseScale::Watch
+//=============================================================================
+// Description: adds the pulse transition object to the watcher
+//
+// Parameters: deleaT - how much time has passed
+//
+// Return: N/A.
+//
+//=============================================================================
+#ifdef DEBUGWATCH
+void PulseScale::Watch( const char* nameSpace )
+{
+ Parent::Watch( nameSpace );
+ char output[ 1024 ];
+ sprintf( output, "%s\\%s", nameSpace, m_Name.GetText() );
+ radDbgWatchDelete( &m_Amplitude );
+ radDbgWatchDelete( &m_Frequency );
+ radDbgWatchAddFloat( &m_Amplitude, "Amplitude", output, NULL, NULL, 0.0f, 1.0f );
+ radDbgWatchAddFloat( &m_Frequency, "Frequency", output, NULL, NULL, 0.0f, rmt::PI * 4 );
+}
+#endif
+
+
+//==============================================================================
+// RecieveEvent::RecieveEvent
+//==============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+RecieveEvent::RecieveEvent():
+ Chainable1(),
+ mEvent( NUM_EVENTS )
+{
+ //nothing
+}
+
+//=============================================================================
+// RecieveEvent::RecieveEvent
+//=============================================================================
+// Description: constructor
+//
+// Parameters: name - the name of the object
+//
+// Return: N/A.
+//
+//=============================================================================
+RecieveEvent::RecieveEvent( const tName& name ):
+ Chainable1( name ),
+ mEvent( NUM_EVENTS )
+{
+ //nothing
+}
+
+//=============================================================================
+// RecieveEvent::Activate
+//=============================================================================
+// Description: activate makes the object start listening for it's event
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+void RecieveEvent::Activate()
+{
+ rAssertMsg( mEvent != NUM_EVENTS, "you need to set the event to something meaningful before this can be activated" );
+ GetEventManager()->AddListener( this, mEvent );
+}
+
+//=============================================================================
+// RecieveEvent::HandleEvent
+//=============================================================================
+// Description: we've got the message we were listenting for if we get this
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+void RecieveEvent::HandleEvent( EventEnum id, void* pEventData )
+{
+ GetEventManager()->RemoveListener( this, mEvent );
+ ContinueChain();
+}
+
+//=============================================================================
+// RecieveEvent::SetEvent
+//=============================================================================
+// Description: specify which event we should be listenting for
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+void RecieveEvent::SetEvent( const EventEnum event )
+{
+ mEvent = event;
+ //IAN: better ensure that this listener isn't active at the moment
+}
+
+//==============================================================================
+// ResumeGame::Activate
+//==============================================================================
+// Description: transition that resumes a paused game the game
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+ResumeGame::ResumeGame():
+ Chainable1()
+{
+ //nothing
+}
+
+//==============================================================================
+// ResumeGame::Activate
+//==============================================================================
+// Description: transition that resumes a paused game the game
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+ResumeGame::ResumeGame( const tName& name ):
+ Chainable1( name )
+{
+ //nothing
+}
+
+//==============================================================================
+// ResumeGame::Activate
+//==============================================================================
+// Description: transition that resumes a paused game the game
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+void ResumeGame::Activate()
+{
+ GameplayContext::GetInstance()->PauseAllButPresentation( false );
+ ContinueChain();
+}
+
+//=============================================================================
+// SendEvent::SendEvent()
+//=============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+SendEvent::SendEvent():
+ mEvent( NUM_EVENTS )
+{
+ //nothing
+}
+
+//=============================================================================
+// SendEvent::SendEvent()
+//=============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+SendEvent::SendEvent( const tName& name ):
+ Chainable1( name ),
+ mEvent( NUM_EVENTS )
+{
+ //nothing
+}
+
+//=============================================================================
+// SendEvent::Activate()
+//=============================================================================
+// Description: fires off the event that we're supposed to send at this point
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+void SendEvent::Activate()
+{
+ Transition::Activate();
+ rAssert( mEvent != NUM_EVENTS );
+ GetEventManager()->TriggerEvent( mEvent, mEventData );
+ ContinueChain();
+}
+
+//=============================================================================
+// SendEvent::SetEvent
+//=============================================================================
+// Description: sets the event that we're going to fire off later on
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+void SendEvent::SetEvent( EventEnum event )
+{
+ mEvent = event;
+}
+
+//=============================================================================
+// SendEvent::SetEventData
+//=============================================================================
+// Description: sets the event data that we're going to fire off later on
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+void SendEvent::SetEventData( void* eventData )
+{
+ mEventData = eventData;
+}
+
+//=============================================================================
+// SwitchContext::SwitchContext()
+//=============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+SwitchContext::SwitchContext():
+ mContext( NUM_CONTEXTS )
+{
+ //nothing
+}
+
+//=============================================================================
+// SwitchContext::SwitchContext()
+//=============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+SwitchContext::SwitchContext( const tName& name ):
+ Parent( name ),
+ mContext( NUM_CONTEXTS )
+{
+ //nothing
+}
+
+//=============================================================================
+// SwitchContext::Activate()
+//=============================================================================
+// Description: changes to the context that we want
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+void SwitchContext::Activate()
+{
+ Transition::Activate();
+ rAssert( mContext != NUM_CONTEXTS );
+ GetGameFlow()->SetContext( mContext );
+ ContinueChain();
+}
+
+//=============================================================================
+// SwitchContext::SetContext
+//=============================================================================
+// Description: sets the context to which we will be going
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//=============================================================================
+void SwitchContext::SetContext( ContextEnum context )
+{
+ mContext = context;
+}
+
+//==============================================================================
+// Show::Show
+//==============================================================================
+// Description: constructor
+//
+// Parameters: NONE
+//
+// Return: N/A.
+//
+//==============================================================================
+Show::Show()
+{
+}
+//==============================================================================
+// Show::Show
+//==============================================================================
+// Description: constructor
+//
+// Parameters: name - the name of the object
+//
+// Return: N/A.
+//
+//==============================================================================
+Show::Show( const tName& name ):
+ Chainable1( name )
+{
+ //nothing
+}
+
+//==============================================================================
+// Show::Activate
+//==============================================================================
+// Description: this gets called when a show transition is triggered
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+void Show::Activate()
+{
+ Transition::Activate();
+ rAssert( m_Drawable != NULL );
+ if( m_Drawable != NULL )
+ {
+ m_Drawable->SetVisible( true );
+ }
+ ContinueChain();
+}
+
+
+//==============================================================================
+// Spin::Spin
+//==============================================================================
+// Description: Constructor
+//
+// Parameters: none
+//
+// Return: N/A.
+//
+//==============================================================================
+Spin::Spin():
+ Transition( "Spin" ),
+ m_Period( 1.0f )
+{
+ //nothing
+}
+
+//==============================================================================
+// Spin::MovesDrawable
+//==============================================================================
+// Description: does this transition move a drawable object?
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+bool Spin::MovesDrawable() const
+{
+ return true;
+}
+
+//==============================================================================
+// Spin::SetPeriod
+//==============================================================================
+// Description: Sets the period of the spinning object
+//
+// Parameters: period - float time in seconds for the period
+//
+// Return: N/A.
+//
+//==============================================================================
+void Spin::SetDrawable( Scrooby::Drawable* drawable )
+{
+ Transition::SetDrawable( drawable );
+ m_BoundedDrawable = dynamic_cast< Scrooby::BoundedDrawable* >( drawable );
+ rAssert( m_BoundedDrawable != NULL );
+}
+
+//==============================================================================
+// Spin::SetPeriod
+//==============================================================================
+// Description: Sets the period of the spinning object
+//
+// Parameters: period - float time in seconds for the period
+//
+// Return: N/A.
+//
+//==============================================================================
+void Spin::SetPeriod( const float period )
+{
+ m_Period = period;
+}
+
+//==============================================================================
+// Spin::Update
+//==============================================================================
+// Description: Does the animation
+//
+// Parameters: deltaT - elapsed time
+//
+// Return: N/A.
+//
+//==============================================================================
+void Spin::Update( const float deltaT )
+{
+ if( IsActive() )
+ {
+ Transition::Update( deltaT );
+ m_ElapsedTime = fmodf( m_ElapsedTime, m_Period * 1000.0f );
+ float angle = m_ElapsedTime / ( m_Period * 1000 ) * 360.0f;
+ if( m_BoundedDrawable != NULL )
+ {
+ m_BoundedDrawable->RotateAboutCenter( angle );
+ }
+ }
+}
+
+//==============================================================================
+// Transition::Transition
+//==============================================================================
+// Description: constructor
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+Transition::Transition():
+#ifdef RAD_DEBUG
+ m_Name( "NONE" ),
+#endif
+ m_Active( false ),
+ m_Done( false ),
+ m_Drawable( NULL ),
+ m_ElapsedTime( 0.0f )
+{
+#ifdef RAD_DEBUG
+ static int count = 0;
+ m_Id = count;
+ ++count;
+#endif
+}
+
+//==============================================================================
+// Transition::Transition
+//==============================================================================
+// Description: constructor
+//
+// Parameters: name - the name to assign - only in debug builds.
+//
+// Return: N/A.
+//
+//==============================================================================
+Transition::Transition( const tName& name ):
+ m_Active( false ),
+ m_Done( false ),
+ m_Drawable( NULL ),
+ m_ElapsedTime( 0.0f )
+{
+#ifdef RAD_DEBUG
+ m_Name = name;
+#endif
+}
+
+//==============================================================================
+// Transition::Activate
+//==============================================================================
+// Description: activates the transition
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+void Transition::Activate()
+{
+ #ifdef RAD_DEBUG
+ //rAssert( m_Name != "NONE" );
+ if( m_Name.GetUID() != static_cast< tUID >( 0 ) )
+ {
+ const char* name = m_Name.GetText();
+ rDebugPrintf( "Transition Starting - %s\n", name );
+ }
+ #endif
+
+ m_Active = true;
+ m_Done = false;
+ Update( 0.0f );
+}
+
+//==============================================================================
+// Transition::Deactivate
+//==============================================================================
+// Description: deactivates the transition
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+void Transition::Deactivate()
+{
+ m_Active = false;
+ m_Done = true;
+}
+
+//==============================================================================
+// Transition::GetDrawable
+//==============================================================================
+// Description: returns the drawable associated with this transition
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+Scrooby::Drawable* Transition::GetDrawable()
+{
+ return m_Drawable;
+}
+
+//==============================================================================
+// Transition::IsActive
+//==============================================================================
+// Description: queries whether or not the transition is active
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+bool Transition::IsActive() const
+{
+ return m_Active;
+}
+
+//==============================================================================
+// Transition::IsDone
+//==============================================================================
+// Description: queries whether or not the transition is done
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+bool Transition::IsDone() const
+{
+ return m_Done;
+}
+
+//==============================================================================
+// Transition::MovesDrawable
+//==============================================================================
+// Description: does this transition move a drawable object?
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+bool Transition::MovesDrawable() const
+{
+ return false;
+}
+
+//==============================================================================
+// Transition::operator=
+//==============================================================================
+// Description: assignment operator
+//
+// Parameters: right - what we're assigning
+//
+// Return: N/A.
+//
+//==============================================================================
+Transition& Transition::operator=( const Transition& right )
+{
+ if( this == &right)
+ {
+ return *this;
+ }
+ m_Active = right.m_Active;
+ m_Drawable = right.m_Drawable;
+ m_ElapsedTime = right.m_ElapsedTime;
+ return *this;
+}
+
+//==============================================================================
+// Transition::Reset
+//==============================================================================
+// Description: resets the transition to it's 0 time state
+//
+// Parameters: None
+//
+// Return: N/A.
+//
+//==============================================================================
+void Transition::Reset()
+{
+ m_ElapsedTime = 0;
+ m_Done = false;
+}
+
+//==============================================================================
+// Transition::SetDrawable
+//==============================================================================
+// Description: sets the drawable that this transition will apply to
+//
+// Parameters: drawable - the drawable
+//
+// Return: N/A.
+//
+//==============================================================================
+void Transition::SetDrawable( Scrooby::Drawable* drawable )
+{
+ m_Drawable = drawable;
+}
+
+//==============================================================================
+// Transition::SetDrawable
+//==============================================================================
+// Description: sets the drawable that this transition will apply to
+//
+// Parameters: drawable - the drawable
+//
+// Return: N/A.
+//
+//==============================================================================
+void Transition::SetDrawable( Scrooby::Drawable& drawable )
+{
+ m_Drawable = &drawable;
+}
+
+//=============================================================================
+// Transition::Update
+//=============================================================================
+// Description: applies the transition to the front end element being modified
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//=============================================================================
+void Transition::Update( const float elapsedTime )
+{
+ if( !IsActive() )
+ {
+ return;
+ }
+
+ //rDebugPrintf( "%s\n", m_Name.GetText() );
+
+ m_ElapsedTime += elapsedTime;
+}
+
+//=============================================================================
+// Transition::Watch
+//=============================================================================
+// Description: adds a function to thw watcher to enable/disable this
+// transition
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//=============================================================================
+#ifdef DEBUGWATCH
+void Transition::Watch( const char* nameSpace )
+{
+ char output[ 1024 ];
+ sprintf( output, "%s\\%s", nameSpace, m_Name.GetText() );
+ radDbgWatchDelete( &m_DummyVariableForActivate );
+ radDbgWatchDelete( &m_DummyVariableForDeactivate );
+ radDbgWatchAddBoolean( &m_DummyVariableForActivate, "Activate", output, ActivateCallback, this );
+ radDbgWatchAddBoolean( &m_DummyVariableForDeactivate, "Deativate", output, DeativateCallback, this );
+}
+#endif
+
+
+//==============================================================================
+// Translator::Translator
+//==============================================================================
+// Description: constructor
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+Translator::Translator():
+ startX( 0 ),
+ startY( 0 ),
+ endX( 0 ),
+ endY( 0 )
+{
+ //nothing
+}
+
+//==============================================================================
+// Translator::Translator
+//==============================================================================
+// Description: constructor
+//
+// Parameters: name - name of the object
+//
+// Return: N/A.
+//
+//==============================================================================
+Translator::Translator( const tName& name ):
+ Chainable1( name ),
+ startX( 0 ),
+ startY( 0 ),
+ endX( 0 ),
+ endY( 0 )
+{
+}
+
+//==============================================================================
+// Translator::~Translator
+//==============================================================================
+// Description: destructor
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+Translator::~Translator()
+{
+ //nothing
+}
+
+//=============================================================================
+// Translator::MateCoordsEnd
+//=============================================================================
+// Description: match up the end coordinates of the transition with where the
+// scrooby object is supposed to be
+//
+// Parameters: drawable - the object to match up with
+//
+// Return: N/A.
+//
+//=============================================================================
+void Translator::MateCoordsEnd( const Scrooby::HasBoundingBox* drawable )
+{
+ SetCoordsEnd( 0, 0 );
+}
+
+//=============================================================================
+// Translator::MateCoordsStart
+//=============================================================================
+// Description: match up the start coordinates of the transition with where the
+// scrooby object is supposed to be
+//
+// Parameters: drawable - the object to match up with
+//
+// Return: N/A.
+//
+//=============================================================================
+void Translator::MateCoordsStart( const Scrooby::HasBoundingBox* drawable )
+{
+ SetCoordsStart( 0, 0 );
+}
+
+//==============================================================================
+// Translator::MovesDrawable
+//==============================================================================
+// Description: does this transition move a drawable object?
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+bool Translator::MovesDrawable() const
+{
+ return true;
+}
+
+//==============================================================================
+// Translator::operator=
+//==============================================================================
+// Description: assignment operator
+//
+// Parameters: right - what we're being assigned
+//
+// Return: reference to self
+//
+//==============================================================================
+Translator& Translator::operator=( const Translator& right )
+{
+ if( this == &right )
+ {
+ return *this;
+ }
+
+ Chainable1::operator=( right );
+
+ startX = right.startX;
+ startY = right.startY;
+ endX = right.endX;
+ endY = right.endY;
+ m_TimeInterval = right.m_TimeInterval;
+ return *this;
+}
+
+//==============================================================================
+// Translator::SetEndCoords
+//==============================================================================
+// Description: sets the ending position of the object
+//
+// Parameters: x, y, the coords
+//
+// Return: N/A.
+//
+//==============================================================================
+void Translator::SetCoordsEnd( const int x, const int y )
+{
+ endX = x;
+ endY = y;
+}
+
+//==============================================================================
+// Translator::SetStartCoords
+//==============================================================================
+// Description: sets the starting position of the object
+//
+// Parameters: x, y, the coords
+//
+// Return: N/A.
+//
+//==============================================================================
+void Translator::SetCoordsStart( const int x, const int y )
+{
+ startX = x;
+ startY = y;
+}
+
+//==============================================================================
+// Translator::SetEndOffscreenBottom
+//==============================================================================
+// Description: positions the transition to end the object offscreen to the bottom
+//
+// Parameters: drawable - the drawable to line up offscreen with
+//
+// Return: N/A.
+//
+//==============================================================================
+void Translator::SetEndOffscreenBottom( const Scrooby::Drawable* drawable )
+{
+ int xMin;
+ int xMax;
+ int yMin;
+ int yMax;
+ drawable->GetBoundingBox( xMin, yMin, xMax, yMax );
+ #ifdef RAD_PS2
+ SetCoordsEnd( 0, -20 -yMax );
+ #else
+ SetCoordsEnd( 0, -yMax );
+ #endif
+}
+
+//==============================================================================
+// Translator::SetEndOffscreenLeft
+//==============================================================================
+// Description: positions the transition to end the object offscreen to the left
+//
+// Parameters: drawable - the drawable to line up offscreen with
+//
+// Return: N/A.
+//
+//==============================================================================
+void Translator::SetEndOffscreenLeft( const Scrooby::Drawable* drawable )
+{
+ int xMin;
+ int xMax;
+ int yMin;
+ int yMax;
+ drawable->GetBoundingBox( xMin, yMin, xMax, yMax );
+ int width = xMax - xMin;
+
+ if( p3d::display->IsWidescreen() )
+ {
+ SetCoordsEnd( -xMin - width - WIDESCREEN_EXTRA_PIXELS, 0 );
+ }
+ else
+ {
+ SetCoordsEnd( -xMin - width, 0 );
+ }
+}
+//==============================================================================
+// Translator::SetEndOffscreenRight
+//==============================================================================
+// Description: positions the transition to end the object offscreen to the right
+//
+// Parameters: drawable - the drawable to line up offscreen with
+//
+// Return: N/A.
+//
+//==============================================================================
+void Translator::SetEndOffscreenRight( const Scrooby::Drawable* drawable )
+{
+ int xMin;
+ int xMax;
+ int yMin;
+ int yMax;
+ drawable->GetBoundingBox( xMin, yMin, xMax, yMax );
+ int width = xMax - xMin;
+ if( p3d::display->IsWidescreen() )
+ {
+ SetCoordsEnd( 640 - xMin + WIDESCREEN_EXTRA_PIXELS, 0 );
+ }
+ else
+ {
+ SetCoordsEnd( 640 - xMin, 0 );
+ }
+}
+
+//==============================================================================
+// Translator::SetEndOffscreenTop
+//==============================================================================
+// Description: positions the transition to end the object offscreen to the left
+//
+// Parameters: drawable - the drawable to line up offscreen with
+//
+// Return: N/A.
+//
+//==============================================================================
+void Translator::SetEndOffscreenTop( const Scrooby::Drawable* drawable )
+{
+ int xMin;
+ int xMax;
+ int yMin;
+ int yMax;
+ drawable->GetBoundingBox( xMin, yMin, xMax, yMax );
+ #ifdef RAD_PS2
+ SetCoordsEnd( 0, 480 + 20 - yMin );
+ #else
+ SetCoordsEnd( 0, 480 - yMin );
+ #endif
+}
+
+//==============================================================================
+// Translator::SetStartOffscreenBottom
+//==============================================================================
+// Description: positions the transition to start the object offscreen to the bottom
+//
+// Parameters: drawable - the drawable to line up offscreen with
+//
+// Return: N/A.
+//
+//==============================================================================
+void Translator::SetStartOffscreenBottom ( const Scrooby::Drawable* drawable )
+{
+ int xMin;
+ int xMax;
+ int yMin;
+ int yMax;
+ drawable->GetBoundingBox( xMin, yMin, xMax, yMax );
+
+ #ifdef RAD_PS2
+ SetCoordsStart( 0, -20 -yMax );
+ #else
+ SetCoordsStart( 0, -yMax );
+ #endif
+
+}
+
+//==============================================================================
+// Translator::SetTimeInterval
+//==============================================================================
+// Description: positions the transition to start the object offscreen to the left
+//
+// Parameters: drawable - the drawable to line up offscreen with
+//
+// Return: N/A.
+//
+//==============================================================================
+void Translator::SetStartOffscreenLeft( const Scrooby::Drawable* drawable )
+{
+ int xMin;
+ int xMax;
+ int yMin;
+ int yMax;
+ drawable->GetBoundingBox( xMin, yMin, xMax, yMax );
+ int width = xMax - xMin;
+
+ if( p3d::display->IsWidescreen() )
+ {
+ SetCoordsStart( -xMin - width - WIDESCREEN_EXTRA_PIXELS, 0 );
+ }
+ else
+ {
+ SetCoordsStart( -xMin - width, 0 );
+ }
+}
+//==============================================================================
+// Translator::SetStartOffscreenRight
+//==============================================================================
+// Description: positions the transition to start the object offscreen to the right
+//
+// Parameters: drawable - the drawable to line up offscreen with
+//
+// Return: N/A.
+//
+//==============================================================================
+void Translator::SetStartOffscreenRight ( const Scrooby::Drawable* drawable )
+{
+ int xMin;
+ int xMax;
+ int yMin;
+ int yMax;
+ drawable->GetBoundingBox( xMin, yMin, xMax, yMax );
+ int width = xMax - xMin;
+ if( p3d::display->IsWidescreen() )
+ {
+ SetCoordsStart( 640 - xMin + WIDESCREEN_EXTRA_PIXELS, 0 );
+ }
+ else
+ {
+ SetCoordsStart( 640 - xMin, 0 );
+ }
+}
+
+//==============================================================================
+// Translator::SetStartOffscreenTop
+//==============================================================================
+// Description: positions the transition to start the object offscreen to the top
+//
+// Parameters: drawable - the drawable to line up offscreen with
+//
+// Return: N/A.
+//
+//==============================================================================
+void Translator::SetStartOffscreenTop( const Scrooby::Drawable* drawable )
+{
+ int xMin;
+ int xMax;
+ int yMin;
+ int yMax;
+ drawable->GetBoundingBox( xMin, yMin, xMax, yMax );
+ SetCoordsStart( 0, 480 - yMin );
+ #ifdef RAD_PS2
+ SetCoordsStart( 0, 480 + 20 - yMin );
+ #else
+ SetCoordsStart( 0, 480 - yMin );
+ #endif
+
+}
+
+//==============================================================================
+// Translator::Apply
+//==============================================================================
+// Description: applies the transition to the front end element being modified
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+void Translator::Update( const float deltaT )
+{
+ if( IsActive() )
+ {
+ Transition::Update( deltaT );
+ float spillover = rmt::Max( m_ElapsedTime - m_TimeInterval, 0.0f );
+ m_ElapsedTime = rmt::Min( m_ElapsedTime, m_TimeInterval );
+
+ float percentDone = rmt::Min( m_ElapsedTime / m_TimeInterval, 1.0f );
+ int x = static_cast< int >( ( endX - startX ) * percentDone + startX );
+ int y = static_cast< int >( ( endY - startY ) * percentDone + startY );
+ if( m_Drawable != NULL )
+ {
+ m_Drawable->Translate( x, y );
+ }
+
+ if( spillover > 0 )
+ {
+ ContinueChain();
+ }
+ }
+}
+
+//==============================================================================
+// Translator::Watch
+//==============================================================================
+// Description: Adds this transition to the watcher
+//
+// Parameters: nameSpace - the name of the group in the watcher
+//
+// Return: N/A.
+//
+//==============================================================================
+#ifdef DEBUGWATCH
+void Translator::Watch( const char* nameSpace )
+{
+ char output[ 1024 ];
+ sprintf( output, "%s\\%s", nameSpace, m_Name.GetText() );
+ Parent1::Watch( nameSpace );
+ Parent2::Watch( output ); //HasTimeInterval doesn't know the name.
+ radDbgWatchDelete( &startX );
+ radDbgWatchDelete( &startY );
+ radDbgWatchDelete( &endX );
+ radDbgWatchDelete( &endY );
+ radDbgWatchAddShort( &startX, "startX", output, NULL, NULL, -640, 640 * 2 );
+ radDbgWatchAddShort( &startY, "startY", output, NULL, NULL, -640, 640 * 2 );
+ radDbgWatchAddShort( &endX, "endX", output, NULL, NULL, -640, 640 * 2 );
+ radDbgWatchAddShort( &endY, "endY", output, NULL, NULL, -640, 640 * 2 );
+}
+#endif
+
+//==============================================================================
+// UnderdampedTranslator::UnderdampedTranslator
+//==============================================================================
+// Description: constructor
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+UnderdampedTranslator::UnderdampedTranslator():
+ Translator()
+{
+}
+
+//==============================================================================
+// UnderdampedTranslator::UnderdampedTranslator
+//==============================================================================
+// Description: constructor
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+UnderdampedTranslator::UnderdampedTranslator( const tName& name ):
+ Translator( name )
+{
+}
+
+//==============================================================================
+// UnderdampedTranslator::MovesDrawable
+//==============================================================================
+// Description: does this transition move a drawable object?
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+bool UnderdampedTranslator::MovesDrawable() const
+{
+ return true;
+}
+
+//==============================================================================
+// UnderdampedTranslator::SetFrequency
+//==============================================================================
+// Description: sets the frequency of oscillation of the underdamped translator
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+void UnderdampedTranslator::SetFrequency( const float frequency )
+{
+ m_Frequency = frequency;
+}
+
+//==============================================================================
+// UnderdampedTranslator::Update
+//==============================================================================
+// Description: updates the object that we're translating
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+void UnderdampedTranslator::Update( const float deltaT )
+{
+ if( IsActive() )
+ {
+ Transition::Update( deltaT );
+ float spillover = rmt::Max( m_ElapsedTime - m_TimeInterval, 0.0f );
+ m_ElapsedTime = rmt::Min( m_ElapsedTime, m_TimeInterval );
+ float decayRate = logf( 0.01f ) / m_TimeInterval;
+ float exponentialPart = expf( decayRate * m_ElapsedTime );
+ float cosinePart = cosf( 2.0f * rmt::PI * m_Frequency * m_ElapsedTime / 1000.0f );
+ float percentage = 1.0f - exponentialPart * cosinePart;
+ int x = static_cast< int >( ( endX - startX ) * percentage + startX );
+ int y = static_cast< int >( ( endY - startY ) * percentage + startY );
+ m_Drawable->Translate( x, y );
+
+ if( spillover > 0 )
+ {
+ ContinueChain();
+ }
+ }
+}
+
+} \ No newline at end of file
diff --git a/game/code/presentation/gui/utility/transitions.h b/game/code/presentation/gui/utility/transitions.h
new file mode 100644
index 0000000..f00b1b9
--- /dev/null
+++ b/game/code/presentation/gui/utility/transitions.h
@@ -0,0 +1,592 @@
+//===========================================================================
+// Copyright (C) 2000 Radical Entertainment Ltd. All rights reserved.
+//
+// Component: SpecialFX
+//
+// Description:
+//
+//
+// Authors: Tony Chu
+//
+// Revisions Date Author Revision
+// 2002/08/30 TChu Created for SRR2
+//
+//===========================================================================
+
+#ifndef TRANSITIONS_H
+#define TRANSITIONS_H
+
+//===========================================================================
+// Nested Includes
+//===========================================================================
+#include <p3d/entity.hpp>
+#include "events/eventenum.h"
+#include "events/eventlistener.h"
+#include <input/controller.h>
+#include <gameflow/gameflow.h>
+#include <presentation/gui/guiwindow.h>
+
+//===========================================================================
+// Forward References
+//===========================================================================
+
+namespace Scrooby
+{
+ class Drawable;
+ class BoundedDrawable;
+ class HasBoundingBox;
+ class Sprite;
+}
+
+class tMultiController;
+//===========================================================================
+// Interface Definitions
+//===========================================================================
+
+namespace GuiSFX
+{
+#ifdef DEBUGWATCH
+ #define WATCH( object, nameSpace ) object.Watch( nameSpace )
+#else
+ #define WATCH( object, nameSpace )
+#endif
+
+#ifdef DEBUGWATCH
+ void ActivateCallback ( void* userData );
+ void DeactivateCallback( void* userData );
+#endif
+//==============================================================================
+// Transition
+//==============================================================================
+class Transition
+{
+public:
+ Transition();
+ Transition( const tName& name );
+ virtual void Activate();
+ virtual void Deactivate();
+ Scrooby::Drawable* GetDrawable();
+ bool IsActive() const;
+ bool IsDone() const;
+ virtual bool MovesDrawable() const;
+ Transition& operator=( const Transition& right );
+ virtual void Reset();
+ virtual void SetDrawable( Scrooby::Drawable* drawable );
+ virtual void SetDrawable( Scrooby::Drawable& drawable );
+ virtual void Update( const float deltaT );
+
+ #ifdef DEBUGWATCH
+ virtual void Watch( const char* nameSpace );
+ #endif
+
+protected:
+#ifdef DEBUGWATCH
+ tName m_Name;
+ int m_Id;
+ bool m_DummyVariableForActivate;
+ bool m_DummyVariableForDeactivate;
+#endif
+ bool m_Active : 1;
+ bool m_Done : 1;
+ Scrooby::Drawable* m_Drawable;
+ float m_ElapsedTime;
+};
+
+//==============================================================================
+// Chainable
+//==============================================================================
+class Chainable : public Transition
+{
+public:
+ Chainable();
+ Chainable( const tName& name );
+ virtual void ContinueChain() = 0;
+ virtual void DeactivateChain() = 0;
+ virtual bool IsChainDone() const = 0;
+ virtual void ResetChain() = 0;
+protected:
+};
+
+//==============================================================================
+// Chainable1 - these transitions can be chained together temporally
+//==============================================================================
+class Chainable1 : public Chainable
+{
+private:
+ typedef Chainable Parent;
+public:
+ Chainable1();
+ Chainable1( const tName& name );
+ Chainable1& operator=( const Chainable1& right );
+ virtual void ContinueChain();
+ virtual void DeactivateChain();
+ virtual bool IsChainDone() const;
+ virtual void ResetChain();
+ void SetNextTransition( Chainable* transition );
+ void SetNextTransition( Chainable& transition );
+protected:
+ Chainable* m_NextTransition;
+};
+
+//==============================================================================
+// Chainable2 - one transition that spawns 2 others at the same time
+//==============================================================================
+class Chainable2 : public Chainable
+{
+public:
+ Chainable2();
+ Chainable2( const tName& name );
+ virtual void ContinueChain();
+ virtual void DeactivateChain();
+ virtual bool IsChainDone() const;
+ virtual void ResetChain();
+ void SetNextTransition( const unsigned int index, Chainable* transition );
+ void SetNextTransition( const unsigned int index, Chainable& transition );
+
+protected:
+ Chainable* m_NextTransition[ 2 ];
+};
+
+//==============================================================================
+// Chainable3 - one transition that spawns 3 others at the same time
+//==============================================================================
+//Ian - this should be a templatized class...
+class Chainable3 : public Chainable
+{
+public:
+ Chainable3();
+ Chainable3( const tName& name );
+ virtual void ContinueChain();
+ virtual void DeactivateChain();
+ virtual bool IsChainDone() const;
+ virtual void ResetChain();
+ void SetNextTransition( const unsigned int index, Chainable* transition );
+ void SetNextTransition( const unsigned int index, Chainable& transition );
+
+protected:
+ Chainable* m_NextTransition[ 3 ];
+};
+
+//==============================================================================
+// Junction2
+//==============================================================================
+class Junction2 : public Chainable2
+{
+public:
+ void Activate();
+protected:
+};
+
+//==============================================================================
+// Junction3
+//==============================================================================
+//IAN - this should be a templatized class too
+class Junction3 : public Chainable3
+{
+public:
+ void Activate();
+protected:
+};
+
+//==============================================================================
+// Dummy - this "transition" does nothing. it's a placeholder
+//==============================================================================
+class Dummy : public Chainable1
+{
+private:
+ typedef Chainable1 Parent;
+public:
+ Dummy();
+ Dummy( const tName& name );
+ void Activate();
+};
+
+//==============================================================================
+// GotoScreen
+//==============================================================================
+class GotoScreen : public Chainable1
+{
+private:
+ typedef Chainable1 Parent;
+public:
+ GotoScreen();
+ GotoScreen( const tName& name );
+ void Activate();
+ void SetEventData( void* eventData );
+ void SetParam1( const unsigned int param1 );
+ void SetParam2( const unsigned int param2 );
+ void SetScreen( CGuiWindow::eGuiWindowID screen );
+ void SetWindowOptions( const unsigned int windowOptions );
+
+protected:
+ CGuiWindow::eGuiWindowID mScreen;
+ unsigned int mParam1;
+ unsigned int mParam2;
+ void* mEventData;
+ unsigned int mWindowOptions;
+};
+
+
+//==============================================================================
+// Hide
+//==============================================================================
+class Hide : public Chainable1
+{
+public:
+ Hide();
+ Hide( const tName& name );
+ void Activate();
+
+protected:
+};
+
+//==============================================================================
+// InputStateChange
+//==============================================================================
+class InputStateChange : public Chainable1
+{
+private:
+ typedef Chainable1 Parent;
+public:
+ InputStateChange();
+ InputStateChange( const tName& name );
+ void Activate();
+ void SetState( const Input::ActiveState state );
+protected:
+private:
+ Input::ActiveState mState;
+};
+
+//==============================================================================
+// RecieveEvent
+//==============================================================================
+class RecieveEvent :
+ public Chainable1,
+ public EventListener
+{
+public:
+ RecieveEvent();
+ RecieveEvent( const tName& name );
+ void Activate();
+ virtual void HandleEvent( EventEnum id, void* pEventData );
+ void SetEvent( const EventEnum event );
+protected:
+private:
+ EventEnum mEvent;
+};
+
+//==============================================================================
+// SendEvent
+//==============================================================================
+class SendEvent : public Chainable1
+{
+public:
+ SendEvent();
+ SendEvent( const tName& name );
+ void Activate();
+ void SetEvent( EventEnum event );
+ void SetEventData( void* eventData );
+
+protected:
+ EventEnum mEvent;
+ void* mEventData;
+};
+
+//==============================================================================
+// SwitchContext
+//==============================================================================
+class SwitchContext : public Chainable1
+{
+private:
+ typedef Chainable1 Parent;
+public:
+ SwitchContext();
+ SwitchContext( const tName& name );
+ void Activate();
+ void SetContext( ContextEnum event );
+
+protected:
+ ContextEnum mContext;
+};
+
+//==============================================================================
+// HasMulticontroller
+//==============================================================================
+class HasMulticontroller
+{
+public:
+ void SetMultiController( tMultiController* multicontroller );
+protected:
+ void ResetMultiControllerFrames();
+
+ tMultiController* m_MultiController;
+ float m_NumFrames;
+};
+
+//==============================================================================
+// HasMulticontroller
+//==============================================================================
+class HasTimeInterval
+{
+public:
+ HasTimeInterval();
+ void SetTimeInterval( const float interval );
+ #ifdef DEBUGWATCH
+ virtual void Watch( const char* nameSpace );
+ #endif
+
+protected:
+ float m_TimeInterval;
+};
+
+//==============================================================================
+// ColorChange
+//==============================================================================
+class ColorChange :
+ public Chainable1,
+ public HasTimeInterval
+{
+private:
+ typedef Chainable1 Parent1;
+ typedef HasTimeInterval Parent2;
+public:
+ ColorChange();
+ ColorChange( const tName& name );
+ void SetStartColour( const tColour c );
+ void SetEndColour( const tColour c );
+ void Update( const float deltaT );
+ #ifdef DEBUGWATCH
+ virtual void Watch( const char* nameSpace );
+ #endif
+
+protected:
+ tColour m_StartColor;
+ tColour m_EndColor;
+};
+
+//==============================================================================
+// IrisWipeClose
+//==============================================================================
+class IrisWipeOpen
+ : public Chainable1,
+ public HasMulticontroller
+
+{
+ //this class doesn't even need a drawable really
+public:
+ IrisWipeOpen();
+ IrisWipeOpen( const tName& name );
+ void Activate();
+ void Update( const float deltaT );
+protected:
+};
+
+//==============================================================================
+// IrisWipeOpen
+//==============================================================================
+class IrisWipeClose
+ : public Chainable1,
+ public HasMulticontroller
+{
+ //this class doesn't even need a drawable really
+public:
+ IrisWipeClose();
+ IrisWipeClose( const tName& name );
+ void Activate();
+ void Deactivate();
+ void Update( const float deltaT );
+protected:
+};
+
+//==============================================================================
+// Show
+//==============================================================================
+class Show : public Chainable1
+{
+public:
+ Show();
+ Show( const tName& name );
+ void Activate();
+
+protected:
+};
+
+//=============================================================================
+// Pause
+//=============================================================================
+class Pause :
+ public Chainable1,
+ public HasTimeInterval
+{
+private:
+ typedef Chainable1 Parent1;
+ typedef HasTimeInterval Parent2;
+
+public:
+ Pause();
+ Pause( const tName& name );
+ void Update( const float deltaT );
+ #ifdef DEBUGWATCH
+ virtual void Watch( const char* nameSpace );
+ #endif
+protected:
+};
+
+//=============================================================================
+// PauseInFrames
+//=============================================================================
+class PauseInFrames :
+ public Chainable1
+{
+private:
+ typedef Chainable1 Parent;
+public:
+ PauseInFrames();
+ PauseInFrames( const tName& name );
+ void Reset();
+ void SetNumberOfFrames( const unsigned int i );
+ void Update( const float deltaT );
+protected:
+ unsigned int m_FramesToPause;
+ unsigned int m_FramesElapsed;
+};
+
+//==============================================================================
+// PauseGame
+//==============================================================================
+class PauseGame :
+ public Chainable1
+{
+ void Activate();
+};
+
+//==============================================================================
+// ResumeGame
+//==============================================================================
+class ResumeGame :
+ public Chainable1
+{
+public:
+ ResumeGame();
+ ResumeGame( const tName& name );
+ void Activate();
+};
+
+//==============================================================================
+// ImageCycler - causes images to cycle forever
+//==============================================================================
+class ImageCycler : public Transition
+{
+public:
+ void SetDrawable( Scrooby::Drawable* drawable );
+ void SetDrawable( Scrooby::Drawable& drawable );
+ void SetPeriod( const float period );
+ void Update( const float deltaT );
+protected:
+ float m_Period;
+ Scrooby::Sprite* m_Sprite; //this is a waste of memory
+};
+
+//==============================================================================
+// Pulse - pulses the scale of the image about its center
+//==============================================================================
+class PulseScale : public Transition
+{
+private:
+ typedef Transition Parent;
+public:
+ PulseScale();
+ PulseScale( const tName& name );
+ virtual bool MovesDrawable() const;
+ void SetAmplitude( const float amplitude );
+ void SetDrawable( Scrooby::Drawable* drawable );
+ void SetDrawable( Scrooby::Drawable& drawable );
+ void SetFrequency( const float frequency );
+ void Update( const float deltaT );
+
+ #ifdef DEBUGWATCH
+ virtual void Watch( const char* nameSpace );
+ #endif
+
+protected:
+ Scrooby::HasBoundingBox* m_BoundedDrawable;
+ float m_Amplitude;
+ float m_Frequency;
+};
+
+//==============================================================================
+// Spin - causes the object to spin about its center forever
+//==============================================================================
+class Spin : public Transition
+{
+public:
+ Spin();
+ virtual bool MovesDrawable() const;
+ void SetDrawable( Scrooby::Drawable* drawable );
+ void SetPeriod( const float period );
+ void Update( const float deltaT );
+protected:
+ float m_Period;
+ Scrooby::BoundedDrawable* m_BoundedDrawable;
+};
+
+//==============================================================================
+// Translator
+//==============================================================================
+class Translator :
+ public Chainable1,
+ public HasTimeInterval
+{
+private:
+ typedef Chainable Parent1;
+ typedef HasTimeInterval Parent2;
+
+public:
+ Translator();
+ Translator( const tName& name );
+ Translator( const Translator& right );
+ ~Translator();
+ void MateCoordsEnd( const Scrooby::HasBoundingBox* drawable );
+ void MateCoordsStart( const Scrooby::HasBoundingBox* drawable );
+ virtual bool MovesDrawable() const;
+ Translator& operator=( const Translator& right );
+ void SetCoordsEnd ( const int x, const int y );
+ void SetCoordsStart( const int x, const int y );
+ void SetEndOffscreenBottom ( const Scrooby::Drawable* drawable );
+ void SetEndOffscreenLeft ( const Scrooby::Drawable* drawable );
+ void SetEndOffscreenRight ( const Scrooby::Drawable* drawable );
+ void SetEndOffscreenTop ( const Scrooby::Drawable* drawable );
+ void SetStartOffscreenBottom ( const Scrooby::Drawable* drawable );
+ void SetStartOffscreenLeft ( const Scrooby::Drawable* drawable );
+ void SetStartOffscreenRight ( const Scrooby::Drawable* drawable );
+ void SetStartOffscreenTop ( const Scrooby::Drawable* drawable );
+ void Update( const float deltaT );
+ #ifdef DEBUGWATCH
+ virtual void Watch( const char* nameSpace );
+ #endif
+
+protected:
+ short int startX;
+ short int startY;
+ short int endX;
+ short int endY;
+};
+
+//==============================================================================
+// Translator - with a springy type of effect.
+//==============================================================================
+class UnderdampedTranslator : public Translator
+{
+public:
+ UnderdampedTranslator();
+ UnderdampedTranslator( const tName& name );
+ virtual bool MovesDrawable() const;
+ void SetFrequency( const float frequency );
+ void Update( const float deltaT );
+protected:
+ float m_Frequency;
+};
+
+} // GuiSFX namespace
+
+#endif // TRANSITIONS_H
diff --git a/game/code/presentation/language.cpp b/game/code/presentation/language.cpp
new file mode 100644
index 0000000..d8eaf00
--- /dev/null
+++ b/game/code/presentation/language.cpp
@@ -0,0 +1,181 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: language.cpp
+//
+// Description: contains functions for dealing with language
+//
+// History: 21/1/2002 + Created -- Ian Gipson
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+#ifdef RAD_PS2
+ #include <libscf.h>
+#endif
+
+#ifdef RAD_GAMECUBE
+ #include <dolphin/os.h>
+#endif
+
+#ifdef RAD_XBOX
+ #include <xtl.h>
+#endif
+//========================================
+// Project Includes
+//========================================
+
+#include <presentation/language.h>
+
+//*****************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// Public Member Functions
+//
+//*****************************************************************************
+namespace Language{
+
+//=============================================================================
+// Language::GetHardwareLanguage()
+//=============================================================================
+// Description: returns the currently set language for the console.
+//
+// Parameters: None.
+//
+// Return: Language enum specifying the current language
+//
+//=============================================================================
+Language GetHardwareLanguage()
+{
+ #ifdef RAD_PS2
+ ////////////////////////////////////////////////////////////
+ // PS2
+ ////////////////////////////////////////////////////////////
+ switch ( sceScfGetLanguage() )
+ {
+ case SCE_DUTCH_LANGUAGE :
+ {
+ return DUTCH;
+ }
+ case SCE_ENGLISH_LANGUAGE :
+ {
+ return ENGLISH;
+ }
+ case SCE_FRENCH_LANGUAGE :
+ {
+ return FRENCH;
+ }
+ case SCE_GERMAN_LANGUAGE :
+ {
+ return GERMAN;
+ }
+ case SCE_ITALIAN_LANGUAGE :
+ {
+ return ITALIAN;
+ }
+ case SCE_JAPANESE_LANGUAGE :
+ {
+ return JAPANESE;
+ }
+ case SCE_PORTUGUESE_LANGUAGE :
+ {
+ return PORTUGUESE;
+ }
+ case SCE_SPANISH_LANGUAGE :
+ {
+ return SPANISH;
+ }
+ default :
+ {
+ return UNKNOWN;
+ }
+ }
+ #endif
+
+ #ifdef RAD_XBOX
+ ////////////////////////////////////////////////////////////
+ // XBOX
+ ////////////////////////////////////////////////////////////
+ switch ( XGetLanguage() )
+ {
+ case XC_LANGUAGE_ENGLISH :
+ {
+ return ENGLISH;
+ }
+ case XC_LANGUAGE_FRENCH :
+ {
+ return FRENCH;
+ }
+ case XC_LANGUAGE_GERMAN :
+ {
+ return GERMAN;
+ }
+ case XC_LANGUAGE_ITALIAN :
+ {
+ return ITALIAN;
+ }
+ case XC_LANGUAGE_JAPANESE :
+ {
+ return JAPANESE;
+ }
+ case XC_LANGUAGE_SPANISH :
+ {
+ return SPANISH;
+ }
+ default :
+ {
+ return UNKNOWN;
+ }
+ }
+ #endif
+
+ #ifdef RAD_GAMECUBE
+ switch ( OSGetLanguage() )
+ {
+ case OS_LANG_ENGLISH:
+ {
+ return ENGLISH;
+ }
+ case OS_LANG_GERMAN:
+ {
+ return GERMAN;
+ }
+ case OS_LANG_FRENCH:
+ {
+ return FRENCH;
+ }
+ case OS_LANG_SPANISH:
+ {
+ return SPANISH;
+ }
+ case OS_LANG_ITALIAN:
+ {
+ return ITALIAN;
+ }
+ case OS_LANG_DUTCH:
+ {
+ return DUTCH;
+ }
+ default:
+ {
+ return UNKNOWN;
+ }
+ }
+ #endif
+
+ #ifdef RAD_WIN32
+ ////////////////////////////////////////////////////////////
+ // WIN32
+ ////////////////////////////////////////////////////////////
+ return ENGLISH; // to be implemented.
+ #endif
+}
+
+} //namespace Language \ No newline at end of file
diff --git a/game/code/presentation/language.h b/game/code/presentation/language.h
new file mode 100644
index 0000000..e2e1a24
--- /dev/null
+++ b/game/code/presentation/language.h
@@ -0,0 +1,43 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: language.h
+//
+// Description: this file contains the prototypes for functions for getting
+// access to languages that the console is set to
+//
+// History: 21/11/2002 + Created -- Ian Gipson
+//
+//=============================================================================
+
+#ifndef LANGUAGE_H
+#define LANGUAGE_H
+
+//========================================
+// Nested Includes
+//========================================
+
+
+//========================================
+// Forward References
+//========================================
+namespace Language
+{
+ enum Language
+ {
+ ENGLISH,
+ FRENCH,
+ GERMAN,
+ ITALIAN,
+ SPANISH,
+ DUTCH,
+ JAPANESE,
+ PORTUGUESE,
+
+ UNKNOWN
+ };
+
+ Language GetHardwareLanguage();
+}
+
+#endif // LANGUAGE_H
diff --git a/game/code/presentation/mouthflapper.cpp b/game/code/presentation/mouthflapper.cpp
new file mode 100644
index 0000000..ea094d2
--- /dev/null
+++ b/game/code/presentation/mouthflapper.cpp
@@ -0,0 +1,565 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: MouthFlapper.cpp
+//
+// Description: Implement MouthFlapper
+//
+// History: 09/09/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+#include <radmath/trig.hpp>
+#include <radtime.hpp>
+#include <stdlib.h>
+#include <p3d/anim/skeleton.hpp>
+
+//========================================
+// Project Includes
+//========================================
+
+#include <presentation/mouthflapper.h>
+
+#include <worldsim/character/character.h>
+
+#include <choreo/puppet.hpp>
+
+#include <poser/pose.hpp>
+#include <poser/joint.hpp>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+static float MIN_OPEN = -0.10f * rmt::PI;
+static float MAX_OPEN = 0.15f * rmt::PI;
+static float MAX_DEVIATION = 0.04f * rmt::PI;
+static float MIN_SPEED = 1.00f;
+static float MAX_SPEED = 4.00f;
+
+//default settings
+MouthFlapperDefaultSetting gDefaultSetting( "default", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f );
+MouthFlapperDefaultSetting gDefaultSettings[] =
+{
+ MouthFlapperDefaultSetting( "apu", -0.314159f, 0.490973f, 0.13f, 2.20f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "b_cbg", -0.314159f, 0.559204f, 0.13f, 2.44f, 3.88f ), //done
+ MouthFlapperDefaultSetting( "b_cletus", -0.314159f, 0.420973f, 0.13f, 1.88f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "b_frink", -0.314159f, 0.420973f, 0.13f, 1.88f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "b_grandpa",-0.314159f, 0.420973f, 0.136640f, 2.20f, 3.56f ), //done
+ MouthFlapperDefaultSetting("b_milhouse",-0.314159f, 0.521504f, 0.125664f, 2.22f, 4.00f ), //done
+ MouthFlapperDefaultSetting( "b_nelson", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ),
+ MouthFlapperDefaultSetting( "b_ralph", -0.314159f, 0.471504f, 0.125664f, 2.22f, 4.00f ), //done
+ MouthFlapperDefaultSetting( "b_skinner",-0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "b_smithers", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "b_snake", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done
+ MouthFlapperDefaultSetting( "b_zfem1", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ),
+ MouthFlapperDefaultSetting( "b_zmale1", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ),
+ MouthFlapperDefaultSetting( "b_zmale2", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ),
+ MouthFlapperDefaultSetting( "b_zmale3", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ),
+ MouthFlapperDefaultSetting( "brn_unf", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done
+ MouthFlapperDefaultSetting( "barney", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done
+ MouthFlapperDefaultSetting( "bart", -0.314159f, 0.521504f, 0.125664f, 2.50f, 4.00f ), //done
+ MouthFlapperDefaultSetting( "burns", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "captain", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done
+ MouthFlapperDefaultSetting( "carl", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "cbg", -0.314159f, 0.559204f, 0.13f, 2.44f, 3.88f ), //done
+ MouthFlapperDefaultSetting( "cletus", -0.314159f, 0.420973f, 0.13f, 1.88f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "frink", -0.314159f, 0.420973f, 0.13f, 1.88f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "gil", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done
+ MouthFlapperDefaultSetting( "grandpa", -0.314159f, 0.420973f, 0.136640f, 2.20f, 3.56f ), //done
+ MouthFlapperDefaultSetting( "hibbert", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done
+ MouthFlapperDefaultSetting( "homer", -0.314159f, 0.420973f, 0.136640f, 2.00f, 3.44f ), //done
+ MouthFlapperDefaultSetting( "jimbo", -0.314159f, 0.470973f, 0.13f, 1.88f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "joger1", -0.314159f, 0.470973f, 0.13f, 1.88f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "kearney", -0.314159f, 0.521504f, 0.125664f, 2.34f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "krusty", -0.314159f, 0.420973f, 0.136640f, 2.20f, 3.56f ), //done
+ MouthFlapperDefaultSetting( "lenny", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "lisa", -0.314159f, 0.471239f, 0.125664f, 2.5f, 4.00f ), //done
+ MouthFlapperDefaultSetting( "louie", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "marge", -0.314159f, 0.420973f, 0.13f, 1.66f, 3.44f ), //done
+ MouthFlapperDefaultSetting( "milhouse", -0.314159f, 0.521504f, 0.125664f, 2.22f, 4.00f ), //done
+ MouthFlapperDefaultSetting( "moe", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "moleman", -0.314159f, 0.452389f, 0.125664f, 1.56f, 3.54f ), //done
+ MouthFlapperDefaultSetting( "ned", -0.314159f, 0.490088f, 0.13f, 1.78f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "nelson", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ),
+ MouthFlapperDefaultSetting( "nriviera", -0.314159f, 0.470973f, 0.13f, 1.88f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "otto", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "patty", -0.314159f, 0.420973f, 0.136640f, 2.20f, 3.56f ), //done
+ MouthFlapperDefaultSetting( "ped0", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ),
+ MouthFlapperDefaultSetting( "ped1", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ),
+ MouthFlapperDefaultSetting( "ped2", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ),
+ MouthFlapperDefaultSetting( "ped3", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ),
+ MouthFlapperDefaultSetting( "ped4", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ),
+ MouthFlapperDefaultSetting( "ped5", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ),
+ MouthFlapperDefaultSetting( "ped6", -0.314159f, 0.452389f, 0.13f, 1.66f, 3.44f ),
+ MouthFlapperDefaultSetting( "ralph", -0.314159f, 0.471504f, 0.125664f, 2.22f, 4.00f ), //done
+ MouthFlapperDefaultSetting( "reward_barney", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done
+ MouthFlapperDefaultSetting( "reward_homer", -0.314159f, 0.420973f, 0.136640f, 2.00f, 3.44f ), //done
+ MouthFlapperDefaultSetting( "reward_kearney",-0.314159f, 0.521504f, 0.125664f, 2.34f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "reward_otto", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ),
+ MouthFlapperDefaultSetting( "reward_willie", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ),
+ MouthFlapperDefaultSetting( "selma", -0.314159f, 0.420973f, 0.136640f, 2.20f, 3.56f ), //done
+ MouthFlapperDefaultSetting( "skinner", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "smithers", -0.314159f, 0.490088f, 0.13f, 2.00f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "snake", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done
+ MouthFlapperDefaultSetting( "teen", -0.314159f, 0.470973f, 0.13f, 1.88f, 3.78f ), //done
+ MouthFlapperDefaultSetting( "wiggum", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ), //done
+ MouthFlapperDefaultSetting( "willie", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ),
+ MouthFlapperDefaultSetting( "zfem1", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ),
+ MouthFlapperDefaultSetting( "zmale1", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ),
+ MouthFlapperDefaultSetting( "zmale2", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ),
+ MouthFlapperDefaultSetting( "zmale3", -0.314159f, 0.559204f, 0.13f, 2.56f, 4.12f ),
+};
+
+char gWatcherNMnameSpace[ 256 ] = "Presentation\\MouthFlapping\\";
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// MouthFlapper::MouthFlapper
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+MouthFlapper::MouthFlapper() :
+ mJointIndex( -1 ),
+ mJoint( NULL ),
+ mCharacter( NULL ),
+ mCurrentdt( 0.0f ),
+ mDirection( -1.0f ),
+ mAngle( 0.0f ),
+ mSpeed( 0.0f ),
+ mMaxOpen( MAX_OPEN ),
+ mMinOpen( MIN_OPEN ),
+ mSetting( gDefaultSetting ),
+ mGotDefaultSettings( false )
+{
+}
+
+//==============================================================================
+// MouthFlapper::~MouthFlapper
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+MouthFlapper::~MouthFlapper()
+{
+ mCharacter = NULL;
+}
+
+//=============================================================================
+// MouthFlapper::AddVariablesToWatcher
+//=============================================================================
+// Description: Adds all the global variables controlling mouth flapping to the
+// watcher so that they can be tuned
+//
+// Parameters: none
+//
+// Return: void
+//
+//=============================================================================
+#ifdef DEBUGWATCH
+void MouthFlapper::AddVariablesToWatcher()
+{
+ int size = GetNumberOfDefaultSettings();
+ int i;
+ for( i = 0; i < size; ++i )
+ {
+ gDefaultSettings[ i ].AddToWatcher();
+ }
+}
+#endif //DEBUGWATCH
+
+//=============================================================================
+// MouthFlapper::GetDefaultSettings
+//=============================================================================
+// Description: Comment
+//
+// Parameters: name - the name of the character who's mouth is supposed to
+// flap
+//
+// Return: void
+//
+//=============================================================================
+void MouthFlapper::GetDefaultSettings( const tName& name )
+{
+ int size = GetNumberOfDefaultSettings();
+ int i;
+ for( i = 0; i < size; ++i )
+ {
+ MouthFlapperDefaultSetting& setting = gDefaultSettings[ i ];
+ tName settingName = setting.GetName();
+ if( settingName == name )
+ {
+ //
+ // Assign the settings
+ //
+ mSetting = setting;
+ return;
+ }
+ }
+ rAssertMsg( false, "A character for whom we have no mouth flapping parameters is talking - please tell Ian which level and mission this was" );
+}
+
+//=============================================================================
+// MouthFlapper::GetNumberOfDefaultSettings
+//=============================================================================
+// Description: returns the nubmer of characters for which default parameters
+// have been hardcoded
+//
+// Parameters: none
+//
+// Return: unsigned int - how many parameters are there
+//
+//=============================================================================
+unsigned int MouthFlapper::GetNumberOfDefaultSettings()
+{
+ size_t totalSize = sizeof( gDefaultSettings );
+ size_t sizeOfEach = sizeof( MouthFlapperDefaultSetting );
+ return totalSize / sizeOfEach;
+}
+
+//=============================================================================
+// MouthFlapper::SetCharacter
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( Character* guy )
+//
+// Return: void
+//
+//=============================================================================
+void MouthFlapper::SetCharacter( Character* pCharacter )
+{
+ mCharacter = pCharacter;
+ if( pCharacter != NULL )
+ {
+ choreo::Puppet* pPuppet = pCharacter->GetPuppet( );
+
+ poser::Pose* pPose = pPuppet->GetPose();
+ tSkeleton* skeleton = pPose->GetSkeleton();
+ mJointIndex = skeleton->FindJointIndex( "Jaw" );
+
+ mJoint = pPose->GetJoint( mJointIndex );
+ }
+ else
+ {
+ mJointIndex = -1;
+ mJoint = NULL;
+ }
+
+ NeuSpeed();
+}
+
+//=============================================================================
+// MouthFlapper::Update
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( int elapsedtime )
+//
+// Return: void
+//
+//=============================================================================
+void MouthFlapper::Advance( float deltaTime )
+{
+ mCurrentdt += deltaTime;
+}
+
+//=============================================================================
+// MouthFlapper::Update
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( Pose* pose )
+//
+// Return: void
+//
+//=============================================================================
+void MouthFlapper::Update( poser::Pose* pose )
+{
+ //
+ // make sure that the default settings are properly applied
+ //
+ rAssert( mCharacter != NULL );
+ const tName& name = mCharacter->GetNameObject();
+ GetDefaultSettings( name );
+
+ if( mCurrentdt <= 0.0f )
+ {
+ return;
+ }
+
+ rAssert( mJointIndex >= 0 );
+ poser::Joint* joint = pose->GetJoint(mJointIndex);
+ poser::Transform pt = joint->GetObjectTransform();
+ rmt::Matrix m = pt.GetMatrix();
+ rmt::Matrix r;
+ r.Identity();
+ float dAngle = mSpeed * mCurrentdt * mDirection;
+ mAngle += dAngle;
+ if( mAngle > mMaxOpen )
+ {
+ mDirection = -mDirection;
+ mAngle = mMaxOpen;
+ NeuSpeed();
+ }
+
+ if( mAngle < mMinOpen )
+ {
+ mDirection = -mDirection;
+ mAngle = mMinOpen;
+ NeuSpeed();
+ }
+
+ r.FillRotateZ( mAngle );
+ m.Mult( r );
+ pt.SetMatrix(m);
+ joint->SetObjectTransform(pt);
+ mCurrentdt = 0.0f;
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// MouthFlapper::NeuSpeed
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void MouthFlapper::NeuSpeed()
+{
+ float defaultMaxDeviation = mSetting.GetMaxDeviation();
+ float defaultMaxSpeed = mSetting.GetMaxSpeed();
+ float defaultMinSpeed = mSetting.GetMinSpeed();
+ float defaultMaxOpen = mSetting.GetMaxOpen();
+ float defaultMinOpen = mSetting.GetMinOpen();
+ mSpeed = defaultMinSpeed + ( defaultMaxSpeed - defaultMinSpeed ) * rand() / RAND_MAX;
+ mMaxOpen = defaultMaxOpen - defaultMaxDeviation * rand() / RAND_MAX;
+ mMinOpen = defaultMinOpen + defaultMaxDeviation * rand() / RAND_MAX;
+}
+
+//=============================================================================
+// MouthFlapperDefaultSetting::MouthFlapperDefaultSetting
+//=============================================================================
+// Description: constructor
+//
+// Parameters: N/A
+//
+// Return: N/A
+//
+//=============================================================================
+MouthFlapperDefaultSetting::MouthFlapperDefaultSetting(
+ const tName& name,
+ const float minOpen,
+ const float maxOpen,
+ const float maxDeviation,
+ const float minSpeed,
+ const float maxSpeed ) :
+ name( name ),
+ minOpen( minOpen ),
+ maxOpen( maxOpen ),
+ maxDeviation( maxDeviation ),
+ minSpeed( minSpeed ),
+ maxSpeed( maxSpeed )
+{
+}
+
+//=============================================================================
+// MouthFlapperDefaultSetting::MouthFlapperDefaultSetting
+//=============================================================================
+// Description: copy constructor
+//
+// Parameters: N/A
+//
+// Return: N/A
+//
+//=============================================================================
+MouthFlapperDefaultSetting::MouthFlapperDefaultSetting( const MouthFlapperDefaultSetting& right )
+{
+ *this = right;
+}
+
+//=============================================================================
+// MouthFlapperDefaultSetting::AddToWatcher
+//=============================================================================
+// Description: adds this set of mouth flapper parameters to the watcher
+//
+// Parameters: NONE
+//
+// Return: NONE
+//
+//=============================================================================
+void MouthFlapperDefaultSetting::AddToWatcher()
+{
+ char nameSpace[ 256 ] = "";
+ const char* nameString = name.GetText();
+ sprintf( nameSpace , "%s%s", gWatcherNMnameSpace, nameString );
+ radDbgWatchAddFloat( &minOpen, "Min Open", nameSpace, NULL, NULL, -rmt::PI, rmt::PI );
+ radDbgWatchAddFloat( &maxOpen, "Max Open", nameSpace, NULL, NULL, -rmt::PI, rmt::PI );
+ radDbgWatchAddFloat( &maxDeviation, "Max Deviation", nameSpace, NULL, NULL, 0.0f, 20.0f );
+ radDbgWatchAddFloat( &minSpeed, "Min Speed", nameSpace, NULL, NULL, 0.0f, 20.0f );
+ radDbgWatchAddFloat( &maxSpeed, "Max Speed", nameSpace, NULL, NULL, 0.0f, 20.0f );
+}
+
+//=============================================================================
+// MouthFlapperDefaultSetting::GetMaxDeviation
+//=============================================================================
+// Description: allows access to the maximum deviation
+//
+// Parameters: NONE
+//
+// Return: the maximum deviation parameter
+//
+//=============================================================================
+const float MouthFlapperDefaultSetting::GetMaxDeviation() const
+{
+ return maxDeviation;
+}
+
+//=============================================================================
+// MouthFlapperDefaultSetting::GetMaxOpen
+//=============================================================================
+// Description: allows access to the maxopen parameters
+//
+// Parameters: NONE
+//
+// Return: the max open parameter
+//
+//=============================================================================
+const float MouthFlapperDefaultSetting::GetMaxOpen() const
+{
+ return maxOpen;
+}
+
+//=============================================================================
+// MouthFlapperDefaultSetting::GetMaxSpeed
+//=============================================================================
+// Description: GetMaxSpeed
+//
+// Parameters: NONE
+//
+// Return: the max speed parameter
+//
+//=============================================================================
+const float MouthFlapperDefaultSetting::GetMaxSpeed() const
+{
+ return maxSpeed;
+}
+
+//=============================================================================
+// MouthFlapperDefaultSetting::GetMinOpen
+//=============================================================================
+// Description: GetMinOpen
+//
+// Parameters: NONE
+//
+// Return: the min open parameter
+//
+//=============================================================================
+const float MouthFlapperDefaultSetting::GetMinOpen() const
+{
+ return minOpen;
+}
+
+//=============================================================================
+// MouthFlapperDefaultSetting::GetMinSpeed
+//=============================================================================
+// Description: GetMinSpeed
+//
+// Parameters: NONE
+//
+// Return: the minSpeed parameter
+//
+//=============================================================================
+const float MouthFlapperDefaultSetting::GetMinSpeed() const
+{
+ return minSpeed;
+}
+
+//=============================================================================
+// MouthFlapperDefaultSetting::GetName
+//=============================================================================
+// Description: GetName
+//
+// Parameters: NONE
+//
+// Return: the name of the object
+//
+//=============================================================================
+const tName& MouthFlapperDefaultSetting::GetName() const
+{
+ return name;
+}
+
+//=============================================================================
+// MouthFlapperDefaultSetting::operator=
+//=============================================================================
+// Description: assignment operator
+//
+// Parameters: N/A
+//
+// Return: N/A
+//
+//=============================================================================
+MouthFlapperDefaultSetting& MouthFlapperDefaultSetting::operator=( const MouthFlapperDefaultSetting& right )
+{
+ if( this == &right )
+ {
+ return *this;
+ }
+
+ name = right.name;
+ minOpen = right.minOpen;
+ maxOpen = right.maxOpen;
+ maxDeviation = right.maxDeviation;
+ minSpeed = right.minSpeed;
+ maxSpeed = right.maxSpeed;
+ return *this;
+}
+
+//=============================================================================
+// MouthFlapperDefaultSetting::RemoveFromWatcher
+//=============================================================================
+// Description: removes this set of mouth flapper parameters to the watcher
+//
+// Parameters: NONE
+//
+// Return: NONE
+//
+//=============================================================================
+void MouthFlapperDefaultSetting::RemoveFromWatcher()
+{
+ radDbgWatchDelete( &minOpen );
+ radDbgWatchDelete( &maxOpen );
+ radDbgWatchDelete( &maxDeviation );
+ radDbgWatchDelete( &minSpeed );
+ radDbgWatchDelete( &maxSpeed );
+}
diff --git a/game/code/presentation/mouthflapper.h b/game/code/presentation/mouthflapper.h
new file mode 100644
index 0000000..0a4e600
--- /dev/null
+++ b/game/code/presentation/mouthflapper.h
@@ -0,0 +1,107 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: mouthflapper.h
+//
+// Description: Blahblahblah
+//
+// History: 09/09/2002 + Created -- NAME
+//
+//=============================================================================
+
+#ifndef MOUTHFLAPPER_H
+#define MOUTHFLAPPER_H
+
+//========================================
+// Nested Includes
+//========================================
+
+#include <poser/joint.hpp>
+#include <poser/posedriver.hpp>
+
+//========================================
+// Forward References
+//========================================
+
+class poser::Joint;
+class poser::Pose;
+class Character;
+
+
+//=============================================================================
+//
+// Synopsis: This class contains all the internal settings for mouth
+// flapping
+//
+//=============================================================================
+class MouthFlapperDefaultSetting
+{
+public:
+ MouthFlapperDefaultSetting( const tName& name, const float minOpen, const float maxOpen, const float maxDeviation, const float minSpeed, const float maxSpeed );
+ MouthFlapperDefaultSetting( const MouthFlapperDefaultSetting& right );
+ MouthFlapperDefaultSetting& operator=( const MouthFlapperDefaultSetting& right );
+ void AddToWatcher();
+ const float GetMaxDeviation() const;
+ const float GetMaxOpen() const;
+ const float GetMaxSpeed() const;
+ const float GetMinOpen() const;
+ const float GetMinSpeed() const;
+ const tName& GetName() const;
+ void RemoveFromWatcher();
+protected:
+private:
+ tName name;
+ float minOpen;
+ float maxOpen;
+ float maxDeviation;
+ float minSpeed;
+ float maxSpeed;
+};
+
+//=============================================================================
+//
+// Synopsis: class for mouth flapping
+//
+//=============================================================================
+class MouthFlapper : public poser::PoseDriver
+{
+public:
+ MouthFlapper();
+ virtual ~MouthFlapper();
+
+#ifdef DEBUGWATCH
+ static void AddVariablesToWatcher();
+#endif DEBUGWATCH
+ virtual void Advance( float deltaTime );
+ void GetDefaultSettings( const tName& name );
+ void SetCharacter( Character* pCharacter );
+ virtual void Update( poser::Pose* pose );
+
+protected:
+ static unsigned int GetNumberOfDefaultSettings();
+
+private:
+
+ //Prevent wasteful constructor creation.
+ MouthFlapper( const MouthFlapper& mouthflapper );
+ MouthFlapper& operator=( const MouthFlapper& mouthflapper );
+
+ void NeuSpeed();
+
+ int mJointIndex;
+ poser::Joint* mJoint;
+ Character* mCharacter;
+
+ float mCurrentdt;
+ float mDirection;
+ float mAngle;
+ float mSpeed;
+ float mMaxOpen;
+ float mMinOpen;
+
+ MouthFlapperDefaultSetting mSetting;
+ bool mGotDefaultSettings;
+};
+
+
+#endif //MOUTHFLAPPER_H
diff --git a/game/code/presentation/nisplayer.cpp b/game/code/presentation/nisplayer.cpp
new file mode 100644
index 0000000..b13a9fb
--- /dev/null
+++ b/game/code/presentation/nisplayer.cpp
@@ -0,0 +1,163 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: nisplayer.cpp
+//
+// Description: Implement NISPlayer
+//
+// History: 16/04/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+#include <p3d/anim/compositedrawable.hpp>
+#include <p3d/utility.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include <presentation/nisplayer.h>
+#include <loading/filehandlerenum.h>
+#include <loading/loadingmanager.h>
+
+#include <render/rendermanager/rendermanager.h>
+
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// NISPlayer::NISPlayer
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+NISPlayer::NISPlayer() :
+ mpSceneGraph( NULL )
+{
+ SetExclusive( false );
+}
+
+//==============================================================================
+// NISPlayer::~NISPlayer
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+NISPlayer::~NISPlayer()
+{
+
+}
+
+
+//=============================================================================
+// NISPlayer::ClearData
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void NISPlayer::ClearData()
+{
+ SimpleAnimationPlayer::ClearData();
+
+ if( mpSceneGraph != NULL )
+ {
+ GetRenderManager()->mEntityDeletionList.Add((tRefCounted*&)mpSceneGraph);
+ mpSceneGraph = NULL;
+ }
+}
+
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// NISPlayer::DoLoaded
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void NISPlayer::DoLoaded()
+{
+ SimpleAnimationPlayer::DoLoaded();
+
+ tRefCounted::Release(mpSceneGraph);
+ tRefCounted::Assign(mpSceneGraph, (tDrawable*)p3d::find<Scenegraph::Scenegraph>( GetAnimationName() ));
+ if(!mpSceneGraph)
+ {
+ tRefCounted::Assign(mpSceneGraph, (tDrawable*)p3d::find<tCompositeDrawable>( GetAnimationName() ));
+ }
+}
+
+//=============================================================================
+// NISPlayer::DoRender
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void NISPlayer::DoRender()
+{
+ SimpleAnimationPlayer::DoRender();
+
+ if(mpSceneGraph)
+ mpSceneGraph->Display();
+}
+
+//=============================================================================
+// NISPlayer::GetBoundingBox
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( rmt::Box3D* box )
+//
+// Return: true if box filled out, false otherwise
+//
+//=============================================================================
+bool NISPlayer::GetBoundingBox( rmt::Box3D* box )
+{
+ bool retval = false;
+
+ if( mpSceneGraph )
+ {
+ mpSceneGraph->GetBoundingBox( box );
+ retval = true;
+ }
+
+ return( retval );
+}
diff --git a/game/code/presentation/nisplayer.h b/game/code/presentation/nisplayer.h
new file mode 100644
index 0000000..430eeb0
--- /dev/null
+++ b/game/code/presentation/nisplayer.h
@@ -0,0 +1,59 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: .h
+//
+// Description: Blahblahblah
+//
+// History: 16/04/2002 + Created -- NAME
+//
+//=============================================================================
+
+#ifndef NISPLAYER_H
+#define NISPLAYER_H
+
+//========================================
+// Nested Includes
+//========================================
+
+#include <presentation/simpleanimationplayer.h>
+
+#include <p3d/scenegraph/scenegraph.hpp>
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: Blahblahblah
+//
+//=============================================================================
+
+class NISPlayer : public SimpleAnimationPlayer
+{
+ public:
+ NISPlayer();
+ virtual ~NISPlayer();
+
+ virtual void ClearData();
+
+ bool GetBoundingBox( rmt::Box3D* box );
+ tDrawable* GetDrawable() { return mpSceneGraph; }
+
+ protected:
+ virtual void DoLoaded();
+ virtual void DoRender();
+
+ private:
+
+ //Prevent wasteful constructor creation.
+ NISPlayer( const NISPlayer& nisPlayer );
+ NISPlayer& operator=( const NISPlayer& nisPlayer );
+
+ tDrawable* mpSceneGraph;
+};
+
+
+#endif //NISPLAYER_H
+
diff --git a/game/code/presentation/playerdrawable.cpp b/game/code/presentation/playerdrawable.cpp
new file mode 100644
index 0000000..1f36147
--- /dev/null
+++ b/game/code/presentation/playerdrawable.cpp
@@ -0,0 +1,90 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: Playerdrawable.cpp
+//
+// Description: Implement PlayerDrawable
+//
+// History: 23/05/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+
+//========================================
+// Project Includes
+//========================================
+
+#include <presentation/playerdrawable.h>
+#include <presentation/animplayer.h>
+#include <render/rendermanager/rendermanager.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// PlayerDrawable::PlayerDrawable
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+PlayerDrawable::PlayerDrawable() :
+ mpPlayer( NULL )
+{
+}
+
+//==============================================================================
+// PlayerDrawable::~PlayerDrawable
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+PlayerDrawable::~PlayerDrawable()
+{
+
+}
+
+//=============================================================================
+// PlayerDrawable::Display
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void PlayerDrawable::Display()
+{
+ if(mpPlayer != NULL)
+ {
+ mpPlayer->Render();
+ }
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
diff --git a/game/code/presentation/playerdrawable.h b/game/code/presentation/playerdrawable.h
new file mode 100644
index 0000000..059ee1b
--- /dev/null
+++ b/game/code/presentation/playerdrawable.h
@@ -0,0 +1,58 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: .h
+//
+// Description: Blahblahblah
+//
+// History: 23/05/2002 + Created -- NAME
+//
+//=============================================================================
+
+#ifndef PlayerDRAWABLE_H
+#define PlayerDRAWABLE_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <p3d/drawable.hpp>
+#include <render/enums/renderenums.h>
+
+//========================================
+// Forward References
+//========================================
+
+class AnimationPlayer;
+
+//=============================================================================
+//
+// Synopsis: The PlayerDrawable is just a temporary thing for the DSG to
+// call and get the current presentation player to draw.
+//
+//=============================================================================
+
+class PlayerDrawable : public tDrawable
+{
+ public:
+ PlayerDrawable();
+ virtual ~PlayerDrawable();
+
+ void SetPlayer( AnimationPlayer* pPlayer ) { mpPlayer = pPlayer; }
+ virtual void Display();
+
+ void SetRenderLayer( RenderEnums::LayerEnum layer ) { mRenderLayer = layer; }
+ RenderEnums::LayerEnum GetRenderLayer() { return mRenderLayer; }
+
+ private:
+
+ //Prevent wasteful constructor creation.
+ PlayerDrawable( const PlayerDrawable& pPlayerDrawable );
+ PlayerDrawable& operator=( const PlayerDrawable& pPlayerDrawable );
+
+ AnimationPlayer* mpPlayer;
+ RenderEnums::LayerEnum mRenderLayer;
+};
+
+
+#endif // PlayerDRAWABLE_H
+
diff --git a/game/code/presentation/presentation.cpp b/game/code/presentation/presentation.cpp
new file mode 100644
index 0000000..c67fc91
--- /dev/null
+++ b/game/code/presentation/presentation.cpp
@@ -0,0 +1,1466 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: presentation.cpp
+//
+// Description: Implement PresentationManager
+//
+// History: 16/04/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+#include <raddebugwatch.hpp>
+#include <p3d/view.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include <events/eventmanager.h>
+#include <events/eventenum.h>
+#include <events/eventdata.h>
+#include <memory/srrmemory.h>
+#include <contexts/context.h>
+#include <contexts/bootupcontext.h>
+#include <contexts/gameplay/gameplaycontext.h>
+#include <gameflow/gameflow.h>
+#include <meta/eventlocator.h>
+#include <meta/triggervolume.h>
+#include <presentation/playerdrawable.h>
+#include <presentation/presentation.h>
+#include <presentation/presentationanimator.h>
+#include <presentation/nisplayer.h>
+#include <presentation/tutorialmanager.h>
+#include <presentation/cameraplayer.h>
+#include <presentation/transitionplayer.h>
+#include <presentation/gui/guimanager.h>
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/guitextbible.h>
+#include <presentation/gui/ingame/guimanageringame.h>
+#include <presentation/gui/ingame/guiscreenhud.h>
+#include <presentation/gui/ingame/guiscreenmissionload.h>
+#include <presentation/mouthflapper.h>
+#include <presentation/fmvplayer/fmvplayer.h>
+
+#include <camera/supercammanager.h>
+#include <camera/supercamcentral.h>
+#include <camera/conversationcam.h>
+#include <camera/isupercamtarget.h>
+
+#include <worldsim/character/character.h>
+#include <worldsim/character/charactermanager.h>
+#include <worldsim/character/charactertarget.h>
+#include <worldsim/avatarmanager.h>
+#include <p3d/matrixstack.hpp>
+
+#include <render/rendermanager/rendermanager.h>
+#include <render/RenderManager/RenderLayer.h>
+#include <render/enums/renderenums.h>
+#include <mission/gameplaymanager.h>
+#include <mission/objectives/missionobjective.h>
+#include <screen.h>
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+// Static pointer to instance of singleton.
+PresentationManager* PresentationManager::spInstance = NULL;
+const int PLAYER_ONE = 0;
+const int MAX_DIALOG_LINES = 64;
+#define MAX_CHARACTERS 64
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// PresentationManager::CreateInstance
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: PresentationManager
+//
+//=============================================================================
+PresentationManager* PresentationManager::CreateInstance()
+{
+MEMTRACK_PUSH_GROUP( "PresentationManager" );
+ if( spInstance == NULL )
+ {
+ spInstance = new(GMA_PERSISTENT) PresentationManager;
+ rAssert( spInstance );
+ }
+MEMTRACK_POP_GROUP( "PresentationManager" );
+
+ return spInstance;
+}
+
+//=============================================================================
+// PresentationManager::GetInstance
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: PresentationManager
+//
+//=============================================================================
+PresentationManager* PresentationManager::GetInstance()
+{
+ return spInstance;
+}
+
+//=============================================================================
+// PresentationManager::DestroyInstance
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void PresentationManager::DestroyInstance()
+{
+ if( spInstance != NULL )
+ {
+ delete( GMA_PERSISTENT, spInstance );
+ spInstance = NULL;
+ }
+}
+
+//==============================================================================
+// PresentationManager::PresentationManager
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+PresentationManager::PresentationManager() :
+ mTransitionPool( NULL ),
+ mNISPool( NULL ),
+ mFMVPool( NULL ),
+ mFIFOBegin( 0 ),
+ mFIFOEnd( 0 ),
+ mpCurrent( NULL ),
+ mpFMVPlayer( NULL ),
+ mpNISPlayer( NULL ),
+ mpCameraPlayer( NULL ),
+ mpTransitionPlayer( NULL ),
+// mLanguage( Language::MAX_LANGUAGES ),
+ mp_PCAnimator( NULL ),
+ mp_NPCAnimator( NULL ),
+ mDialogLineNumber( -1 ),
+ mCameraForLineOfDialog(MAX_DIALOG_LINES),
+ mpPlayCallback( 0 ),
+ mWaitingOnFade( false ),
+ mOverlay( 0 )
+{
+ mInConversation = false;
+ // mOldFOV= 0.0F;
+
+ unsigned int i;
+
+ for( i = 0; i < MAX_EVENT_SIZE; i++ )
+ {
+ mEventFIFO[ i ] = NULL;
+ }
+
+ // what is the current allocator
+ radMemoryAllocator current = HeapManager::GetInstance()->GetCurrentAllocator();
+ GameMemoryAllocator gmaCurrent = HeapManager::GetInstance()->GetCurrentHeap();
+
+ mFMVPool = new FMVEventPool( gmaCurrent, 10 );
+ mNISPool = new NISEventPool( gmaCurrent, 10 );
+ mTransitionPool = new TransitionEventPool( gmaCurrent, 10 );
+ mpNISPlayer = new NISPlayer();
+ mpCameraPlayer = new CameraPlayer();
+ mpTransitionPlayer = new TransitionPlayer();
+ mpFMVPlayer = new( current ) FMVPlayer();
+ mpPlayerDrawable = new PlayerDrawable();
+ mpPlayerDrawable->AddRef();
+ mOverlay = new PresentationOverlay();
+ mOverlay->AddRef();
+
+ mp_oldcam = NULL;
+ mOldCamIndexNum =0;
+}
+
+//==============================================================================
+// PresentationManager::~PresentationManager
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+PresentationManager::~PresentationManager()
+{
+ delete mFMVPool; mFMVPool = NULL;
+ delete mNISPool; mNISPool = NULL;
+ delete mTransitionPool; mTransitionPool = NULL;
+ delete mpNISPlayer; mpNISPlayer = NULL;
+ delete mpCameraPlayer; mpCameraPlayer = NULL;
+ delete mpTransitionPlayer; mpTransitionPlayer = NULL;
+ delete mpFMVPlayer; mpFMVPlayer = NULL;
+
+ this->FinalizePlayerDrawable();
+
+ mpPlayerDrawable->ReleaseVerified();
+ mOverlay->Release();
+}
+
+//=============================================================================
+// PresentationManager::Initialize
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void PresentationManager::Initialize()
+{
+MEMTRACK_PUSH_GROUP( "PresentationManager" );
+ //Cary: I took this out since it was allocating to the levelslot when
+ //the level isn't even loaded. No one seems to know what it's for
+ //so Darryl probably did it and it's not used anymore. Feb 13th 2003
+ //pLayer = GetRenderManager()->mpLayer( RenderEnums::LevelSlot );
+ //pLayer->AddGuts( mpPlayerDrawable );
+
+ GetEventManager()->AddListener( this, EVENT_LOCATOR );
+
+ //Listen for Conversation
+ GetEventManager()->AddListener( this, EVENT_CONVERSATION_INIT );
+ GetEventManager()->AddListener( this, EVENT_CONVERSATION_SKIP );
+ GetEventManager()->AddListener( this, EVENT_CONVERSATION_DONE );
+
+ //Listen for MouthFlapping Cues
+ GetEventManager()->AddListener( this, EVENT_PC_TALK );
+ GetEventManager()->AddListener( this, EVENT_PC_SHUTUP );
+ GetEventManager()->AddListener( this, EVENT_NPC_TALK );
+ GetEventManager()->AddListener( this, EVENT_NPC_SHUTUP );
+ GetEventManager()->AddListener( this, EVENT_GUI_FADE_OUT_DONE );
+
+ rAssert( mp_PCAnimator == NULL );
+ rAssert( mp_NPCAnimator == NULL );
+ HeapMgr()->PushHeap( GMA_LEVEL_OTHER );
+ mp_PCAnimator = new PresentationAnimator();
+ mp_NPCAnimator = new PresentationAnimator();
+ HeapMgr()->PopHeap( GMA_LEVEL_OTHER );
+MEMTRACK_POP_GROUP( "PresentationManager" );
+}
+
+//=============================================================================
+// PresentationManager::Finalize
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void PresentationManager::Finalize()
+{
+ mCameraForLineOfDialog.erase( mCameraForLineOfDialog.begin(), mCameraForLineOfDialog.end() );
+
+ mp_PCAnimator->SetCharacter( NULL );
+ mp_NPCAnimator->SetCharacter( NULL );
+ mp_PCAnimator->ClearAmbientAnimations();
+ mp_NPCAnimator->ClearAmbientAnimations();
+
+ //remove for Conversation
+ GetEventManager()->RemoveListener( this, EVENT_CONVERSATION_INIT );
+ GetEventManager()->RemoveListener( this, EVENT_CONVERSATION_SKIP );
+ GetEventManager()->RemoveListener( this, EVENT_CONVERSATION_DONE );
+
+ //remove for MouthFlapping Cues
+ GetEventManager()->RemoveListener( this, EVENT_PC_TALK );
+ GetEventManager()->RemoveListener( this, EVENT_PC_SHUTUP );
+ GetEventManager()->RemoveListener( this, EVENT_NPC_TALK );
+ GetEventManager()->RemoveListener( this, EVENT_NPC_SHUTUP );
+
+ delete mp_PCAnimator; mp_PCAnimator = NULL;
+ delete mp_NPCAnimator; mp_NPCAnimator = NULL;
+}
+
+//=============================================================================
+// PresentationManager::InitializePlayerDrawable
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void
+PresentationManager::InitializePlayerDrawable()
+{
+ RenderLayer* pLayer = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot );
+ rAssert( pLayer != NULL );
+ pLayer->pView( 0 )->SetClearColour( tColour( 0, 0, 0 ) );
+ pLayer->AddGuts( mpPlayerDrawable );
+}
+
+//=============================================================================
+// PresentationManager::FinalizePlayerDrawable
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void
+PresentationManager::FinalizePlayerDrawable()
+{
+ RenderLayer* pLayer = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot );
+ rAssert( pLayer != NULL );
+ pLayer->RemoveGuts( mpPlayerDrawable );
+}
+
+//=============================================================================
+// PresentationManager::GetAnimatorNpc
+//=============================================================================
+// Description: returns the presentation animator for the NPC
+//
+// Parameters: NONE
+//
+// Return: pointer to the presentationanimator
+//
+//=============================================================================
+PresentationAnimator* PresentationManager::GetAnimatorNpc()
+{
+ return this->mp_NPCAnimator;
+}
+
+//=============================================================================
+// PresentationManager::GetAnimatorPc
+//=============================================================================
+// Description: returns the presentation animator for the PC
+//
+// Parameters: NONE
+//
+// Return: pointer to the presentationanimator
+//
+//=============================================================================
+PresentationAnimator* PresentationManager::GetAnimatorPc()
+{
+ return this->mp_PCAnimator;
+}
+
+/*=============================================================================
+Description: You're one stop method for playing an FMV during gameplay. It
+ unloads the HUD (for memory), plays the FMV, and then
+ reloads the HUD. Don't use this in the frontend as the
+ un/reloading of the frontend is a waste.
+ NOTE that the platform specific path for the movies is prepended
+ to the filename. So if you pass "fmv2.rmv" you'll get
+ "d:\movies\fmv2.rmv" on XBox, "movies\fmv2.rmv" on PS2,
+ "movies/fmv2.rmv" on GC.
+=============================================================================*/
+void PresentationManager::PlayFMV( const char* FileName,
+ PresentationEvent::PresentationEventCallBack* pCallback,
+ bool IsSkippable,
+ bool StopMusic,
+ bool IsLocalized )
+{
+ // this puts the FMV player in the "loading" state
+ // this is needed so that the gag system can tell when a gag has ended
+ // (without this the state right before and right after the fmc playes is the same
+ mpFMVPlayer->PreLoad();
+
+#ifdef RAD_E3
+ // no in-game FMV's for E3 build
+ //
+ if( pCallback != NULL )
+ {
+ pCallback->OnPresentationEventEnd( NULL );
+ }
+
+ return;
+#endif
+
+ if( mOverlay )
+ {
+ //
+ // Hide the HUD
+ //
+ CGuiScreenHud* hud = dynamic_cast< CGuiScreenHud* >( GetGuiSystem()->GetInGameManager()->FindWindowByID( CGuiWindow::GUI_SCREEN_ID_HUD ) );
+ rAssert( hud != NULL );
+ Scrooby::Screen* screen = hud->GetScroobyScreen();
+ screen->SetAlpha( 0.0f );
+
+
+ mOverlay->SetStart( BLACK_TRANSPARENT );
+ mOverlay->SetEnd( BLACK );
+ mOverlay->SetDuration( 0.5f );
+ RenderLayer* pLayer = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot );
+ rAssert( pLayer );
+ if( pLayer->IsDead() )
+ {
+ pLayer->Resurrect();
+ }
+ pLayer->Thaw();
+ pLayer->AddGuts( mOverlay );
+ }
+ mWaitingOnFade = true;
+ FMVEvent* pEvent = 0;
+ GetPresentationManager()->QueueFMV( &pEvent, this );
+#ifdef RAD_XBOX
+ strcpy( pEvent->fileName, "D:\\movies\\" );
+#elif RAD_PS2
+ strcpy( pEvent->fileName, "movies\\" );
+#elif RAD_WIN32
+ strcpy( pEvent->fileName, "movies\\" );
+#else
+ strcpy( pEvent->fileName, "movies/" );
+#endif
+ strcat( pEvent->fileName, FileName );
+ pEvent->SetRenderLayer( RenderEnums::PresentationSlot );
+ pEvent->SetAutoPlay( true );
+
+#ifdef PAL
+ if( IsLocalized )
+ {
+ switch( CGuiTextBible::GetCurrentLanguage() )
+ {
+ case Scrooby::XL_FRENCH:
+ {
+ pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_FRENCH );
+
+ break;
+ }
+ case Scrooby::XL_GERMAN:
+ {
+ pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_GERMAN );
+
+ break;
+ }
+ case Scrooby::XL_SPANISH:
+ {
+ pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_SPANISH );
+
+ break;
+ }
+ default:
+ {
+ rAssert( CGuiTextBible::GetCurrentLanguage() == Scrooby::XL_ENGLISH );
+ pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_ENGLISH );
+
+ break;
+ }
+ }
+ }
+ else
+#endif // PAL
+ {
+ pEvent->SetAudioIndex( FMVEvent::AUDIO_INDEX_ENGLISH );
+ }
+
+#ifdef RAD_GAMECUBE
+ pEvent->SetAllocator( GMA_ANYWHERE_IN_LEVEL );
+#else
+ pEvent->SetAllocator( GMA_LEVEL_HUD );
+#endif
+ pEvent->SetClearWhenDone( true );
+ pEvent->SetKeepLayersFrozen( true );
+ pEvent->SetSkippable(IsSkippable);
+ if( StopMusic )
+ {
+ pEvent->KillMusic();
+ }
+ mpPlayCallback = pCallback;
+}
+/*=============================================================================
+Description: This is a callback when the event queued by PlayFMV.
+=============================================================================*/
+void PresentationManager::OnPresentationEventBegin( PresentationEvent* pEvent )
+{
+ Context* context = GetGameFlow()->GetContext( GetGameFlow()->GetCurrentContext() );
+ if( dynamic_cast<GameplayContext*>( context ) )
+ {
+ static_cast<GameplayContext*>( context )->PauseAllButPresentation( true );
+ }
+ GetGuiSystem()->HandleMessage( GUI_MSG_RELEASE_INGAME );
+ if( mpPlayCallback )
+ {
+ mpPlayCallback->OnPresentationEventBegin( pEvent );
+ }
+ RenderLayer* rl = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot );
+ rAssert( rl );
+ rl->RemoveGuts( mOverlay );
+}
+/*=============================================================================
+Description: This is a callback when the event queued by PlayFMV.
+=============================================================================*/
+void PresentationManager::OnPresentationEventLoadComplete( PresentationEvent* pEvent )
+{
+ if( mpPlayCallback )
+ {
+ mpPlayCallback->OnPresentationEventLoadComplete( pEvent );
+ }
+}
+/*=============================================================================
+Description: This is a callback when the event queued by PlayFMV.
+=============================================================================*/
+void PresentationManager::OnPresentationEventEnd( PresentationEvent* pEvent )
+{
+ HeapMgr()->PushHeap (GMA_LEVEL_HUD);
+ GetGuiSystem()->HandleMessage( GUI_MSG_INIT_INGAME );
+ HeapMgr()->PopHeap (GMA_LEVEL_HUD);
+ GetLoadingManager()->AddCallback( this );
+ if( mOverlay )
+ {
+ mOverlay->SetStart( BLACK_TRANSPARENT );
+ mOverlay->SetEnd( BLACK );
+ mOverlay->SetDuration( 0.5f );
+ //mOverlay->SetRemoveOnComplete( true );
+ RenderLayer* pLayer = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot );
+ rAssert( pLayer );
+ pLayer->AddGuts( mOverlay );
+ }
+}
+/*=============================================================================
+Description:
+=============================================================================*/
+void PresentationManager::OnProcessRequestsComplete( void* pUserData )
+{
+ Context* context = GetGameFlow()->GetContext( GetGameFlow()->GetCurrentContext() );
+ if( dynamic_cast<GameplayContext*>( context ) )
+ {
+ static_cast<GameplayContext*>( context )->PauseAllButPresentation( false );
+ }
+ GetRenderManager()->ThawFromPresentation();
+ GetGuiSystem()->HandleMessage( GUI_MSG_RUN_INGAME );
+ if( mpPlayCallback )
+ {
+ mpPlayCallback->OnPresentationEventEnd( 0 );
+ }
+ mpPlayCallback = 0;
+ if( mOverlay )
+ {
+ mOverlay->SetEnd( BLACK );
+ mOverlay->SetFrames( 10 );
+ mOverlay->SetRemoveOnComplete( true );
+ RenderLayer* pLayer = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot );
+ rAssert( pLayer );
+ pLayer->AddGuts( mOverlay );
+ }
+}
+//=============================================================================
+// PresentationManager::QueueFMV
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( FMVEvent** pFMVEvent, PresentationEvent::PresentationEventCallBack* pCallback )
+//
+// Return: void
+//
+//=============================================================================
+void PresentationManager::QueueFMV( FMVEvent** pFMVEvent, PresentationEvent::PresentationEventCallBack* pCallback )
+{
+ (*pFMVEvent) = mFMVPool->AllocateFromPool();
+ (*pFMVEvent)->Init();
+ (*pFMVEvent)->SetAllocator(GMA_LEVEL_MOVIE);
+ (*pFMVEvent)->pCallback = pCallback;
+
+ AddToQueue( *pFMVEvent );
+}
+
+//=============================================================================
+// PresentationManager::QueueNIS
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( NISEvent** pNISEvent, PresentationEvent::PresentationEventCallBack* pCallback )
+//
+// Return: void
+//
+//=============================================================================
+void PresentationManager::QueueNIS( NISEvent** pNISEvent, PresentationEvent::PresentationEventCallBack* pCallback )
+{
+ (*pNISEvent) = mNISPool->AllocateFromPool();
+ (*pNISEvent)->Init();
+
+ (*pNISEvent)->pCallback = pCallback;
+
+ AddToQueue( *pNISEvent );
+}
+
+//=============================================================================
+// PresentationManager::QueueTransition
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( TransitionEvent** pTransitionEvent,
+// PresentationEvent::PresentationEventCallBack* pCallback )
+//
+// Return: void
+//
+//=============================================================================
+void PresentationManager::QueueTransition( TransitionEvent** pTransitionEvent,
+ PresentationEvent::PresentationEventCallBack* pCallback )
+{
+ (*pTransitionEvent) = mTransitionPool->AllocateFromPool();
+ (*pTransitionEvent)->Init();
+
+ (*pTransitionEvent)->pCallback = pCallback;
+
+ AddToQueue( *pTransitionEvent );
+}
+
+bool PresentationManager::IsBusy(void) const
+{
+ return (mpCurrent != 0) || mWaitingOnFade;
+}
+
+//=============================================================================
+// PresentationManager::Update
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( unsigned int elapsedTime )
+//
+// Return: void
+//
+//=============================================================================
+void PresentationManager::Update( unsigned int elapsedTime )
+{
+ GetTutorialManager()->Update( static_cast< float >( elapsedTime ) );
+
+ if( mp_PCAnimator != NULL )
+ {
+ mp_PCAnimator->Update( static_cast<int>( elapsedTime ));
+ }
+
+ if( mp_NPCAnimator != NULL )
+ {
+ mp_NPCAnimator->Update( static_cast<int>( elapsedTime ));
+ }
+
+ rAssert( mOverlay != NULL );
+ mOverlay->Update( elapsedTime );
+
+ if( mWaitingOnFade )
+ {
+ if( mOverlay->GetAlpha() == 0.0f )
+ {
+ // get one extra frame of full black.
+ mWaitingOnFade = false;
+ }
+ return;
+ }
+ if( mpCurrent == NULL )
+ {
+ mpCurrent = GetFirst();
+
+ if (mpCurrent != NULL )
+ {
+ if( mpCurrent->pCallback != NULL )
+ {
+ mpCurrent->pCallback->OnPresentationEventBegin( mpCurrent );
+ }
+ mpPlayerDrawable->SetPlayer( mpCurrent->GetPlayer() );
+ mpPlayerDrawable->SetRenderLayer( mpCurrent->GetRenderLayer() );
+
+ mpCurrent->Start();
+ mWaitingOnFade = false;
+ }
+ }
+
+ if( mpCurrent != NULL )
+ {
+ bool finished = !mpCurrent->Update( elapsedTime );
+
+ if( finished )
+ {
+ if( mpCurrent->pCallback != NULL )
+ {
+ mpCurrent->pCallback->OnPresentationEventEnd( mpCurrent );
+ }
+ mpCurrent->Stop();
+ mpPlayerDrawable->SetPlayer( NULL );
+
+ ReturnToPool( mpCurrent );
+
+ mpCurrent = NULL;
+ }
+ }
+}
+
+//=============================================================================
+// PresentationManager::ClearQueue
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void PresentationManager::ClearQueue()
+{
+ if( mpCurrent == NULL )
+ {
+ mpCurrent = GetFirst();
+ }
+
+ while ( mpCurrent != NULL )
+ {
+ if( mpCurrent->pCallback != NULL )
+ {
+ mpCurrent->pCallback->OnPresentationEventEnd( mpCurrent );
+ }
+
+ mpCurrent->Stop();
+
+ ReturnToPool( mpCurrent );
+
+ mpCurrent = GetFirst();
+ };
+
+ mpPlayerDrawable->SetPlayer( NULL );
+}
+
+//=============================================================================
+// PresentationManager::GetCameraTargetForLineOfDialog
+//=============================================================================
+// Description: what should the camera look at for this line of dialog
+//
+// Parameters: lineOfDialog - which line are we on?
+//
+// Return: CameraTarget - PC, NPC, or Don't Care
+//
+//=============================================================================
+const tName PresentationManager::GetCameraTargetForLineOfDialog( const unsigned int lineOfDialog ) const
+{
+ size_t size = mCameraForLineOfDialog.size();
+ if( lineOfDialog >= size )
+ {
+ return tName( "NONE" );
+ }
+ else
+ {
+ const tName& returnMe = mCameraForLineOfDialog[ lineOfDialog ];
+ return returnMe;
+ }
+}
+//=============================================================================
+// PresentationManager::HandleEvent
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( EventEnum id, void* pEventData )
+//
+// Return: void
+//
+//=============================================================================
+void PresentationManager::HandleEvent( EventEnum id, void* pEventData )
+{
+ switch( id )
+ {
+ case EVENT_GUI_FADE_OUT_DONE:
+ {
+ if( mWaitingOnFade )
+ {
+ mWaitingOnFade = false;
+ }
+ }
+ break;
+ case EVENT_LOCATOR:
+ {
+/*
+ EventLocator* locator = (EventLocator*)pEventData;
+ if( locator->GetFlag(Locator::ACTIVE) )
+ {
+ if( strcmp( locator->GetTriggerVolume()->GetName(), "TestTrigger" ) == 0 )
+ {
+ NISEvent* pEvent;
+ QueueNIS( &pEvent, NULL );
+ pEvent->fileName = "art\\camtest.p3d";
+ pEvent->type = NISEvent::NIS_CAMERA;
+ strcpy( pEvent->camera, "cameraShape1" );
+ strcpy( pEvent->animation, "CAM_cameraShape1" );
+ strcpy( pEvent->controller, "MasterController" );
+ pEvent->LoadFromInventory();
+ }
+ }
+*/
+ break;
+ }
+
+ case EVENT_CONVERSATION_INIT:
+ {
+ DialogEventData* p_dialogstruct = static_cast <DialogEventData*> (pEventData);
+
+ //
+ // Register the character and the NPC with the conversation camera
+ //
+ SuperCam* camera = GetSuperCamManager()->GetSCC( 0 )->GetSuperCam( SuperCam::CONVERSATION_CAM );
+ ConversationCam* convCam = dynamic_cast< ConversationCam* >( camera );
+ convCam->SetCharacter( 0, p_dialogstruct->char1 );
+ convCam->SetCharacter( 1, p_dialogstruct->char2 );
+
+ rAssert(p_dialogstruct);
+ rAssert( p_dialogstruct->char1 != NULL );
+ rAssert( p_dialogstruct->char2 != NULL );
+
+ //
+ // some conversations are special - race missions for example
+ // require different bitmaps
+ //
+ Character* char1 = p_dialogstruct->char1;
+ Character* char2 = p_dialogstruct->char2;
+ Character* npc = NULL;
+ Character* pc = NULL;
+
+ if( char1->IsNPC() )
+ {
+ npc = char1;
+ pc = char2;
+ }
+ else
+ {
+ rAssert( char2->IsNPC() );
+ npc = char2;
+ pc = char1;
+ }
+
+ mp_PCAnimator->SetCharacter(pc);
+ mp_NPCAnimator->SetCharacter(npc);
+
+ if(pc->GetStateManager()->GetState() == CharacterAi::INCAR)
+ {
+ GetAvatarManager()->PutCharacterOnGround(pc, pc->GetTargetVehicle());
+ }
+
+ //
+ // Make the characters face one another
+ //
+
+ // If we're talking to patty and selma, we need to make selma face the user
+ GameplayManager* gpm = GetGameplayManager();
+ Mission* mission = gpm->GetCurrentMission();
+ bool pattyAndSelma = mission->GetCurrentStage()->GetObjective()->IsPattyAndSelmaDialog();
+ if( pattyAndSelma )
+ {
+ CharacterManager* cm = GetCharacterManager();
+ Character* selma = cm->GetCharacterByName( "selma" );
+ if(selma == NULL && GetGameplayManager()->GetCurrentLevelIndex() == RenderEnums::L7)
+ {
+ selma = cm->GetMissionCharacter("zmale1");
+ rTuneAssert(selma != NULL);
+ }
+ MakeCharactersFaceEachOther( selma, pc );
+
+ }
+ MakeCharactersFaceEachOther( char1, char2 );
+
+ mDialogLineNumber = -1;
+ mOldCamIndexNum= GetSuperCamManager()->GetSCC(PLAYER_ONE)->GetActiveSuperCamIndex();
+
+ // don't swap to close up camera if we are using a static cam (generally in an interior,
+ // where the camera movement could screw us up)
+ if(GetSuperCamManager()->GetSCC(PLAYER_ONE)->AllowCameraToggle())
+ {
+ if ( GetGameplayManager()->GetCurrentMission()->DialogueCharactersTeleported() )
+ {
+ GetSuperCamManager()->GetSCC(PLAYER_ONE)->SelectSuperCam(SuperCam::CONVERSATION_CAM, SuperCamCentral::CUT, 0 );
+ }
+ else
+ {
+ GetSuperCamManager()->GetSCC(PLAYER_ONE)->SelectSuperCam(SuperCam::CONVERSATION_CAM, 0 );
+ }
+ GetSuperCamManager()->GetSCC(PLAYER_ONE)->AddTarget( mp_NPCAnimator->GetCharacter()->GetTarget() );
+ }
+
+ //TO DO call Character eye blinking
+ mInConversation =true;
+
+
+ // make the talk-to NPC stand still
+ rAssert( npc );
+ static_cast<NPCController*>(npc->GetController())->TransitToState( NPCController::TALKING_WITH_PLAYER );
+
+ tName name = npc->GetNameObject();
+ ReplaceMissionBriefingBitmap( name );
+ break;
+ }
+
+ case EVENT_PC_TALK:
+ {
+ if( InConversation() )
+ {
+ ++mDialogLineNumber;
+ tName target = GetCameraTargetForLineOfDialog( mDialogLineNumber );
+ if( target == tName( "NONE" ) )
+ {
+ ConversationCam::UsePcCam();
+ }
+ else
+ {
+ ConversationCam::SetCameraByName( target );
+ }
+ mp_PCAnimator->PlaySpecialAmbientAnimation();
+ mp_NPCAnimator->PlaySpecialAmbientAnimation();
+ }
+ else
+ {
+ Avatar* av = GetAvatarManager()->GetAvatarForPlayer( 0 );
+ Character* character = av->GetCharacter();
+ mp_PCAnimator->SetCharacter( character );
+
+ }
+ mp_PCAnimator->StartTalking();
+ break;
+ }
+ case EVENT_PC_SHUTUP:
+ {
+ mp_PCAnimator->StopTalking();
+ break;
+ }
+ case EVENT_NPC_TALK:
+ {
+ if( InConversation() )
+ {
+ ++mDialogLineNumber;
+ const tName& target = GetCameraTargetForLineOfDialog( mDialogLineNumber );
+ if( target == tName( "NONE" ) )
+ {
+ ConversationCam::UseNpcCam();
+ }
+ else
+ {
+ ConversationCam::SetCameraByName( target );
+ }
+ mp_NPCAnimator->PlaySpecialAmbientAnimation();
+ mp_PCAnimator->PlaySpecialAmbientAnimation();
+ }
+ else
+ {
+ Character* character = reinterpret_cast< Character* >( pEventData );
+ mp_NPCAnimator->SetCharacter( character );
+ }
+ mp_NPCAnimator->StartTalking();
+ break;
+ }
+ case EVENT_NPC_SHUTUP:
+ {
+ mp_NPCAnimator->StopTalking();
+ if( !InConversation() )
+ {
+ mp_NPCAnimator->SetCharacter( NULL );
+ }
+ break;
+ }
+
+ case EVENT_CONVERSATION_SKIP:
+ {
+ //
+ // Eventually this will take us to CONVERSATION_DONE
+ //
+ mInConversation = false;
+ break;
+ }
+ case EVENT_CONVERSATION_DONE:
+ {
+ //change camera to previous
+
+ if ( GetGameplayManager()->GetCurrentMission()->DialogueCharactersTeleported() )
+ {
+ GetSuperCamManager()->GetSCC(PLAYER_ONE)->SelectSuperCam(mOldCamIndexNum, SuperCamCentral::CUT, 0);
+ }
+ else
+ {
+ GetSuperCamManager()->GetSCC(PLAYER_ONE)->SelectSuperCam(mOldCamIndexNum, 0);
+ }
+
+ // resume walking...
+ Character* npc = mp_NPCAnimator->GetCharacter();
+ if( npc )
+ {
+ static_cast<NPCController*>(npc->GetController())->TransitToState( NPCController::STOPPED );
+ }
+
+ //TO DO stop eyeblinking.
+
+ mInConversation = false;
+ if ( mp_PCAnimator->GetCharacter() != NULL)
+ {
+ mp_PCAnimator->StopTalking();
+ mp_PCAnimator->SetCharacter(NULL);
+ }
+
+ if ( mp_NPCAnimator->GetCharacter() != NULL)
+ {
+ mp_NPCAnimator->StopTalking();
+ mp_NPCAnimator->SetCharacter(NULL);
+ }
+
+
+
+ break;
+ }
+ default:
+ {
+ // don't be lazy! handle the event!
+ rAssert( false );
+ }
+ }
+}
+
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// PresentationManager::AddToQueue
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( PresentationEvent* pEvent )
+//
+// Return: void
+//
+//=============================================================================
+void PresentationManager::AddToQueue( PresentationEvent* pEvent )
+{
+ // if you hit this assert then chances are the presentation queue is full
+ rAssert( mFIFOEnd < MAX_EVENT_SIZE );
+ rAssert( mEventFIFO[ mFIFOEnd ] == NULL );
+
+ mEventFIFO[ mFIFOEnd ] = pEvent;
+
+ mFIFOEnd++;
+ if( mFIFOEnd >= MAX_EVENT_SIZE )
+ {
+ mFIFOEnd = 0;
+ }
+}
+
+//=============================================================================
+// PresentationManager::ReturnToPool
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( PresentationEvent* presevent )
+//
+// Return: void
+//
+//=============================================================================
+void PresentationManager::ReturnToPool( PresentationEvent* presevent )
+{
+ // change to use appropriate pool without doing it the dumb way
+ mFMVPool->ReturnToPool( (unsigned int)presevent );
+ mNISPool->ReturnToPool( (unsigned int)presevent );
+ mTransitionPool->ReturnToPool( (unsigned int)presevent );
+}
+
+//=============================================================================
+// PresentationManager::GetFirst
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: PresentationEvent
+//
+//=============================================================================
+PresentationEvent* PresentationManager::GetFirst()
+{
+ rAssert( mFIFOBegin < MAX_EVENT_SIZE );
+
+ if( mEventFIFO[ mFIFOBegin ] != NULL )
+ {
+ PresentationEvent* pEvent = mEventFIFO[ mFIFOBegin ];
+
+ mEventFIFO[ mFIFOBegin ] = NULL;
+
+ mFIFOBegin++;
+ if( mFIFOBegin >= MAX_EVENT_SIZE )
+ {
+ mFIFOBegin = 0;
+ }
+
+ return( pEvent );
+ }
+ else
+ {
+ return( NULL );
+ }
+}
+
+
+//Do stuff once we are in the gameplay context
+void PresentationManager::OnGameplayStart()
+{
+ //get ptr to the Players Avatar
+ mp_PCAnimator->SetCharacter(GetCharacterManager()->GetCharacter(0) );
+}
+
+void PresentationManager::OnGameplayStop()
+{
+}
+
+//=============================================================================
+// PresentationManager::SetCamerasForLineOfDialog
+//=============================================================================
+// Description: sets the cameras for specific lines of dialog
+//
+// Parameters: names - a vector of names that represnet cameras for lines of
+// dialog
+//
+// Return: NONE
+//
+//=============================================================================
+void PresentationManager::SetCamerasForLineOfDialog( const TNAMEVECTOR& names )
+{
+ #ifdef RAD_DEBUG
+ size_t size = names.size();
+ size_t i;
+ for( i = 0; i < size; ++i )
+ {
+ tName name = names[ i ];
+ }
+ #endif
+ mCameraForLineOfDialog.erase( mCameraForLineOfDialog.begin(), mCameraForLineOfDialog.end() );
+ mCameraForLineOfDialog.insert( mCameraForLineOfDialog.begin(), names.begin(), names.end() );
+}
+
+//=============================================================================
+// PresentationManager::InConversation()
+//=============================================================================
+// Description: determines if the game is in a conversation or not
+//
+// Parameters: NONE
+//
+// Return: bool - are we in a conversation or not?
+//
+//=============================================================================
+bool PresentationManager::InConversation() const
+{
+ return mInConversation;
+}
+
+//=============================================================================
+// PresentationManager::StopAll
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void PresentationManager::StopAll()
+{
+#ifdef RAD_WIN32
+ mpFMVPlayer->ForceStop();
+#else
+ mpFMVPlayer->Stop();
+#endif
+ mpNISPlayer->Stop();
+ mpTransitionPlayer->Stop();
+ mpCameraPlayer->Stop();
+}
+
+PresentationOverlay::PresentationOverlay() :
+mAlpha( 0.0f ),
+mInvDuration( 0.0f ),
+mStart( BLACK_TRANSPARENT ),
+mEnd( BLACK_TRANSPARENT ),
+mFrameCount( -1 ),
+mIsAutoRemove( false )
+{}
+
+void PresentationOverlay::Update( unsigned int ElapsedTime )
+{
+ if( mFrameCount == 0 )
+ {
+ mAlpha = 0.0f;
+ mInvDuration = 0.0f;
+ mFrameCount = -1;
+ if( mIsAutoRemove )
+ {
+ RenderLayer* rl = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot );
+ rAssert( rl );
+ rl->RemoveGuts( this );
+ rl->Freeze();
+ mIsAutoRemove = false;
+ }
+ }
+ else if( mAlpha > 0.0f )
+ {
+ mAlpha -= ( (float)ElapsedTime * mInvDuration );
+ if( mAlpha < 0.0f )
+ {
+ mAlpha = 0.0f;
+ mInvDuration = 0.0f;
+ if( mIsAutoRemove )
+ {
+ RenderLayer* rl = GetRenderManager()->mpLayer( RenderEnums::PresentationSlot );
+ rAssert( rl );
+ rl->RemoveGuts( this );
+ rl->Freeze();
+ mIsAutoRemove = false;
+ }
+ }
+ }
+}
+
+void PresentationOverlay::Display( void )
+{
+ // First check if anything is visible...
+ int alpha = 0;
+ if( mFrameCount == -1 )
+ {
+ alpha = int( ( mStart.Alpha() * mAlpha ) + ( mEnd.Alpha() * ( 1.0f - mAlpha ) ) );
+ }
+ else
+ {
+ --mFrameCount;
+ if( mFrameCount < 0 )
+ {
+ mFrameCount = 0;
+ }
+ alpha = mEnd.Alpha();
+ }
+ if( alpha <= 0 )
+ {
+ return;
+ }
+ // Now figure out the colour.
+ tColour c;
+ if( mFrameCount == -1 )
+ {
+ int red = int( ( mStart.Red() * mAlpha ) + ( mEnd.Red() * ( 1.0f - mAlpha ) ) );
+ int green = int( ( mStart.Green() * mAlpha ) + ( mEnd.Green() * ( 1.0f - mAlpha ) ) );
+ int blue = int( ( mStart.Blue() * mAlpha ) + ( mEnd.Blue() * ( 1.0f - mAlpha ) ) );
+ c.Set( red, green, blue, alpha );
+ }
+ else
+ {
+ c.c = mEnd.c;
+ }
+
+ // Let's draw poly!
+ p3d::stack->Push();
+ bool oldZWrite = p3d::pddi->GetZWrite();
+ pddiCompareMode oldZComp = p3d::pddi->GetZCompare();
+ if( oldZWrite )
+ {
+ p3d::pddi->SetZWrite( false );
+ }
+ if( oldZComp != PDDI_COMPARE_ALWAYS )
+ {
+ p3d::pddi->SetZCompare( PDDI_COMPARE_ALWAYS );
+ }
+ p3d::stack->LoadIdentity();
+ p3d::pddi->SetProjectionMode( PDDI_PROJECTION_ORTHOGRAPHIC );
+ pddiColour oldAmbient = p3d::pddi->GetAmbientLight();
+ p3d::pddi->SetAmbientLight( pddiColour( 255, 255, 255 ) );
+
+ pddiPrimStream* overlay = 0;
+
+ pddiShader* overlayShader = BootupContext::GetInstance()->GetSharedShader();
+ rAssert( overlayShader );
+
+ overlayShader->SetInt( PDDI_SP_BLENDMODE, PDDI_BLEND_ALPHA );
+ overlayShader->SetInt( PDDI_SP_ISLIT, 0 );
+ overlayShader->SetInt( PDDI_SP_SHADEMODE, PDDI_SHADE_FLAT );
+ overlayShader->SetInt( PDDI_SP_TWOSIDED, 1 );
+
+ overlay = p3d::pddi->BeginPrims( overlayShader, PDDI_PRIM_TRISTRIP, PDDI_V_C, 4 );
+
+ overlay->Colour( c );
+ overlay->Coord( 0.5f, -0.5f, 1.0f );
+ overlay->Colour( c );
+ overlay->Coord( -0.5f, -0.5f, 1.0f );
+ overlay->Colour( c );
+ overlay->Coord( 0.5f, 0.5f, 1.0f );
+ overlay->Colour( c );
+ overlay->Coord( -0.5f, 0.5f, 1.0f );
+
+ p3d::pddi->EndPrims( overlay );
+ p3d::pddi->SetProjectionMode(PDDI_PROJECTION_PERSPECTIVE);
+ p3d::pddi->SetAmbientLight( oldAmbient );
+ if( oldZWrite )
+ {
+ p3d::pddi->SetZWrite( true );
+ }
+ if( oldZComp != PDDI_COMPARE_ALWAYS )
+ {
+ p3d::pddi->SetZCompare( oldZComp );
+ }
+ p3d::stack->Pop();
+}
+
+//=============================================================================
+// PresentationManager::CheckRaceMissionBitmaps
+//=============================================================================
+// Description: updates bitmaps on the mission start screen if we're entering
+// a race mission
+//
+// Parameters: none7
+//
+// Return: void
+//
+//=============================================================================
+void PresentationManager::CheckRaceMissionBitmaps()
+{
+}
+
+//=============================================================================
+// PresentationManager::ReplaceMissionBriefingBitmap
+//=============================================================================
+// Description: depending on who we're talking to, we need to replace the
+// picture on the mission briefing screen
+//
+// Parameters: conversationCharacterName - name of the character that led to
+// this screen
+//
+// Return: void
+//
+//=============================================================================
+void PresentationManager::ReplaceMissionBriefingBitmap( const tName& conversationCharacterName )
+{
+ const tName& name = conversationCharacterName;
+
+ //
+ // These are for the race missions
+ //
+ if( name == "b_nelson" )
+ {
+ CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_CT.p3d" );
+ CGuiScreenMissionLoad::ClearBitmap();
+ }
+ else if( name == "b_milhouse" )
+ {
+ CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_TT.p3d" );
+ CGuiScreenMissionLoad::ClearBitmap();
+ }
+ else if( name == "b_ralph" )
+ {
+ CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_CP.p3d" );
+ CGuiScreenMissionLoad::ClearBitmap();
+ }
+ else if( name == "b_louie" )
+ {
+ CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_GB.p3d" );
+ CGuiScreenMissionLoad::ClearBitmap();
+ }
+ else if( name == "b_witch" )
+ {
+ CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_HW.p3d" );
+ CGuiScreenMissionLoad::ClearBitmap();
+ }
+ else if( name == "b_zfem1" )
+ {
+ CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_HW.p3d" );
+ CGuiScreenMissionLoad::ClearBitmap();
+ }
+ else if( name == "b_zmale1" )
+ {
+ CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_HW.p3d" );
+ CGuiScreenMissionLoad::ClearBitmap();
+ }
+ else if( name == "b_zmale3" )
+ {
+ CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/misXX_HW.p3d" );
+ CGuiScreenMissionLoad::ClearBitmap();
+ }
+
+ //
+ // these are for the bonus missions
+ //
+ else if( name == "b_cletus")
+ {
+ CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/mis01_08.p3d" );
+ CGuiScreenMissionLoad::ClearBitmap();
+ }
+ else if( name == "b_grandpa")
+ {
+ CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/mis02_08.p3d" );
+ CGuiScreenMissionLoad::ClearBitmap();
+ }
+ else if( name == "b_skinner")
+ {
+ CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/mis03_08.p3d" );
+ CGuiScreenMissionLoad::ClearBitmap();
+ }
+ else if( name == "b_cbg")
+ {
+ CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/mis04_08.p3d" );
+ CGuiScreenMissionLoad::ClearBitmap();
+ }
+ else if( name == "b_frink")
+ {
+ CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/mis05_08.p3d" );
+ CGuiScreenMissionLoad::ClearBitmap();
+ }
+ else if( name == "b_snake")
+ {
+ CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/mis06_08.p3d" );
+ CGuiScreenMissionLoad::ClearBitmap();
+ }
+ else if( name == "b_smithers")
+ {
+ CGuiScreenMissionLoad::SetBitmapName( "art/frontend/dynaload/images/mis07_08.p3d" );
+ CGuiScreenMissionLoad::ClearBitmap();
+ }
+ else
+ {
+ return;
+ }
+
+ //
+ // Trigger an update of the picture via scrooby
+ //
+ CGuiScreenMissionLoad::ReplaceBitmap();
+}
+
+//=============================================================================
+// PresentationManager::MakeCharactersFaceEachOther
+//=============================================================================
+// Description: depending on who we're talking to, we need to replace the
+// picture on the mission briefing screen
+//
+// Parameters: c1, c2 - the two characters that we want to face each other
+//
+// Return: void
+//
+//=============================================================================
+void PresentationManager::MakeCharactersFaceEachOther( Character* c0, Character* c1 )
+{
+ rmt::Vector position0;
+ rmt::Vector position1;
+
+ c0->GetPosition( &position0 );
+ c1->GetPosition( &position1 );
+ rmt::Vector offset = position1 - position0;
+ offset.Normalize();
+ float rotation = choreo::GetWorldAngle( offset.x, offset.z );
+ c0->RelocateAndReset( position0, rotation, false );
+ c1->RelocateAndReset( position1, rotation + rmt::PI, false );
+}
diff --git a/game/code/presentation/presentation.h b/game/code/presentation/presentation.h
new file mode 100644
index 0000000..659c181
--- /dev/null
+++ b/game/code/presentation/presentation.h
@@ -0,0 +1,217 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: .h
+//
+// Description: Blahblahblah
+//
+// History: 16/04/2002 + Created -- NAME
+//
+//=============================================================================
+
+#ifndef PRESENTATIONMANAGER_H
+#define PRESENTATIONMANAGER_H
+
+//========================================
+// Nested Includes
+//========================================
+
+#include <radmath/radmath.hpp>
+#include <p3d/entity.hpp>
+#include <p3d/drawable.hpp>
+#include <events/eventlistener.h>
+
+#include <memory/allocpool.h>
+#include <memory/stlallocators.h>
+//#include <presentation/language.h>
+#include <presentation/presevents/fmvevent.h>
+#include <presentation/presevents/nisevent.h>
+#include <presentation/presevents/presentationevent.h>
+#include <presentation/presevents/transevent.h>
+
+#include <render/enums/renderenums.h>
+#include <vector>
+
+//========================================
+// Forward References
+//========================================
+class Character;
+class NISPlayer;
+class FMVPlayer;
+class CameraPlayer;
+class TransitionPlayer;
+class PlayerDrawable;
+class SuperCam;
+class PresentationAnimator;
+
+//========================================
+// typedefs
+//========================================
+
+typedef AllocPool< FMVEvent > FMVEventPool;
+typedef AllocPool< NISEvent > NISEventPool;
+typedef AllocPool< TransitionEvent > TransitionEventPool;
+
+//=============================================================================
+//
+// Synopsis: Blahblahblah
+//
+//=============================================================================
+
+/*=============================================================================
+ This drawable is used to a poly over the camera to fade out the scene, etc.
+This was being done by the frontend, but it relies on a scrooby project being
+loaded and while playing a movie during game play we don't have that.
+ This could also be used for putting a texture over the screen, but that's not
+implemented at this time.
+=============================================================================*/
+const tColour BLACK( 0x00, 0x00, 0x00, 0xFF );
+const tColour WHITE( 0xFF, 0xFF, 0xFF, 0xFF );
+const tColour BLACK_TRANSPARENT( 0x00, 0x00, 0x00, 0x00 );
+const tColour WHITE_TRANSPARENT( 0xFF, 0xFF, 0xFF, 0x00 );
+class PresentationOverlay : public tDrawable
+{
+public:
+ PresentationOverlay();
+
+ virtual void Display();
+ void Update( unsigned int ElapsedTime );
+
+ void SetStart( tColour Colour ) { mStart = Colour; }
+ void SetEnd( tColour Colour ) { mEnd = Colour; }
+ // Note setting the duration begins the fading from one colour to another.
+ void SetDuration( float Duration ) { mInvDuration = 0.001f / Duration; mAlpha = 1.0f; mFrameCount = -1; }
+ void SetFrames( int FrameCount ) { mFrameCount = FrameCount; } // Hold start colour for this many frames.
+ float GetAlpha( void ) const { return mAlpha; }
+ void SetRemoveOnComplete( bool AutoRemove ) { mIsAutoRemove = AutoRemove; }
+
+protected:
+ float mAlpha;
+ float mInvDuration;
+ tColour mStart;
+ tColour mEnd;
+ int mFrameCount;
+ bool mIsAutoRemove : 1;
+};
+
+class PresentationManager : public EventListener,
+ public PresentationEvent::PresentationEventCallBack,
+ public LoadingManager::ProcessRequestsCallback
+{
+ public:
+ // Static Methods for accessing this singleton.
+ static PresentationManager* CreateInstance();
+ static PresentationManager* GetInstance();
+ static void DestroyInstance();
+
+ void Initialize();
+ void Finalize();
+ void OnGameplayStart();
+ void OnGameplayStop();
+
+ void InitializePlayerDrawable();
+ void FinalizePlayerDrawable();
+
+ // Free frontend, play movie, reload frontend.
+ void PlayFMV( const char* FileName, PresentationEvent::PresentationEventCallBack* pCallback = 0,
+ bool IsSkippable = true,
+ bool StopMusic = false,
+ bool IsLocalized = true );
+
+ // Creates an event and passes it back. Adds this event to the queue.
+ void QueueFMV( FMVEvent** pFMVEvent,
+ PresentationEvent::PresentationEventCallBack* pCallback );
+
+ // Creates an event and passes it back. Adds this event to the queue.
+ void QueueNIS( NISEvent** pNISEvent,
+ PresentationEvent::PresentationEventCallBack* pCallback );
+
+ // Creates an event and passes it back. Adds this event to the queue.
+ void QueueTransition( TransitionEvent** pTransitionEvent,
+ PresentationEvent::PresentationEventCallBack* pCallback );
+
+ // Scales the p3d stack by 11.9
+ void ClearQueue();
+ bool IsQueueEmpty() { return( mEventFIFO[ mFIFOBegin ] == NULL ); }
+ bool IsBusy(void) const;
+
+ void Update( unsigned int elapsedTime );
+
+ FMVPlayer* GetFMVPlayer() { return( mpFMVPlayer ); }
+ NISPlayer* GetNISPlayer() { return( mpNISPlayer ); }
+ TransitionPlayer* GetTransPlayer() { return( mpTransitionPlayer ); }
+ CameraPlayer* GetCameraPlayer() {return( mpCameraPlayer ); }
+
+ virtual void HandleEvent( EventEnum id, void* pEventData );
+ PresentationAnimator* GetAnimatorNpc();
+ PresentationAnimator* GetAnimatorPc();
+ typedef std::vector< tName, s2alloc<tName> > TNAMEVECTOR;
+ void SetCamerasForLineOfDialog( const TNAMEVECTOR& names );
+ bool InConversation() const;
+ void StopAll();
+ void CheckRaceMissionBitmaps();
+ void ReplaceMissionBriefingBitmap( const tName& conversationCharacterName );
+ void MakeCharactersFaceEachOther( Character* c0, Character* c1 );
+
+ protected:
+ void AddToQueue( PresentationEvent* pEvent );
+ const tName GetCameraTargetForLineOfDialog( const unsigned int lineOfDialog ) const;
+ void ReturnToPool( PresentationEvent* presevent );
+
+ virtual void OnPresentationEventBegin( PresentationEvent* pEvent );
+ virtual void OnPresentationEventLoadComplete( PresentationEvent* pEvent );
+ virtual void OnPresentationEventEnd( PresentationEvent* pEvent );
+ virtual void OnProcessRequestsComplete( void* pUserData );
+
+ // Gets the first event in the queue
+ PresentationEvent* GetFirst();
+ private:
+ PresentationManager();
+ virtual ~PresentationManager();
+
+ //Prevent wasteful constructor creation.
+ PresentationManager( const PresentationManager& presentationManager );
+ PresentationManager& operator=( const PresentationManager& presentationManager );
+
+ // Pointer to the one and only instance of this singleton.
+ static PresentationManager* spInstance;
+
+ TransitionEventPool* mTransitionPool;
+ NISEventPool* mNISPool;
+ FMVEventPool* mFMVPool;
+
+ SuperCam* mp_oldcam;
+ unsigned int mOldCamIndexNum;
+
+
+ // Very simple implementation of a queue. I don't actually
+ // even know if it works.
+ static const unsigned int MAX_EVENT_SIZE = 10;
+ PresentationEvent* mEventFIFO[ MAX_EVENT_SIZE ];
+ unsigned int mFIFOBegin;
+ unsigned int mFIFOEnd;
+
+ PresentationEvent* mpCurrent;
+
+ FMVPlayer* mpFMVPlayer;
+ NISPlayer* mpNISPlayer;
+ CameraPlayer* mpCameraPlayer;
+ TransitionPlayer* mpTransitionPlayer;
+
+ PlayerDrawable* mpPlayerDrawable;
+ PresentationAnimator* mp_PCAnimator;
+ PresentationAnimator* mp_NPCAnimator;
+// Language::Language mLanguage;
+ int mDialogLineNumber;
+ TNAMEVECTOR mCameraForLineOfDialog;
+ PresentationEvent::PresentationEventCallBack* mpPlayCallback;
+ bool mInConversation : 1;
+ bool mWaitingOnFade : 1;
+ PresentationOverlay* mOverlay;
+};
+
+// A little syntactic sugar for getting at this singleton.
+inline PresentationManager* GetPresentationManager() { return( PresentationManager::GetInstance() ); }
+
+#endif //PRESENTATIONMANAGER_H
+
diff --git a/game/code/presentation/presentationanimator.cpp b/game/code/presentation/presentationanimator.cpp
new file mode 100644
index 0000000..a719030
--- /dev/null
+++ b/game/code/presentation/presentationanimator.cpp
@@ -0,0 +1,367 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: PresentationAnimator.cpp
+//
+// Description: Implement PresentationAnimator
+//
+// History: 9/24/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include <ai/sequencer/actioncontroller.h>
+#include <ai/sequencer/action.h>
+#include <memory/srrmemory.h>
+
+#include <presentation/blinker.h>
+#include <presentation/mouthflapper.h>
+#include <presentation/presentationanimator.h>
+
+#include <worldsim/character/character.h>
+#include <vector>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//=============================================================================
+// Forward Declarations
+//=============================================================================
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// PresentationAnimator::PresentationAnimator
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+PresentationAnimator::PresentationAnimator():
+ mCharacter( NULL ),
+ mMouthFlapper( NULL ),
+ mRandomSelection( true ),
+ mTalkTime(0)
+{
+ MEMTRACK_PUSH_GROUP( "PresentationAnimator" );
+ mMouthFlapper = new(GMA_LEVEL_OTHER) MouthFlapper();
+ mMouthFlapper->AddRef();
+ MEMTRACK_POP_GROUP( "PresentationAnimator" );
+}
+
+//==============================================================================
+// PresentationAnimator::~PresentationAnimator
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+PresentationAnimator::~PresentationAnimator()
+{
+ mMouthFlapper->Release();
+}
+//=============================================================================
+// PresentationAnimator::AddAmbientAnimations
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( Character* pCharacter )
+//
+// Return: void
+//
+//=============================================================================
+void PresentationAnimator::AddAmbientAnimations( const TNAMEVECTOR& animations )
+{
+ if( !animations.empty() )
+ {
+ mAnimationNames.erase( mAnimationNames.begin(), mAnimationNames.end() );
+ mAnimationNames.insert( mAnimationNames.begin(), animations.begin(), animations.end() );
+ }
+}
+
+//=============================================================================
+// PresentationAnimator::ClearAmbientAnimations
+//=============================================================================
+// Description: Comment
+//
+// Parameters:
+//
+// Return: void
+//
+//=============================================================================
+void PresentationAnimator::ClearAmbientAnimations( void )
+{
+ mAnimationNames.erase( mAnimationNames.begin(), mAnimationNames.end() );
+}
+
+
+//=============================================================================
+// PresentationAnimator::ChooseNextAnimation
+//=============================================================================
+// Description: Chooses the next animation from a list of animation names
+//
+// Parameters: NONE
+//
+// Return: tName - the name of the animation chosen
+//
+//=============================================================================
+const tName PresentationAnimator::ChooseNextAnimation()
+{
+ size_t size = mAnimationNames.size();
+ if( size == 0 )
+ {
+ return tName( "NONE" );
+ }
+ else
+ {
+ tName returnMe = mAnimationNames[ 0 ];
+ mAnimationNames.erase( mAnimationNames.begin() );
+ return returnMe;
+ }
+}
+
+//=============================================================================
+// PresentationAnimator::ChooseRandomAnimation
+//=============================================================================
+// Description: Chooses a random animation from the vector of potential
+// animation names that have been set in the script
+//
+// Parameters: NONE
+//
+// Return: tName - the name of the animation chosen
+//
+//=============================================================================
+const tName PresentationAnimator::ChooseRandomAnimation() const
+{
+ int size = mAnimationNames.size();
+ if( size == 0 )
+ {
+ return tName( "NONE" );
+ }
+ else
+ {
+ int randomNumber = rand();
+ int selection = randomNumber % size;
+ return mAnimationNames[ selection ];
+ }
+}
+
+//=============================================================================
+// PresentationAnimator::SetCharacter
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( Character* pCharacter )
+//
+// Return: void
+//
+//=============================================================================
+void PresentationAnimator::SetCharacter( Character* pCharacter )
+{
+ mCharacter = pCharacter;
+ mMouthFlapper->SetCharacter( pCharacter );
+}
+
+//=============================================================================
+// PresentationAnimator::GetCharacter
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: Character
+//
+//=============================================================================
+Character* PresentationAnimator::GetCharacter()
+{
+ return mCharacter;
+}
+
+//=============================================================================
+// PresentationAnimator::PlaySpecialAmbientAnimation
+//=============================================================================
+// Description: triggers playing of a special ambient animation - ie homer
+// scratching himself
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void PresentationAnimator::PlaySpecialAmbientAnimation()
+{
+ tName chosenAnimationName;
+ if( mRandomSelection )
+ {
+ chosenAnimationName = ChooseRandomAnimation();
+ }
+ else
+ {
+ chosenAnimationName = ChooseNextAnimation();
+ }
+
+ if( ( chosenAnimationName == "NONE" ) || ( chosenAnimationName == "none" ) )
+ {
+ return;
+ }
+
+ if( mCharacter == NULL )
+ {
+ return;
+ }
+ bool canPlay = mCharacter->CanPlayAnimation( chosenAnimationName );
+ if( canPlay )
+ {
+ ActionController* actionController = mCharacter->GetActionController();
+ rAssert( actionController != NULL );
+ Sequencer* pSeq = actionController->GetNextSequencer();
+ rAssert( pSeq != NULL );
+ if( !pSeq->IsBusy() )
+ {
+ pSeq->BeginSequence();
+ PlayAnimationAction* pAction = 0;
+ pAction = new PlayAnimationAction( mCharacter, chosenAnimationName );
+ pAction->AbortWhenMovementOccurs( true );
+ pSeq->AddAction( pAction );
+ pSeq->EndSequence();
+ }
+ }
+ else
+ {
+ #ifdef RAD_DEBUG
+ const char* characterName = mCharacter->GetNameDangerous();
+ const char* animationName = chosenAnimationName.GetText();
+ rDebugPrintf
+ (
+ "PresentationAnimator::PlaySpecialAmbientAnimation, character'%s' cannont play'%s'\n",
+ characterName,
+ animationName
+ );
+ #endif
+ }
+}
+
+//=============================================================================
+// PresentationAnimator::SetRandomSelection
+//=============================================================================
+// Description: should the animations be chosen in order or randomly from the
+// set of animations
+//
+// Parameters: random - random or not
+//
+// Return: NONE
+//
+//=============================================================================
+void PresentationAnimator::SetRandomSelection( const bool random )
+{
+ mRandomSelection = random;
+}
+
+const bool PresentationAnimator::GetRandomSelection() const
+{
+ return mRandomSelection;
+}
+
+
+//=============================================================================
+// PresentationAnimator::StartTalking
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void PresentationAnimator::StartTalking()
+{
+ if( mCharacter != NULL )
+ {
+ mCharacter->GetPuppet()->GetEngine()->GetPoseEngine()->AddPoseDriver( 2, mMouthFlapper );
+ }
+ mMouthFlapper->SetIsEnabled( true );
+}
+
+//=============================================================================
+// PresentationAnimator::StopTalking
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void PresentationAnimator::StopTalking()
+{
+ mMouthFlapper->SetIsEnabled( false );
+ if( mCharacter != NULL )
+ {
+ mCharacter->GetPuppet()->GetEngine()->GetPoseEngine()->RemovePoseDriver( 2, mMouthFlapper );
+ }
+}
+
+//=============================================================================
+// PresentationAnimator::Talkfor
+//=============================================================================
+void PresentationAnimator::TalkFor(int time)
+{
+ mTalkTime = time;
+ StartTalking();
+}
+
+//=============================================================================
+// PresentationAnimator::Update
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( int elapsedTime )
+//
+// Return: void
+//
+//=============================================================================
+void PresentationAnimator::Update( int elapsedTime )
+{
+ if(mTalkTime > 0)
+ {
+ if((mTalkTime - elapsedTime) < 0)
+ {
+ mTalkTime = 0;
+ StopTalking();
+ }
+ else
+ {
+ mTalkTime -= elapsedTime;
+ }
+ }
+
+
+ //mBlinker->Update( elapsedTime );
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
diff --git a/game/code/presentation/presentationanimator.h b/game/code/presentation/presentationanimator.h
new file mode 100644
index 0000000..b2d455a
--- /dev/null
+++ b/game/code/presentation/presentationanimator.h
@@ -0,0 +1,70 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: presentationanimator.h
+//
+// Description: Blahblahblah
+//
+// History: 9/24/2002 + Created -- NAME
+//
+//=============================================================================
+
+#ifndef PRESENTATIONANIMATOR_H
+#define PRESENTATIONANIMATOR_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <vector>
+
+#include <memory/stlallocators.h>
+
+
+//========================================
+// Forward References
+//========================================
+
+class Character;
+class MouthFlapper;
+
+//=============================================================================
+//
+// Synopsis: PresentationAnimator
+//
+//=============================================================================
+
+class PresentationAnimator
+{
+public:
+ PresentationAnimator();
+ virtual ~PresentationAnimator();
+
+ void SetCharacter( Character* pCharacter );
+ Character* GetCharacter();
+
+ typedef std::vector< tName, s2alloc<tName> > TNAMEVECTOR;
+ void AddAmbientAnimations( const TNAMEVECTOR& animations );
+ void ClearAmbientAnimations( void );
+ void PlaySpecialAmbientAnimation();
+ void SetRandomSelection( const bool random );
+ const bool GetRandomSelection() const;
+ void StartTalking();
+ void StopTalking();
+ void TalkFor(int time);
+ void Update( int elapsedTime );
+
+private:
+ const tName ChooseNextAnimation();
+ const tName ChooseRandomAnimation() const;
+ PresentationAnimator( const PresentationAnimator& presentationanimator );
+ PresentationAnimator& operator=( const PresentationAnimator& presentationanimator );
+
+ Character* mCharacter;
+ MouthFlapper* mMouthFlapper;
+ TNAMEVECTOR mAnimationNames;
+ bool mRandomSelection;
+ int mTalkTime;
+};
+
+
+#endif //PRESENTATIONANIMATOR_H
diff --git a/game/code/presentation/presevents/allpresevents.cpp b/game/code/presentation/presevents/allpresevents.cpp
new file mode 100644
index 0000000..9182536
--- /dev/null
+++ b/game/code/presentation/presevents/allpresevents.cpp
@@ -0,0 +1,4 @@
+#include <presentation/presevents/fmvevent.cpp>
+#include <presentation/presevents/nisevent.cpp>
+#include <presentation/presevents/presentationevent.cpp>
+#include <presentation/presevents/transevent.cpp>
diff --git a/game/code/presentation/presevents/fmvevent.cpp b/game/code/presentation/presevents/fmvevent.cpp
new file mode 100644
index 0000000..70235f0
--- /dev/null
+++ b/game/code/presentation/presevents/fmvevent.cpp
@@ -0,0 +1,74 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: fmvevent.cpp
+//
+// Description: Implement FMVEvent
+//
+// History: 23/05/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+
+//========================================
+// Project Includes
+//========================================
+
+#include <presentation/fmvplayer/fmvplayer.h>
+#include <presentation/presentation.h>
+#include <presentation/presevents/fmvevent.h>
+#include <memory/srrmemory.h>
+#include <render/rendermanager/rendermanager.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+FMVEvent::FMVEvent () : PresentationEvent ()
+{
+}
+
+
+FMVEvent::~FMVEvent ()
+{
+}
+
+
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// FMVEvent::GetPlayer
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: AnimationPlayer
+//
+//=============================================================================
+AnimationPlayer* FMVEvent::GetPlayer()
+{
+ return( GetPresentationManager()->GetFMVPlayer() );
+}
+
+FMVEvent::FMVEventData::FMVEventData() : AudioIndex( 0 ), Allocator( GMA_LEVEL_MOVIE ), KillMusic( false )
+{
+} \ No newline at end of file
diff --git a/game/code/presentation/presevents/fmvevent.h b/game/code/presentation/presevents/fmvevent.h
new file mode 100644
index 0000000..498d0a1
--- /dev/null
+++ b/game/code/presentation/presevents/fmvevent.h
@@ -0,0 +1,62 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: .h
+//
+// Description: Blahblahblah
+//
+// History: 23/05/2002 + Created -- NAME
+//
+//=============================================================================
+
+#ifndef FMVEVENT_H
+#define FMVEVENT_H
+
+//========================================
+// Nested Includes
+//========================================
+
+#include <presentation/presevents/presentationevent.h>
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: Blahblahblah
+//
+//=============================================================================
+
+class FMVEvent : public PresentationEvent
+{
+ public:
+ FMVEvent ();
+ virtual ~FMVEvent ();
+
+ AnimationPlayer* GetPlayer();
+ void SetAudioIndex(unsigned int idx) { mData.AudioIndex = idx; }
+ void SetAllocator( GameMemoryAllocator Alloc ) { mData.Allocator = Alloc; }
+ void KillMusic() { mData.KillMusic = true; }
+
+ struct FMVEventData
+ {
+ FMVEventData();
+ unsigned int AudioIndex;
+ GameMemoryAllocator Allocator;
+ bool KillMusic;
+ };
+
+ static const unsigned int AUDIO_INDEX_ENGLISH = 0;
+ static const unsigned int AUDIO_INDEX_FRENCH = 1;
+ static const unsigned int AUDIO_INDEX_GERMAN = 2;
+ static const unsigned int AUDIO_INDEX_SPANISH = 3;
+
+ protected:
+ void* GetUserData () { return reinterpret_cast<void*>(&mData); }
+
+ FMVEventData mData;
+};
+
+#endif //FMVEVENT_H
+
diff --git a/game/code/presentation/presevents/nisevent.cpp b/game/code/presentation/presevents/nisevent.cpp
new file mode 100644
index 0000000..f549d7e
--- /dev/null
+++ b/game/code/presentation/presevents/nisevent.cpp
@@ -0,0 +1,229 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: NISevent.cpp
+//
+// Description: Implement NISEvent
+//
+// History: 23/05/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+
+//========================================
+// Project Includes
+//========================================
+
+#include <presentation/animplayer.h>
+#include <presentation/cameraplayer.h>
+#include <presentation/nisplayer.h>
+#include <presentation/presentation.h>
+#include <presentation/presevents/nisevent.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// NISEvent::NISEvent
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: NISEvent
+//
+//=============================================================================
+NISEvent::NISEvent()
+{
+ type = NIS_SCENEGRAPH;
+}
+
+//=============================================================================
+// NISEvent::~NISEvent
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: NISEvent
+//
+//=============================================================================
+NISEvent::~NISEvent()
+{
+}
+
+//=============================================================================
+// NISEvent::LoadNow
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void NISEvent::LoadNow()
+{
+ AnimationPlayer* player = GetPlayer();
+
+ SetNames();
+
+ player->LoadData( fileName, false, GetUserData() );
+
+ player->SetPlayAfterLoad( false );
+
+ SetLoaded( true );
+}
+
+//=============================================================================
+// NISEvent::LoadFromInventory
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void NISEvent::LoadFromInventory()
+{
+ AnimationPlayer* player = GetPlayer();
+
+ SetNames();
+
+ player->LoadData( fileName, true, GetUserData() );
+
+ SetClearWhenDone( false );
+ SetLoaded( true );
+}
+
+//=============================================================================
+// NISEvent::Init
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void NISEvent::Init()
+{
+ PresentationEvent::Init();
+
+ mbHasSetNames = false;
+}
+
+//=============================================================================
+// NISEvent::Start
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void NISEvent::Start()
+{
+ SetNames();
+
+ PresentationEvent::Start();
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// NISEvent::Update
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( unsigned int elapsedTime )
+//
+// Return: void
+//
+//=============================================================================
+AnimationPlayer* NISEvent::GetPlayer()
+{
+ AnimationPlayer* player = NULL;
+
+ switch( type )
+ {
+ case NIS_CAMERA:
+ {
+ player = GetPresentationManager()->GetCameraPlayer();
+ break;
+ }
+ case NIS_SCENEGRAPH:
+ {
+ player = GetPresentationManager()->GetNISPlayer();
+ break;
+ }
+ default:
+ {
+ // trouble!
+ rAssert( false );
+ break;
+ }
+ }
+
+ return( player );
+}
+
+//=============================================================================
+// NISEvent::SetNames
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void NISEvent::SetNames()
+{
+ if( !mbHasSetNames )
+ {
+ mbHasSetNames = true;
+
+ switch( type )
+ {
+ case NIS_CAMERA:
+ {
+ CameraPlayer* player = GetPresentationManager()->GetCameraPlayer();
+ player->SetNameData( controller, camera, animation );
+ break;
+ }
+ case NIS_SCENEGRAPH:
+ {
+ NISPlayer* player = GetPresentationManager()->GetNISPlayer();
+ player->SetNameData( controller, camera, animation );
+ break;
+ }
+ default:
+ {
+ // trouble!
+ rAssert( false );
+ break;
+ }
+ }
+ }
+}
diff --git a/game/code/presentation/presevents/nisevent.h b/game/code/presentation/presevents/nisevent.h
new file mode 100644
index 0000000..6b1e684
--- /dev/null
+++ b/game/code/presentation/presevents/nisevent.h
@@ -0,0 +1,66 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: .h
+//
+// Description: Blahblahblah
+//
+// History: 23/05/2002 + Created -- NAME
+//
+//=============================================================================
+
+#ifndef NISEVENT_H
+#define NISEVENT_H
+
+//========================================
+// Nested Includes
+//========================================
+
+#include <presentation/presevents/presentationevent.h>
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: Blahblahblah
+//
+//=============================================================================
+
+class NISEvent : public PresentationEvent
+{
+ public:
+ NISEvent();
+ ~NISEvent();
+
+ enum NISType
+ {
+ NIS_CAMERA,
+ NIS_SCENEGRAPH,
+ NUM_NIS_TYPES
+ };
+
+ NISType type;
+
+ char controller[32];
+ char camera[32];
+ char animation[32];
+
+ void LoadNow();
+ void LoadFromInventory();
+
+ AnimationPlayer* GetPlayer();
+
+ virtual void Init();
+
+ virtual void Start();
+ protected:
+ private:
+ void SetNames();
+
+ bool mbHasSetNames;
+};
+
+#endif //NISEVENT_H
+
diff --git a/game/code/presentation/presevents/presentationevent.cpp b/game/code/presentation/presevents/presentationevent.cpp
new file mode 100644
index 0000000..dd26a66
--- /dev/null
+++ b/game/code/presentation/presevents/presentationevent.cpp
@@ -0,0 +1,180 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: presentationevent.cpp
+//
+// Description: Implement PresentationEvent
+//
+// History: 22/05/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+
+// Foundation Tech
+#include <raddebug.hpp>
+
+//========================================
+// Project Includes
+//========================================
+
+#include <presentation/animplayer.h>
+#include <presentation/presevents/presentationevent.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// PresentationEvent::PresentationEvent
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+PresentationEvent::PresentationEvent()
+{
+ Init();
+}
+
+//==============================================================================
+// PresentationEvent::~PresentationEvent
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+PresentationEvent::~PresentationEvent()
+{
+
+}
+
+
+//==============================================================================
+// PresentationEvent::OnLoadDataComplete
+//==============================================================================
+//
+// Description:
+//
+// Parameters:
+//
+// Return:
+//
+//==============================================================================
+void PresentationEvent::OnLoadDataComplete()
+{
+ if( pCallback != NULL )
+ {
+ pCallback->OnPresentationEventLoadComplete( this );
+ }
+}
+
+//=============================================================================
+// PresentationEvent::Update
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( unsigned int elapsedTime )
+//
+// Return: bool
+//
+//=============================================================================
+bool PresentationEvent::Update( unsigned int elapsedTime )
+{
+ AnimationPlayer* player = GetPlayer();
+
+ player->Update( elapsedTime );
+
+ return( player->IsPlaying() );
+}
+
+//=============================================================================
+// PresentationEvent::Start
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void PresentationEvent::Start()
+{
+ AnimationPlayer* player = GetPlayer();
+
+ if( !mbLoaded )
+ {
+ player->LoadData( fileName, this, false, GetUserData() );
+
+ mbLoaded = true;
+ }
+ player->SetKeepLayersFrozen( mbKeepLayersFrozen );
+ player->SetSkippable(mbIsSkippable);
+ player->Play();
+}
+
+//=============================================================================
+// PresentationEvent::Stop
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void PresentationEvent::Stop()
+{
+ AnimationPlayer* player = GetPlayer();
+
+ if( mbClearWhenDone )
+ {
+ player->ClearData();
+ }
+ else
+ {
+ player->Reset();
+ }
+}
+
+//=============================================================================
+// PresentationEvent::Init
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void PresentationEvent::Init()
+{
+ mbAutoPlay = true;
+ mbClearWhenDone = true;
+ mbLoaded = false;
+ mbKeepLayersFrozen = false;
+ mbIsSkippable = true;
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
diff --git a/game/code/presentation/presevents/presentationevent.h b/game/code/presentation/presevents/presentationevent.h
new file mode 100644
index 0000000..ae007c0
--- /dev/null
+++ b/game/code/presentation/presevents/presentationevent.h
@@ -0,0 +1,107 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: .h
+//
+// Description: Blahblahblah
+//
+// History: 22/05/2002 + Created -- NAME
+//
+//=============================================================================
+
+#ifndef PRESENTATIONEVENT_H
+#define PRESENTATIONEVENT_H
+
+//========================================
+// Nested Includes
+//========================================
+
+#include <events/eventenum.h>
+
+#include <presentation/animplayer.h>
+
+#include <render/enums/renderenums.h>
+
+//========================================
+// Forward References
+//========================================
+
+class AnimationPlayer;
+
+//=============================================================================
+//
+// Synopsis: These classes make it easier for the PresentationManager to
+// queue lots of animations for use on the different players.
+// Keep in mind that the PresentationManager is keeping a bunch
+// of these in a pool so you MUST call Init to reset all the
+// members to their default values.
+//
+//=============================================================================
+
+class PresentationEvent : public AnimationPlayer::LoadDataCallBack
+{
+ public:
+ PresentationEvent();
+ virtual ~PresentationEvent();
+
+ // Implement AnimationPlayer::LoadDataCallBack
+ //
+ virtual void OnLoadDataComplete();
+
+ struct PresentationEventCallBack
+ {
+ virtual void OnPresentationEventBegin( PresentationEvent* pEvent ) = 0;
+ virtual void OnPresentationEventLoadComplete( PresentationEvent* pEvent ) = 0;
+ virtual void OnPresentationEventEnd( PresentationEvent* pEvent ) = 0;
+ };
+
+ PresentationEventCallBack* pCallback;
+ char fileName[64];
+ bool bInInventory;
+
+ // set ClearWhenDone to true to clear all data when this event finishes
+ // or false to leave stuff (like the MoviePlayer) allocated. Default = true
+ void SetClearWhenDone( bool bClear ) { mbClearWhenDone = bClear; }
+
+ // set AutoPlay to true to play animation immediately after loading finsihes
+ // Default = true
+ void SetAutoPlay( bool bAutoPlay ) { mbAutoPlay = bAutoPlay; }
+ bool GetAutoPlay() { return mbAutoPlay; }
+ void SetKeepLayersFrozen( bool IsKeep ) { mbKeepLayersFrozen = IsKeep; }
+ bool GetKeepLayersFrozen( void ) const { return mbKeepLayersFrozen; }
+ void SetSkippable(bool IsSkippable) {mbIsSkippable = IsSkippable;}
+ bool IsSkippable(void) const {return mbIsSkippable;}
+
+ void SetRenderLayer( RenderEnums::LayerEnum layer ) { mRenderLayer = layer; }
+ RenderEnums::LayerEnum GetRenderLayer() { return mRenderLayer; }
+
+ virtual AnimationPlayer* GetPlayer() = 0;
+
+ bool Update( unsigned int elapsedTime );
+
+ virtual void Start();
+ virtual void Stop();
+
+ virtual void Init();
+
+ protected:
+ void SetLoaded( bool bLoaded ) { mbLoaded = bLoaded; }
+
+ virtual void* GetUserData () { return 0; }
+
+ private:
+
+ //Prevent wasteful constructor creation.
+ PresentationEvent( const PresentationEvent& presentationEvent );
+ PresentationEvent& operator=( const PresentationEvent& presentationEvent );
+
+ bool mbAutoPlay : 1;
+ bool mbClearWhenDone : 1;
+ bool mbLoaded : 1;
+ bool mbKeepLayersFrozen : 1;
+ bool mbIsSkippable : 1;
+ RenderEnums::LayerEnum mRenderLayer;
+};
+
+#endif // PRESENTATIONEVENT_H
+
diff --git a/game/code/presentation/presevents/transevent.cpp b/game/code/presentation/presevents/transevent.cpp
new file mode 100644
index 0000000..daea4a1
--- /dev/null
+++ b/game/code/presentation/presevents/transevent.cpp
@@ -0,0 +1,77 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: Transevent.cpp
+//
+// Description: Implement TransEvent
+//
+// History: 23/05/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+
+//========================================
+// Project Includes
+//========================================
+
+#include <presentation/presentation.h>
+#include <presentation/transitionplayer.h>
+#include <presentation/presevents/transevent.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// TransitionEvent::GetPlayer
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: AnimationPlayer
+//
+//=============================================================================
+AnimationPlayer* TransitionEvent::GetPlayer()
+{
+ return( GetPresentationManager()->GetTransPlayer() );
+}
+
+//=============================================================================
+// TransitionEvent::Start
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void TransitionEvent::Start()
+{
+ TransitionPlayer* player = GetPresentationManager()->GetTransPlayer();
+
+ player->SetTransition( &transInfo );
+
+ player->Play();
+}
+
diff --git a/game/code/presentation/presevents/transevent.h b/game/code/presentation/presevents/transevent.h
new file mode 100644
index 0000000..6c921b1
--- /dev/null
+++ b/game/code/presentation/presevents/transevent.h
@@ -0,0 +1,44 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: .h
+//
+// Description: Blahblahblah
+//
+// History: 23/05/2002 + Created -- NAME
+//
+//=============================================================================
+
+#ifndef TRANSEVENT_H
+#define TRANSEVENT_H
+
+//========================================
+// Nested Includes
+//========================================
+
+#include <presentation/presevents/presentationevent.h>
+#include <presentation/transitionplayer.h>
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: Blahblahblah
+//
+//=============================================================================
+
+class TransitionEvent : public PresentationEvent
+{
+ public:
+ TransitionPlayer::TransitionInfo transInfo;
+
+ AnimationPlayer* GetPlayer();
+
+ virtual void Start();
+ protected:
+};
+
+#endif //TRANSEVENT_H
+
diff --git a/game/code/presentation/simpleanimationplayer.cpp b/game/code/presentation/simpleanimationplayer.cpp
new file mode 100644
index 0000000..dc250c8
--- /dev/null
+++ b/game/code/presentation/simpleanimationplayer.cpp
@@ -0,0 +1,300 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: simpleanimationplayer.cpp
+//
+// Description: Implement SimpleAnimationPlayer
+//
+// History: 29/05/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+#include <p3d/anim/multicontroller.hpp>
+#include <p3d/camera.hpp>
+#include <p3d/utility.hpp>
+#include <p3d/view.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include <presentation/simpleanimationplayer.h>
+
+
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// SimpleAnimationPlayer::SimpleAnimationPlayer
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+SimpleAnimationPlayer::SimpleAnimationPlayer() :
+ mpMasterController( NULL ),
+ mCycleMode( DEFAULT_CYCLE_MODE ),
+ mpCamera( NULL ),
+ mpViewCamera( NULL ),
+ mbSetCamera( false ),
+ mIntroFrames(0),
+ mOutroFrames(0),
+ mInIntro(false)
+{
+ strcpy( msCamera, "" );
+ strcpy( msController, "" );
+ strcpy( msAnimation, "" );
+}
+
+//==============================================================================
+// SimpleAnimationPlayer::~SimpleAnimationPlayer
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+SimpleAnimationPlayer::~SimpleAnimationPlayer()
+{
+ tRefCounted::Release( mpViewCamera );
+}
+
+//=============================================================================
+// SimpleAnimationPlayer::Update
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( unsigned int elapsedTime )
+//
+// Return: void
+//
+//=============================================================================
+void SimpleAnimationPlayer::Update( unsigned int elapsedTime )
+{
+ if ( (GetState() == ANIM_PLAYING) && mpMasterController)
+ {
+ if(mOutroFrames && (mpMasterController->GetFrame() > static_cast<float>(mNumFrames - mOutroFrames)))
+ {
+ mpMasterController->SetFrameRange(static_cast<float>(mNumFrames - mOutroFrames), static_cast<float>(mNumFrames));
+ mpMasterController->SetCycleMode(FORCE_CYCLIC);
+ }
+
+ mpMasterController->Advance( static_cast<float>(elapsedTime) );
+ }
+}
+
+
+//==============================================================================
+// SimpleAnimationPlayer::Rewind
+//==============================================================================
+//
+// Description:
+//
+// Parameters:
+//
+// Return:
+//
+//==============================================================================
+void SimpleAnimationPlayer::Rewind()
+{
+ if(mpMasterController)
+ {
+ mpMasterController->Reset();
+ mpMasterController->Advance(0.0f);
+
+ SetState( ANIM_LOADED );
+ }
+}
+
+//=============================================================================
+// SimpleAnimationPlayer::ClearData
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void SimpleAnimationPlayer::ClearData()
+{
+ AnimationPlayer::ClearData();
+
+ if( mpMasterController != NULL )
+ {
+ mpMasterController->Release();
+ mpMasterController = NULL;
+ }
+
+ mCycleMode = DEFAULT_CYCLE_MODE;
+
+ if( mpCamera != NULL )
+ {
+ mpCamera->Release();
+ mpCamera = NULL;
+ mbSetCamera = false;
+ }
+}
+
+//=============================================================================
+// SimpleAnimationPlayer::SetNameData
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( char* controller, char* camera, char* animation )
+//
+// Return: void
+//
+//=============================================================================
+void SimpleAnimationPlayer::SetNameData( char* controller, char* camera, char* animation )
+{
+ strcpy( msController, controller );
+ if( camera != NULL )
+ {
+ strcpy( msCamera, camera );
+ }
+ strcpy( msAnimation, animation );
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// SimpleAnimationPlayer::DoLoaded
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void SimpleAnimationPlayer::DoLoaded()
+{
+ tRefCounted::Assign(mpMasterController, p3d::find<tMultiController>( msController ));
+
+ if(mpMasterController)
+ {
+ // reset to the first frame, and update (so evrything is in the correct
+ // place if we display before calling update again)
+ mpMasterController->Reset();
+ mpMasterController->SetFrame(0);
+ mpMasterController->Advance(0.0f);
+
+ mpMasterController->SetCycleMode( mCycleMode );
+
+ mNumFrames = rmt::FtoL(mpMasterController->GetNumFrames());
+
+ if(mIntroFrames != 0)
+ {
+ mpMasterController->SetFrameRange(0.0f, (float)mIntroFrames);
+ mpMasterController->SetCycleMode( FORCE_CYCLIC );
+ }
+ }
+
+ if( strlen( msCamera ) > 0 )
+ {
+ tRefCounted::Assign(mpCamera,p3d::find<tCamera>( msCamera ));
+ }
+
+ mbSetCamera = false;
+}
+
+//=============================================================================
+// SimpleAnimationPlayer::DoRender
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void SimpleAnimationPlayer::DoRender()
+{
+ if(!mpMasterController)
+ {
+ Stop();
+ return;
+ }
+
+ if ( !mbSetCamera && mpCamera != NULL )
+ {
+ tView* view = p3d::context->GetView();
+ rAssert( view );
+
+ mpViewCamera = view->GetCamera();
+ mpViewCamera->AddRef();
+
+ view->SetCamera( mpCamera );
+
+ mbSetCamera = true;
+ }
+
+ if ( (mpMasterController->GetFrame() >= mpMasterController->GetNumFrames()) && (mOutroFrames == 0))
+ {
+ if ( mbSetCamera )
+ {
+ tView* view = p3d::context->GetView();
+ rAssert( view );
+
+ view->SetCamera( mpViewCamera );
+ tRefCounted::Release( mpViewCamera );
+ }
+
+ Stop();
+ }
+}
+
+
+void SimpleAnimationPlayer::SetIntroLoop(unsigned nFrames)
+{
+ mIntroFrames = nFrames;
+}
+
+void SimpleAnimationPlayer::SetOutroLoop(unsigned nFrames)
+{
+ mOutroFrames = nFrames;
+}
+
+void SimpleAnimationPlayer::Play(void)
+{
+ AnimationPlayer::Play();
+
+ if(mIntroFrames)
+ {
+ mInIntro = true;
+ }
+}
+
+void SimpleAnimationPlayer::DoneIntro(void)
+{
+ if(mpMasterController)
+ {
+ mInIntro = false;
+ mpMasterController->SetFrameRange(0.0f, static_cast<float>(mNumFrames));
+ mpMasterController->SetCycleMode(mCycleMode);
+ }
+}
diff --git a/game/code/presentation/simpleanimationplayer.h b/game/code/presentation/simpleanimationplayer.h
new file mode 100644
index 0000000..eb39bd8
--- /dev/null
+++ b/game/code/presentation/simpleanimationplayer.h
@@ -0,0 +1,89 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: .h
+//
+// Description: Blahblahblah
+//
+// History: 29/05/2002 + Created -- NAME
+//
+//=============================================================================
+
+#ifndef SIMPLEANIMATIONPLAYER_H
+#define SIMPLEANIMATIONPLAYER_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <p3d/anim/animate.hpp> // p3dCycleMode
+#include <presentation/animplayer.h>
+
+//========================================
+// Forward References
+//========================================
+
+class tMultiController;
+class tCamera;
+
+//=============================================================================
+//
+// Synopsis: Wraps up the P3D related crap involved with playing an
+// animation.
+//
+//=============================================================================
+
+class SimpleAnimationPlayer : public AnimationPlayer
+{
+ public:
+ SimpleAnimationPlayer();
+ virtual ~SimpleAnimationPlayer();
+
+ virtual void Update( unsigned int elapsedTime );
+
+ virtual void ClearData();
+
+ void SetNameData( char* controller, char* camera, char* animation );
+
+ void SetCycleMode( p3dCycleMode cycleMode ) { mCycleMode = cycleMode; }
+ void SetIntroLoop(unsigned nFrames);
+ void SetOutroLoop(unsigned nFrames);
+
+ void Play(void);
+ void DoneIntro(void);
+
+ void Rewind();
+
+ protected:
+
+ // These set all the objects needs to play an animation
+ void SetController(tMultiController* pController ) { mpMasterController = pController; }
+ void SetCamera( tCamera* pCamera ) { mpCamera = pCamera; }
+
+ virtual void DoLoaded();
+ virtual void DoRender();
+
+ const char* GetAnimationName() { return( &msAnimation[0] ); }
+
+ private:
+
+ //Prevent wasteful constructor creation.
+ SimpleAnimationPlayer( const SimpleAnimationPlayer& );
+ SimpleAnimationPlayer& operator=( const SimpleAnimationPlayer& );
+
+ char msController[32];
+ char msCamera[32];
+ char msAnimation[32];
+
+ tMultiController* mpMasterController;
+ p3dCycleMode mCycleMode;
+ tCamera* mpCamera;
+ tCamera* mpViewCamera;
+ bool mbSetCamera;
+ unsigned mIntroFrames;
+ unsigned mOutroFrames;
+ bool mInIntro;
+ unsigned mNumFrames;
+};
+
+
+#endif // SIMPLEANIMATIONPLAYER_H
diff --git a/game/code/presentation/transitionplayer.cpp b/game/code/presentation/transitionplayer.cpp
new file mode 100644
index 0000000..5d7f3ce
--- /dev/null
+++ b/game/code/presentation/transitionplayer.cpp
@@ -0,0 +1,161 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: transitionplayer.cpp
+//
+// Description: Implement TransitionPlayer
+//
+// History: 02/05/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+#include <p3d/view.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include <presentation/transitionplayer.h>
+#include <render/rendermanager/rendermanager.h>
+#include <render/rendermanager/renderlayer.h>
+
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// TransitionPlayer::TransitionPlayer
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+TransitionPlayer::TransitionPlayer() :
+ mpLayer1( NULL ),
+ mpLayer2( NULL ),
+ miIndex( static_cast< unsigned int >( -1 ) )
+{
+ //init msInfo?
+}
+
+//==============================================================================
+// TransitionPlayer::~TransitionPlayer
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+TransitionPlayer::~TransitionPlayer()
+{
+}
+
+void TransitionPlayer::SetTransition( TransitionInfo* info )
+{
+ rAssert( GetState() != ANIM_IDLE );
+
+ msInfo = *info;
+
+ RenderManager* rm = GetRenderManager();
+
+ mpLayer1 = rm->mpLayer( msInfo.layer1 );
+ mpLayer2 = rm->mpLayer( msInfo.layer2 );
+
+ miIndex = 0;
+
+ rAssert( msInfo.length != 0 );
+}
+
+void TransitionPlayer::Update( unsigned int elapsedTime )
+{
+ if ( GetState() == ANIM_PLAYING )
+ {
+ if (miIndex == 0)
+ {
+ if ( mpLayer2->IsFrozen() )
+ {
+ mpLayer2->Thaw();
+ }
+ else if ( mpLayer2->IsDead() )
+ {
+ mpLayer2->Resurrect();
+ }
+ }
+
+ miIndex += elapsedTime;
+
+ if ( miIndex < msInfo.length )
+ {
+ DoUpdate( elapsedTime );
+ }
+ else
+ {
+ mpLayer1->Freeze();
+
+ Stop();
+ }
+ }
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+void TransitionPlayer::DoUpdate( unsigned int elapsedTime )
+{
+ switch ( msInfo.type )
+ {
+ case TRANS_WIPE_RIGHT:
+ {
+ float f1 = static_cast<float>( miIndex );
+ float f2 = static_cast<float>( msInfo.length );
+
+ float r = f1 / f2;
+
+ tView* view = mpLayer2->pView( 0 );
+ view->SetWindow( 0.0f, 0.0f, r, 1.0f );
+
+ view = mpLayer1->pView( 0 );
+ view->SetWindow( r, 0.0f, 1.0f, 1.0f );
+ break;
+ }
+ default :
+ {
+ //nothing
+ }
+ }
+}
+
+//=============================================================================
+// TransitionPlayer::DoRender
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void TransitionPlayer::DoRender()
+{
+}
diff --git a/game/code/presentation/transitionplayer.h b/game/code/presentation/transitionplayer.h
new file mode 100644
index 0000000..3e48fb3
--- /dev/null
+++ b/game/code/presentation/transitionplayer.h
@@ -0,0 +1,82 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: .h
+//
+// Description: Blahblahblah
+//
+// History: 02/05/2002 + Created -- NAME
+//
+//=============================================================================
+
+#ifndef TRANSITIONPLAYER_H
+#define TRANSITIONPLAYER_H
+
+//========================================
+// Nested Includes
+//========================================
+
+#include <presentation/animplayer.h>
+
+#include <render/enums/renderenums.h>
+
+//========================================
+// Forward References
+//========================================
+
+class RenderLayer;
+
+//=============================================================================
+//
+// Synopsis: Blahblahblah
+//
+//=============================================================================
+
+class TransitionPlayer : public AnimationPlayer
+{
+ public:
+ TransitionPlayer();
+ virtual ~TransitionPlayer();
+
+ enum TransitionType
+ {
+ TRANS_CROSSFADE,
+ TRANS_WIPE_RIGHT,
+ TRANS_TO_BLACK,
+ TRANS_FROM_BLACK,
+ NUM_TRANS
+ };
+
+ struct TransitionInfo
+ {
+ RenderEnums::LayerEnum layer1;
+ RenderEnums::LayerEnum layer2;
+ unsigned int length;
+ TransitionType type;
+ };
+
+ void SetTransition( TransitionInfo* info );
+
+ virtual void Update( unsigned int elapsedTime );
+ protected:
+ virtual void DoUpdate( unsigned int elapsedTime );
+
+ virtual void DoLoaded() {};
+ virtual void DoRender();
+
+ private:
+
+ //Prevent wasteful constructor creation.
+ TransitionPlayer( const TransitionPlayer& transitionPlayer );
+ TransitionPlayer& operator=( const TransitionPlayer& transitionPlayer );
+
+ RenderLayer* mpLayer1;
+ RenderLayer* mpLayer2;
+
+ TransitionInfo msInfo;
+ unsigned int miIndex;
+};
+
+
+#endif //TRANSITIONPLAYER_H
+
diff --git a/game/code/presentation/tutorialmanager.cpp b/game/code/presentation/tutorialmanager.cpp
new file mode 100644
index 0000000..f78e952
--- /dev/null
+++ b/game/code/presentation/tutorialmanager.cpp
@@ -0,0 +1,745 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: presentation.cpp
+//
+// Description: Implement PresentationManager
+//
+// History: 16/04/2002 + Created -- NAME
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+
+//========================================
+// Project Includes
+//========================================
+#include <data/gamedatamanager.h>
+#include <events/eventmanager.h>
+#include <gameflow/gameflow.h>
+#include <main/commandlineoptions.h>
+#include <memory/srrmemory.h>
+#include <meta/locatorevents.h>
+#include <mission/mission.h>
+#include <mission/missionmanager.h>
+#include <mission/gameplaymanager.h>
+#include <mission/objectives/missionobjective.h>
+#include <presentation/gui/guisystem.h>
+#include <presentation/gui/ingame/guimanageringame.h>
+#include <presentation/gui/ingame/guiscreenhud.h>
+#include <presentation/tutorialmanager.h>
+#include <presentation/tutorialmode.h>
+#include <worldsim/redbrick/vehicle.h>
+
+#include <string.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+// Static pointer to instance of singleton.
+TutorialManager* TutorialManager::spInstance = NULL;
+//#define NUMBER_OF_MISSION_OBJECTIVE_MESSAGES 300
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// TutorialManager::CreateInstance
+//=============================================================================
+// Description: creats an instance of the singleton
+//
+// Parameters: ()
+//
+// Return: TutorialManager
+//
+//=============================================================================
+TutorialManager* TutorialManager::CreateInstance()
+{
+ MEMTRACK_PUSH_GROUP( "TutorialManager" );
+ if( spInstance == NULL )
+ {
+ spInstance = new TutorialManager;
+ rAssert( spInstance );
+ }
+ size_t size = sizeof( TutorialManager );
+ MEMTRACK_POP_GROUP( "TutorialManager" );
+ return spInstance;
+}
+
+//=============================================================================
+// TutorialManager::GetInstance
+//=============================================================================
+// Description: gets the instance of the singleton
+//
+// Parameters: ()
+//
+// Return: TutorialManager
+//
+//=============================================================================
+TutorialManager* TutorialManager::GetInstance()
+{
+ return spInstance;
+}
+
+//=============================================================================
+// TutorialManager::AddToQueue
+//=============================================================================
+// Description: adds an item to the queue of events to process
+//
+// Parameters: event - the tutorial event that we want to show as soon as
+// possible
+//
+// Return: void
+//
+//=============================================================================
+void TutorialManager::AddToQueue( TutorialMode event )
+{
+ m_Queue.push_back( event );
+}
+
+//=============================================================================
+// TutorialManager::DestroyInstance
+//=============================================================================
+// Description: destroys the only instance of the singleton
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void TutorialManager::DestroyInstance()
+{
+ if( spInstance != NULL )
+ {
+ delete spInstance;
+ spInstance = NULL;
+ }
+}
+
+//==============================================================================
+// TutorialManager::TutorialManager
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+TutorialManager::TutorialManager() :
+ m_EnableTutorialMode( false ),
+ m_EnableTutorialEvents( true ),
+ m_DialogCurrentlyPlaying( false ),
+ m_TimeSinceDialogStart( 0.0f ),
+ m_tutorialsSeen( 0 )
+{
+#ifndef FINAL
+ // We're going to be passing enums in void* messages - they'd better be the
+ // same size or else we're in big trouble
+ size_t sizeOfEnum = sizeof( TutorialMode );
+ size_t sizeOfVoid = sizeof( void* );
+ rReleaseAssert( sizeOfEnum == sizeOfVoid );
+#endif
+ m_Queue.reserve( 16 );
+
+ GetGameDataManager()->RegisterGameData( this, 1 + sizeof( m_tutorialsSeen ), "Tutorial Manager" );
+
+ if( CommandLineOptions::Get( CLO_NO_TUTORIAL ) )
+ {
+ m_EnableTutorialEvents = false;
+ }
+}
+
+//==============================================================================
+// TutorialManager::~TutorialManager
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+TutorialManager::~TutorialManager()
+{
+ GetEventManager()->RemoveAll( this );
+}
+
+//==============================================================================
+// TutorialManager::HandleEvent
+//==============================================================================
+// Description: Handles events that are passed to this listener
+//
+// Parameters: id - the event id
+// pEventData - any data that tags along for the ride
+//
+// Return: N/A.
+//
+//==============================================================================
+void TutorialManager::HandleEvent( EventEnum id, void* pEventData )
+{
+ if( id == EVENT_TUTORIAL_DIALOG_DONE )
+ {
+ MarkDialogFinished();
+
+ return;
+ }
+
+ if( !m_EnableTutorialMode || !m_EnableTutorialEvents )
+ {
+ return;
+ }
+
+ switch( id )
+ {
+ case EVENT_CARD_COLLECTED:
+ {
+ AddToQueue( TUTORIAL_COLLECTOR_CARD );
+ GetEventManager()->RemoveListener( this, EVENT_CARD_COLLECTED );
+ break;
+ }
+ case EVENT_COLLECTED_COINS:
+ {
+ AddToQueue( TUTORIAL_COLLECTOR_COIN );
+ GetEventManager()->RemoveListener( this, EVENT_COLLECTED_COINS );
+ break;
+ }
+ case static_cast< EventEnum >( EVENT_LOCATOR + LocatorEvent::INTERIOR_ENTRANCE ):
+ {
+ AddToQueue( TUTORIAL_INTERIOR_ENTERED );
+ GetEventManager()->RemoveListener( this, static_cast< EventEnum >( EVENT_LOCATOR + LocatorEvent::INTERIOR_ENTRANCE ) );
+ break;
+ }
+ case static_cast< EventEnum >( EVENT_LOCATOR + LocatorEvent::CAR_DOOR ):
+ {
+ AddToQueue( TUTORIAL_AT_CAR_DOOR );
+ GetEventManager()->RemoveListener( this, static_cast< EventEnum >( EVENT_LOCATOR + LocatorEvent::CAR_DOOR ) );
+ break;
+ }
+ case static_cast< EventEnum >( EVENT_INTERACTIVE_GAG ):
+ {
+ AddToQueue( TUTORIAL_INTERACTIVE_GAG );
+ GetEventManager()->RemoveListener( this, static_cast< EventEnum >( EVENT_INTERACTIVE_GAG ) );
+ break;
+ }
+ case EVENT_ENTERING_PLAYER_CAR:
+ {
+ AddToQueue( TUTORIAL_GETTING_INTO_PLAYER_CAR );
+ GetEventManager()->RemoveListener( this, EVENT_ENTERING_PLAYER_CAR );
+ break;
+ }
+ case EVENT_ENTERING_TRAFFIC_CAR:
+ {
+ //
+ // Have we played the player car tutorial message yet?
+ //
+ bool seenDrivingTutorial = QueryTutorialSeen( TUTORIAL_GETTING_INTO_PLAYER_CAR );
+ if( seenDrivingTutorial )
+ {
+ AddToQueue( TUTORIAL_GETTING_INTO_TRAFFIC_CAR );
+ GetEventManager()->RemoveListener( this, EVENT_ENTERING_TRAFFIC_CAR );
+ }
+ else
+ {
+ AddToQueue( TUTORIAL_GETTING_INTO_PLAYER_CAR );
+ SetTutorialSeen( TUTORIAL_GETTING_INTO_TRAFFIC_CAR, true );
+ GetEventManager()->RemoveListener( this, EVENT_ENTERING_TRAFFIC_CAR );
+ GetEventManager()->RemoveListener( this, EVENT_ENTERING_PLAYER_CAR );
+ }
+ break;
+ }
+ case EVENT_ANIMATED_CAM_SHUTDOWN:
+ {
+ AddToQueue( TUTORIAL_START_GAME );
+ GetEventManager()->RemoveListener( this, EVENT_ANIMATED_CAM_SHUTDOWN );
+ break;
+ }
+ case EVENT_BONUS_MISSION_CHARACTER_APPROACHED:
+ {
+ int missionNum = reinterpret_cast< int >( pEventData );
+ Mission* mission = GetMissionManager()->GetMission( missionNum );
+ bool raceMission = mission->IsRaceMission();
+ bool wagerMission = mission->IsWagerMission();
+
+ if( wagerMission )
+ {
+ AddToQueue( TUTORIAL_WAGER_MISSION );
+ }
+ else if( raceMission )
+ {
+ AddToQueue( TUTORIAL_RACE );
+ }
+ else
+ {
+ AddToQueue( TUTORIAL_BONUS_MISSION );
+ }
+
+ bool seenRace = QueryTutorialSeen( TUTORIAL_RACE );
+ bool seenBonus = QueryTutorialSeen( TUTORIAL_BONUS_MISSION );
+ bool seenWager = QueryTutorialSeen( TUTORIAL_WAGER_MISSION );
+ if( seenRace && seenBonus && seenWager )
+ {
+ GetEventManager()->RemoveListener( this, EVENT_MISSION_START );
+ }
+ break;
+ }
+ case EVENT_HIT_BREAKABLE:
+ {
+ AddToQueue( TUTORIAL_BREAKABLE_DESTROYED );
+ GetEventManager()->RemoveListener( this, EVENT_HIT_BREAKABLE );
+ break;
+ }
+ case EVENT_UNLOCKED_CAR:
+ {
+ AddToQueue( TUTORIAL_UNLOCKED_CAR );
+ GetEventManager()->RemoveListener( this, EVENT_UNLOCKED_CAR );
+ break;
+ }
+ case EVENT_VEHICLE_DESTROYED:
+ {
+ //
+ // Check if this is a user vehicle
+ //
+ Vehicle* vehicle = reinterpret_cast< Vehicle* >( pEventData );
+ rAssert( vehicle != NULL );
+ if( vehicle->mVehicleType == VT_USER )
+ {
+ AddToQueue( TUTORIAL_VEHICLE_DESTROYED );
+ GetEventManager()->RemoveListener( this, EVENT_VEHICLE_DESTROYED );
+ }
+ break;
+ }
+ case EVENT_COLLECTED_WRENCH:
+ {
+ AddToQueue( TUTORIAL_WRENCH );
+ GetEventManager()->RemoveListener( this, EVENT_COLLECTED_WRENCH );
+ break;
+ }
+ case EVENT_WASP_APPROACHED:
+ {
+ AddToQueue( TUTORIAL_BREAK_CAMERA );
+ GetEventManager()->RemoveListener( this, EVENT_WASP_APPROACHED );
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "TutorialManager: why are we registered for messages we don't care about?" );
+ break;
+ }
+ }
+
+// ProcessQueue();
+}
+
+//==============================================================================
+// TutorialManager::Initialize
+//==============================================================================
+// Description: Initializes this manager as a listener to various event types
+//
+// Parameters: None
+//
+// Return: N/A.
+//
+//==============================================================================
+void TutorialManager::Initialize()
+{
+ while( !m_Queue.empty() )
+ {
+ m_Queue.pop_back();
+ }
+
+ GetEventManager()->AddListener( this, EVENT_CARD_COLLECTED );
+ GetEventManager()->AddListener( this, EVENT_COLLECTED_COINS );
+ GetEventManager()->AddListener( this, EVENT_COLLECTED_WRENCH );
+ GetEventManager()->AddListener( this, static_cast< EventEnum >( EVENT_LOCATOR + LocatorEvent::INTERIOR_ENTRANCE ) );
+ GetEventManager()->AddListener( this, static_cast< EventEnum >( EVENT_LOCATOR + LocatorEvent::CAR_DOOR ) );
+ GetEventManager()->AddListener( this, EVENT_INTERACTIVE_GAG );
+ GetEventManager()->AddListener( this, EVENT_ENTERING_PLAYER_CAR );
+ GetEventManager()->AddListener( this, EVENT_ENTERING_TRAFFIC_CAR );
+ GetEventManager()->AddListener( this, EVENT_ANIMATED_CAM_SHUTDOWN );
+ GetEventManager()->AddListener( this, EVENT_BONUS_MISSION_CHARACTER_APPROACHED );
+ GetEventManager()->AddListener( this, EVENT_HIT_BREAKABLE );
+ GetEventManager()->AddListener( this, EVENT_TUTORIAL_DIALOG_DONE );
+ GetEventManager()->AddListener( this, EVENT_UNLOCKED_CAR );
+ GetEventManager()->AddListener( this, EVENT_VEHICLE_DESTROYED );
+ GetEventManager()->AddListener( this, EVENT_WASP_APPROACHED );
+}
+
+//==============================================================================
+// TutorialManager::MarkDialogFinished
+//==============================================================================
+// Description: when a piece of dialog is finished playing, you may need to play
+// another
+//
+// Parameters: None
+//
+// Return: N/A.
+//
+//==============================================================================
+void TutorialManager::MarkDialogFinished()
+{
+/*
+ CGuiScreenHud* hud = GetCurrentHud();
+ if( hud != NULL )
+ {
+ hud->TutorialBitmapInitOutro();
+ }
+*/
+ m_DialogCurrentlyPlaying = false;
+// ProcessQueue();
+}
+
+//==============================================================================
+// TutorialManager::ProcessQueue
+//==============================================================================
+// Description: takes an item out of the queue, and processes it
+//
+// Parameters: None
+//
+// Return: N/A.
+//
+//==============================================================================
+void TutorialManager::ProcessQueue()
+{
+/*
+ CGuiScreenHud* hud = GetCurrentHud();
+ if( hud == NULL )
+ {
+ return;
+ }
+*/
+ if( m_DialogCurrentlyPlaying )
+ {
+ return;
+ }
+
+ //
+ // return if there's nothing in the queue
+ //
+ size_t size = m_Queue.size();
+ if( size <= 0 )
+ {
+ return;
+ }
+
+ TutorialMode event = m_Queue.front();
+
+ //
+ // Check if the event is marked in the character sheet as "already played"
+ //
+ bool alreadySeen = this->QueryTutorialSeen( event );
+ if( !alreadySeen )
+ {
+ //
+ // Make sure we never see this message again
+ //
+ this->SetTutorialSeen( event, true );
+
+#ifndef RAD_WIN32
+ switch( event )
+ {
+ case TUTORIAL_BREAK_CAMERA:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_BREAK_CAMERA;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_BONUS_MISSION:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_BONUS_MISSION;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_BREAKABLE_DESTROYED:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_BREAKABLE_DESTROYED;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_COLLECTOR_CARD:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_COLLECTOR_CARD;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_COLLECTOR_COIN:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_COLLECTOR_COIN;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_INTERACTIVE_GAG:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_INTERACTIVE_GAG;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_INTERIOR_ENTERED:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_INTERIOR_ENTERED;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode);
+ break;
+ }
+ case TUTORIAL_GETTING_INTO_PLAYER_CAR:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_GETTING_INTO_PLAYER_CAR;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_GETTING_INTO_TRAFFIC_CAR:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_GETTING_INTO_TRAFFIC_CAR;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_GETTING_OUT_OF_CAR:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_GETTING_OUT_OF_CAR;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_RACE:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_RACE;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_START_GAME:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_START_GAME;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_VEHICLE_DESTROYED:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_VEHICLE_DESTROYED;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_REWARD:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_REWARD;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_UNLOCKED_CAR:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_UNLOCKED_CAR;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_WAGER_MISSION:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_WAGER_MISSION;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_WRENCH:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_WRENCH;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_AT_CAR_DOOR:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_AT_CAR_DOOR;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ case TUTORIAL_INTERACTIVE_GAG_APPROACHED:
+ {
+ m_DialogCurrentlyPlaying = true;
+ m_TimeSinceDialogStart = 0;
+ TutorialMode mode = TUTORIAL_INTERACTIVE_GAG_APPROACHED;
+ GetEventManager()->TriggerEvent( EVENT_TUTORIAL_DIALOG_PLAY, &mode );
+ break;
+ }
+ default:
+ {
+ rAssertMsg( false, "Why don't we process this message" );
+ return;
+
+ break;
+ }
+ }
+#endif
+
+// hud->SetTutorialMessage( event );
+// hud->TutorialBitmapShow();
+
+ GetGuiSystem()->GotoScreen( CGuiWindow::GUI_SCREEN_ID_TUTORIAL, 0, 0,
+ CLEAR_WINDOW_HISTORY | FORCE_WINDOW_CHANGE_IMMEDIATE );
+
+#ifdef RAD_WIN32
+ m_DialogCurrentlyPlaying = false;
+#endif
+ GetGameFlow()->SetContext( CONTEXT_PAUSE );
+
+ }
+
+ //
+ // Pop an item off the queue
+ //
+ m_Queue.erase( m_Queue.begin() );
+}
+
+//==============================================================================
+// TutorialManager::Update
+//==============================================================================
+// Description: takes an item out of the queue, and processes it
+//
+// Parameters: None
+//
+// Return: N/A.
+//
+//==============================================================================
+void TutorialManager::Update( const float deltaT )
+{
+ CGuiScreenHud* currentHud = GetCurrentHud();
+ if( currentHud != NULL && currentHud->IsActive() )
+ {
+ // only update tutorial manager if the HUD is currently active
+ //
+// m_TimeSinceDialogStart += deltaT;
+// if( m_TimeSinceDialogStart > 10000.0f )
+ {
+ m_TimeSinceDialogStart = 0;
+ m_DialogCurrentlyPlaying = false;
+/*
+ CGuiScreenHud* hud = GetCurrentHud();
+ if( hud != NULL )
+ {
+ hud->TutorialBitmapInitOutro();
+ }
+*/
+ }
+
+ ProcessQueue();
+ }
+}
+
+void
+TutorialManager::LoadData( const GameDataByte* dataBuffer, unsigned int numBytes )
+{
+ m_EnableTutorialEvents = ( dataBuffer[ 0 ] != 0 );
+
+ memcpy( &m_tutorialsSeen, dataBuffer + 1, sizeof( m_tutorialsSeen ) );
+}
+
+void
+TutorialManager::SaveData( GameDataByte* dataBuffer, unsigned int numBytes )
+{
+ dataBuffer[ 0 ] = m_EnableTutorialEvents ? ~0 : 0;
+
+ memcpy( dataBuffer + 1, &m_tutorialsSeen, sizeof( m_tutorialsSeen ) );
+}
+
+void
+TutorialManager::ResetData()
+{
+#ifdef RAD_WIN32
+
+ if( !GetInputManager()->GetController(0)->IsTutorialDisabled() )
+ {
+#endif
+ m_EnableTutorialEvents = true;
+ m_tutorialsSeen = 0;
+#ifdef RAD_WIN32
+ }
+#endif
+
+#ifndef FINAL
+ if( CommandLineOptions::Get( CLO_NO_TUTORIAL ) )
+ {
+ m_EnableTutorialEvents = false;
+ }
+#endif
+
+ // re-add event listeners
+ //
+ GetEventManager()->RemoveAll( this );
+ this->Initialize();
+}
+
+//=============================================================================
+// TutorialManager::QueryTutorialSeen
+//=============================================================================
+// Description: checks to see if a given tutorial has already been played
+//
+// Parameters: tutorial - enum of the tutorial in question
+//
+// Return: bool - has the tutorial been shown
+//
+//=============================================================================
+bool TutorialManager::QueryTutorialSeen( const TutorialMode tutorial )
+{
+ return (m_tutorialsSeen & (1 << tutorial)) > 0;
+
+}
+
+//=============================================================================
+// TutorialManager::SetTutorialSeen
+//=============================================================================
+// Description: sets the status of a specific tutorial
+//
+// Parameters: tutorial - enum of the tutorial in question
+//
+// Return: bool - has the tutorial been shown
+//
+//=============================================================================
+void TutorialManager::SetTutorialSeen( const TutorialMode tutorial, const bool seen )
+{
+ if ( seen )
+ {
+ m_tutorialsSeen |= (1 << tutorial);
+ }
+ else
+ {
+ m_tutorialsSeen &= ~(1 << tutorial);
+ }
+}
+
diff --git a/game/code/presentation/tutorialmanager.h b/game/code/presentation/tutorialmanager.h
new file mode 100644
index 0000000..c2a6f81
--- /dev/null
+++ b/game/code/presentation/tutorialmanager.h
@@ -0,0 +1,127 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: tutorialmanager.h
+//
+// Description: this system controls the operation of tutorial mode
+//
+// History: 19/12/2002 + Created -- Ian Gipson
+//
+//=============================================================================
+
+#ifndef TUTORIALMANGER_H
+#define TUTORIALMANGER_H
+
+//========================================
+// Nested Includes
+//========================================
+#include "events/eventlistener.h"
+#include "presentation/tutorialmode.h"
+#include <vector>
+
+#include <data/gamedata.h>
+#include <memory/stlallocators.h>
+
+//========================================
+// Forward References
+//========================================
+
+//========================================
+// typedefs
+//========================================
+
+
+//=============================================================================
+//
+// Synopsis: TutorialManager
+//
+//=============================================================================
+
+class TutorialManager : public EventListener,
+ public GameDataHandler
+{
+ public:
+ // Static Methods for accessing this singleton.
+ static TutorialManager* CreateInstance();
+ static TutorialManager* GetInstance();
+ static void DestroyInstance();
+
+ void EnableTutorialMode( const bool enabled );
+ bool IsTutorialModeEnabled() const;
+
+ void EnableTutorialEvents( const bool enabled );
+ bool IsTutorialEventsEnabled() const;
+
+ virtual void HandleEvent( EventEnum id, void* pEventData );
+ void Initialize();
+ void MarkDialogFinished();
+ void Update( const float deltaT );
+
+ TutorialMode GetCurrentEventID() const;
+ bool IsDialogPlaying() const;
+
+ // Implements GameDataHandler
+ //
+ virtual void LoadData( const GameDataByte* dataBuffer, unsigned int numBytes );
+ virtual void SaveData( GameDataByte* dataBuffer, unsigned int numBytes );
+ virtual void ResetData();
+
+ protected:
+ void AddToQueue( TutorialMode event );
+ void ProcessQueue();
+
+ bool QueryTutorialSeen( const TutorialMode tutorial );
+ void SetTutorialSeen( const TutorialMode tutorial, const bool seen );
+
+ static TutorialManager* spInstance;
+ private:
+ TutorialManager();
+ virtual ~TutorialManager();
+
+ std::vector< TutorialMode, s2alloc<TutorialMode> > m_Queue;
+
+ bool m_EnableTutorialMode : 1; // controlled by scripts
+ bool m_EnableTutorialEvents : 1; // controlled by user (in pause menu settings)
+ bool m_DialogCurrentlyPlaying : 1;
+ bool m_RaceMissionPlayed : 1;
+ bool m_BonusMissionPlayed : 1;
+ float m_TimeSinceDialogStart;
+
+ int m_tutorialsSeen; // bit field
+
+};
+
+inline TutorialManager* GetTutorialManager() { return( TutorialManager::GetInstance() ); }
+
+inline void TutorialManager::EnableTutorialMode( const bool enabled )
+{
+ m_EnableTutorialMode = enabled;
+}
+
+inline bool TutorialManager::IsTutorialModeEnabled() const
+{
+ return m_EnableTutorialMode;
+}
+
+inline void TutorialManager::EnableTutorialEvents( const bool enabled )
+{
+ m_EnableTutorialEvents = enabled;
+}
+
+inline bool TutorialManager::IsTutorialEventsEnabled() const
+{
+ return m_EnableTutorialEvents;
+}
+
+inline TutorialMode TutorialManager::GetCurrentEventID() const
+{
+ return m_Queue.front();
+}
+
+inline bool TutorialManager::IsDialogPlaying() const
+{
+ return m_DialogCurrentlyPlaying;
+}
+
+#endif //PRESENTATIONMANAGER_H
+
diff --git a/game/code/presentation/tutorialmode.h b/game/code/presentation/tutorialmode.h
new file mode 100644
index 0000000..80ed292
--- /dev/null
+++ b/game/code/presentation/tutorialmode.h
@@ -0,0 +1,61 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: tutorialmode.h
+//
+// Description: this system controls the operation of tutorial mode
+//
+// History: 19/12/2002 + Created -- Ian Gipson
+//
+//=============================================================================
+
+#ifndef TUTORIALMODE_H
+#define TUTORIALMODE_H
+
+//========================================
+// Nested Includes
+//========================================
+
+//========================================
+// Forward References
+//========================================
+
+//========================================
+// typedefs
+//========================================
+enum TutorialMode
+{
+ TUTORIAL_BREAK_CAMERA,
+ TUTORIAL_BONUS_MISSION,
+ TUTORIAL_START_GAME,
+ TUTORIAL_GETTING_INTO_PLAYER_CAR,
+ TUTORIAL_GETTING_INTO_TRAFFIC_CAR,
+ TUTORIAL_INTERACTIVE_GAG,
+ TUTORIAL_RACE,
+ TUTORIAL_COLLECTOR_CARD,
+ TUTORIAL_COLLECTOR_COIN,
+ TUTORIAL_REWARD,
+ TUTORIAL_GETTING_OUT_OF_CAR,
+ TUTORIAL_BREAKABLE_APPROACHED,
+ TUTORIAL_BREAKABLE_DESTROYED,
+ TUTORIAL_INTERIOR_ENTERED,
+ TUTORIAL_COIN_COLLECTED, //never triggered?
+ TUTORIAL_VEHICLE_DESTROYED,
+ TUTORIAL_UNLOCKED_CAR,
+ TUTORIAL_WRENCH,
+ TUTORIAL_AT_CAR_DOOR,
+ TUTORIAL_INTERACTIVE_GAG_APPROACHED, //never triggered
+ TUTORIAL_WAGER_MISSION,
+ TUTORIAL_INVALID,
+ TUTORIAL_MAX = TUTORIAL_INVALID
+};
+
+//=============================================================================
+//
+// Synopsis:
+//
+//=============================================================================
+
+
+#endif //TUTORIALMODE_H
+