From af80d52e22d3612b006ce452d2b7f22cc392f55e Mon Sep 17 00:00:00 2001 From: Cyd Date: Sun, 19 Jul 2026 11:25:49 -0500 Subject: [PATCH] source410: engine COMPLETE (165/165) - link reaches PE emission; deep ledger cut The tlink32 campaign after the checkpoint: eleven engine bodies back-dated from BT412 (rotation player team explode dropzone terrain cultural receiver subsystm app l4gauge - the Application core included), the WinTesla-ectomy handled by backdate.py's new unwrap rules (accessor-fn statics -> 1995 static objects, decl rewrites, pointer->reference Derivation ctor, 2007 windowed- gauge/console-marshal/idle-pump excisions), staged statics TUs opened for the game classes (MECH/BTPLAYER/BTDIRECT/PROJTILE/MISSILE/BTL4MPPR .CPP + L4APP/ NETWORK engine statics). State: every compiled symbol short of the shallow graph RESOLVED (the 52- and 17-symbol ledgers burned to zero); with 32stub.exe in place the linker reaches full vtable closure and emits the deep ledger (~210 symbols, UNRESOLVED- LEDGER.txt): remaining engine bodies (objstrm cstr gauge/gaugrend graphics pixelmap palette resfile ray scnrole explosion-table), the DOS driver extern layer (_SVGA*/_PCSerial*/_PCSPAK*/joystick/netnub/sosMIDI), the full L4App body, and the real game-TU frontier (Mech::Make et al.). Recipe proven for every category. Co-Authored-By: Claude Fable 5 --- restoration/source410/BT/BTDIRECT.CPP | 29 + restoration/source410/BT/BTPLAYER.CPP | 29 + restoration/source410/BT/MECH.CPP | 39 + restoration/source410/BT/MISSILE.CPP | 29 + restoration/source410/BT/PROJTILE.CPP | 29 + restoration/source410/BT_L4/BTL4MPPR.CPP | 42 + restoration/source410/MUNGA/APP.CPP | 1798 +++++++ restoration/source410/MUNGA/APP.HPP | 6 +- restoration/source410/MUNGA/CULTURAL.CPP | 1093 ++++ restoration/source410/MUNGA/DROPZONE.CPP | 459 ++ restoration/source410/MUNGA/EXPLODE.CPP | 794 +++ restoration/source410/MUNGA/NETWORK.CPP | 44 + restoration/source410/MUNGA/PLAYER.CPP | 893 ++++ restoration/source410/MUNGA/RANDOM.CPP | 180 + restoration/source410/MUNGA/RECEIVER.CPP | 641 +++ restoration/source410/MUNGA/ROTATION.CPP | 1344 +++++ restoration/source410/MUNGA/SUBSYSTM.CPP | 298 ++ restoration/source410/MUNGA/TEAM.CPP | 205 + restoration/source410/MUNGA/TERRAIN.CPP | 305 ++ restoration/source410/MUNGA_L4/L4APP.CPP | 73 + restoration/source410/MUNGA_L4/L4GAUGE.CPP | 5171 +++++++++++++++++++ restoration/source410/UNRESOLVED-LEDGER.txt | 271 +- restoration/source410/backdate.py | 61 +- restoration/source410/build410.sh | 1 + restoration/source410/override/FILESTRM.HPP | 2 +- 25 files changed, 13776 insertions(+), 60 deletions(-) create mode 100644 restoration/source410/BT/BTDIRECT.CPP create mode 100644 restoration/source410/BT/BTPLAYER.CPP create mode 100644 restoration/source410/BT/MECH.CPP create mode 100644 restoration/source410/BT/MISSILE.CPP create mode 100644 restoration/source410/BT/PROJTILE.CPP create mode 100644 restoration/source410/BT_L4/BTL4MPPR.CPP create mode 100644 restoration/source410/MUNGA/APP.CPP create mode 100644 restoration/source410/MUNGA/CULTURAL.CPP create mode 100644 restoration/source410/MUNGA/DROPZONE.CPP create mode 100644 restoration/source410/MUNGA/EXPLODE.CPP create mode 100644 restoration/source410/MUNGA/NETWORK.CPP create mode 100644 restoration/source410/MUNGA/PLAYER.CPP create mode 100644 restoration/source410/MUNGA/RANDOM.CPP create mode 100644 restoration/source410/MUNGA/RECEIVER.CPP create mode 100644 restoration/source410/MUNGA/ROTATION.CPP create mode 100644 restoration/source410/MUNGA/SUBSYSTM.CPP create mode 100644 restoration/source410/MUNGA/TEAM.CPP create mode 100644 restoration/source410/MUNGA/TERRAIN.CPP create mode 100644 restoration/source410/MUNGA_L4/L4APP.CPP create mode 100644 restoration/source410/MUNGA_L4/L4GAUGE.CPP diff --git a/restoration/source410/BT/BTDIRECT.CPP b/restoration/source410/BT/BTDIRECT.CPP new file mode 100644 index 00000000..3710496d --- /dev/null +++ b/restoration/source410/BT/BTDIRECT.CPP @@ -0,0 +1,29 @@ +//===========================================================================// +// Project: BattleTech // +//---------------------------------------------------------------------------// +// Copyright (C) 1995, Virtual World Entertainment, Inc. // +// All Rights reserved worldwide // +// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // +//===========================================================================// + +#include +#pragma hdrstop + +#if !defined(BTDIRECT_HPP) +# include +#endif + +Derivation + BTCameraDirector::ClassDerivations( + CameraDirector::ClassDerivations, + "BTCameraDirector" + ); + +BTCameraDirector::SharedData + BTCameraDirector::DefaultData( + BTCameraDirector::ClassDerivations, + CameraDirector::MessageHandlers, + CameraDirector::AttributeIndex, + 1, + (Entity::MakeHandler)BTCameraDirector::Make + ); diff --git a/restoration/source410/BT/BTPLAYER.CPP b/restoration/source410/BT/BTPLAYER.CPP new file mode 100644 index 00000000..6c2ce4b8 --- /dev/null +++ b/restoration/source410/BT/BTPLAYER.CPP @@ -0,0 +1,29 @@ +//===========================================================================// +// Project: BattleTech // +//---------------------------------------------------------------------------// +// Copyright (C) 1995, Virtual World Entertainment, Inc. // +// All Rights reserved worldwide // +// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // +//===========================================================================// + +#include +#pragma hdrstop + +#if !defined(BTPLAYER_HPP) +# include +#endif + +Derivation + BTPlayer::ClassDerivations( + Player::ClassDerivations, + "BTPlayer" + ); + +BTPlayer::SharedData + BTPlayer::DefaultData( + BTPlayer::ClassDerivations, + Player::MessageHandlers, + Player::AttributeIndex, + 1, + (Entity::MakeHandler)BTPlayer::Make + ); diff --git a/restoration/source410/BT/MECH.CPP b/restoration/source410/BT/MECH.CPP new file mode 100644 index 00000000..f1553c8f --- /dev/null +++ b/restoration/source410/BT/MECH.CPP @@ -0,0 +1,39 @@ +//===========================================================================// +// File: mech.cpp // +// Project: BattleTech Brick: Entity Manager // +// Contents: Implementation details for the Mech entity // +//---------------------------------------------------------------------------// +// Date Who Modification // +// -------- --- ---------------------------------------------------------- // +// // +//---------------------------------------------------------------------------// +// Copyright (C) 1995, Virtual World Entertainment, Inc. // +// All Rights reserved worldwide // +// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // +//===========================================================================// + +#include +#pragma hdrstop + +#if !defined(MECH_HPP) +# include +#endif + +// +//############################################################################# +//############################################################################# +// +Derivation + Mech::ClassDerivations( + JointedMover::ClassDerivations, + "Mech" + ); + +Mech::SharedData + Mech::DefaultData( + Mech::ClassDerivations, + JointedMover::MessageHandlers, + JointedMover::AttributeIndex, + 33, + (Entity::MakeHandler)Mech::Make + ); diff --git a/restoration/source410/BT/MISSILE.CPP b/restoration/source410/BT/MISSILE.CPP new file mode 100644 index 00000000..577d4e37 --- /dev/null +++ b/restoration/source410/BT/MISSILE.CPP @@ -0,0 +1,29 @@ +//===========================================================================// +// Project: BattleTech // +//---------------------------------------------------------------------------// +// Copyright (C) 1995, Virtual World Entertainment, Inc. // +// All Rights reserved worldwide // +// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // +//===========================================================================// + +#include +#pragma hdrstop + +#if !defined(MISSILE_HPP) +# include +#endif + +Derivation + Missile::ClassDerivations( + Projectile::ClassDerivations, + "Missile" + ); + +Missile::SharedData + Missile::DefaultData( + Missile::ClassDerivations, + Mover::MessageHandlers, + Mover::AttributeIndex, + 1, + (Entity::MakeHandler)Missile::Make + ); diff --git a/restoration/source410/BT/PROJTILE.CPP b/restoration/source410/BT/PROJTILE.CPP new file mode 100644 index 00000000..7f94096e --- /dev/null +++ b/restoration/source410/BT/PROJTILE.CPP @@ -0,0 +1,29 @@ +//===========================================================================// +// Project: BattleTech // +//---------------------------------------------------------------------------// +// Copyright (C) 1995, Virtual World Entertainment, Inc. // +// All Rights reserved worldwide // +// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // +//===========================================================================// + +#include +#pragma hdrstop + +#if !defined(PROJTILE_HPP) +# include +#endif + +Derivation + Projectile::ClassDerivations( + Mover::ClassDerivations, + "Projectile" + ); + +Projectile::SharedData + Projectile::DefaultData( + Projectile::ClassDerivations, + Mover::MessageHandlers, + Mover::AttributeIndex, + 1, + (Entity::MakeHandler)Projectile::Make + ); diff --git a/restoration/source410/BT_L4/BTL4MPPR.CPP b/restoration/source410/BT_L4/BTL4MPPR.CPP new file mode 100644 index 00000000..df609a84 --- /dev/null +++ b/restoration/source410/BT_L4/BTL4MPPR.CPP @@ -0,0 +1,42 @@ +//===========================================================================// +// Project: BattleTech // +//---------------------------------------------------------------------------// +// Copyright (C) 1995, Virtual World Entertainment, Inc. // +// All Rights reserved worldwide // +// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // +//===========================================================================// + +#include +#pragma hdrstop + +#if !defined(BTL4MPPR_HPP) +# include +#endif + +Derivation + MechThrustmasterMapper::ClassDerivations( + Subsystem::ClassDerivations, + "MechThrustmasterMapper" + ); + +MechThrustmasterMapper::SharedData + MechThrustmasterMapper::DefaultData( + MechThrustmasterMapper::ClassDerivations, + Subsystem::MessageHandlers, + Subsystem::AttributeIndex, + 1 + ); + +Derivation + MechRIOMapper::ClassDerivations( + Subsystem::ClassDerivations, + "MechRIOMapper" + ); + +MechRIOMapper::SharedData + MechRIOMapper::DefaultData( + MechRIOMapper::ClassDerivations, + Subsystem::MessageHandlers, + Subsystem::AttributeIndex, + 1 + ); diff --git a/restoration/source410/MUNGA/APP.CPP b/restoration/source410/MUNGA/APP.CPP new file mode 100644 index 00000000..98d10133 --- /dev/null +++ b/restoration/source410/MUNGA/APP.CPP @@ -0,0 +1,1798 @@ +# if !defined(MUNGA_HPP) +# include +# endif +# if !defined(REGISTRY_HPP) +# include +# endif +# if !defined(RENDERER_HPP) +# include +# endif +# if !defined(CONTROLS_HPP) +# include +# endif +# if !defined(UPDATE_HPP) +# include +# endif +# if !defined(MISSION_HPP) +# include +# endif +# if !defined(PLAYER_HPP) +# include +# endif +# if !defined(DIRECTOR_HPP) +# include +# endif +# if !defined(APPMGR_HPP) +# include +# endif +# if !defined(AUDREND_HPP) +# include +# endif +# if !defined(VIDREND_HPP) +# include +# endif +# if !defined(GAUGREND_HPP) +# include +# endif +# if !defined(HOSTMGR_HPP) +# include +# endif +# if !defined(INTEREST_HPP) +# include +# endif +# if !defined(NTTMGR_HPP) +# include +# endif +# if !defined(APPTASK_HPP) +# include +# endif +# if !defined(CONSOLE_HPP) +# include +# endif +# if !defined(APPMSG_HPP) +# include +# endif +# if !defined(EVTSTAT_HPP) +# include +# endif + +#if defined(TRACE_FOREGROUND_PROCESSING) + BitTrace Foreground_Processing("Foreground Processing"); +#endif + +#if defined(TRACE_UPDATE_MANAGER) + BitTrace Update_Manager("Update Manager"); +#endif + +#if defined(TRACE_RENDERER_MANAGER) + BitTrace Renderer_Manager("Renderer Manager"); +#endif + +Application *application = NULL; +int Exit_Code = 0; +Logical Application::suppressGauges = False; + +//############################################################################# +//########################### Application ############################### +//############################################################################# + +//############################################################################# +// Message Support +// +const Receiver::HandlerEntry + Application::MessageHandlerEntries[]= +{ + MESSAGE_ENTRY(Application, StateQuery), + MESSAGE_ENTRY(Application, CheckLoad), + MESSAGE_ENTRY(Application, RunMission), + MESSAGE_ENTRY(Application, StopMission), + MESSAGE_ENTRY(Application, ResumeMission), + MESSAGE_ENTRY(Application, SuspendMission), + MESSAGE_ENTRY(Application, KeyCommand), + MESSAGE_ENTRY(Application, LoadMission), + MESSAGE_ENTRY(Application, AbortMission) +}; + +Application::MessageHandlerSet + Application::MessageHandlers(ELEMENTS(Application::MessageHandlerEntries), Application::MessageHandlerEntries, NetworkClient::MessageHandlers); + +//############################################################################# +// Virtual Data support +// +Derivation + Application::ClassDerivations(NetworkClient::ClassDerivations, "Application"); + +Application::SharedData + Application::DefaultData( + Application::ClassDerivations, + Application::MessageHandlers + ); + +// +//############################################################################# +// TestInstance +//############################################################################# +// +Logical + Application::TestInstance() const +{ + if (!IsDerivedFrom(ClassDerivations)) + { + return False; + } + Check(&applicationState); + if (eventQueue) + { + Check(eventQueue); + } + if (networkManager) + { + Check(networkManager); + } + if (entityManager) + { + Check(entityManager); + } + if (registry) + { + Check(registry); + } + if (hostManager) + { + Check(hostManager); + } + if (interestManager) + { + Check(interestManager); + } + if (updateManager) + { + Check(updateManager); + } + if (rendererManager) + { + Check(rendererManager); + } + if (controlsManager) + { + Check(controlsManager); + } + if (intercomManager) + { + Check(intercomManager); + } + if (resourceFile) + { + Check(resourceFile); + } + if (viewpointEntity) + { + Check(viewpointEntity); + } + if (currentMission) + { + Check(currentMission); + } + if (backgroundTasks) + { + Check(backgroundTasks); + } + if (audioRenderer) + { + Check(audioRenderer); + } + if (videoRenderer) + { + Check(videoRenderer); + } + if (gaugeRenderer) + { + Check(gaugeRenderer); + } + return True; +} + +// +//############################################################################# +// Application +//############################################################################# +// +Application::Application( + ResourceFile *resource_file, + ApplicationID application_ID, + ClassID class_ID, + SharedData &shared_data +): + NetworkClient(class_ID, shared_data, ApplicationClientID), + applicationState(ApplicationStateCount) +{ + Check(&shared_data); + Check(resource_file); + + applicationID = application_ID; + + // + // Create the event queue + // + eventQueue = GeneralEventQueue::Make( + EVENT_PRIORITIES_COUNT, + "MUNGA Event Count" + ); + Check(eventQueue); + + // + // Remember the resource file + // + resourceFile = resource_file; + missionPlayer = NULL; + + // + // NULL managers not yet created + // + networkManager = NULL; + registry = NULL; + controlsManager = NULL; + intercomManager = NULL; + backgroundTasks = NULL; + interestManager = NULL; + audioRenderer = NULL; + videoRenderer = NULL; + gaugeRenderer = NULL; + + // + // NULL pointers to other objects not yet created + // + viewpointEntity = NULL; + currentMission = NULL; + + // + // Create base level managers + // + entityManager = new EntityManager; + Register_Object(entityManager); + hostManager = new HostManager; + Register_Object(hostManager); + updateManager = new UpdateManager; + Register_Object(updateManager); + rendererManager = new RendererManager; + Register_Object(rendererManager); + backgroundTasks = new BackgroundTasks; + Register_Object(backgroundTasks); + + // + // Set up game state + // + executeFrames = False; + applicationState.SetState(InitializingState); + currentMission = NULL; + secondsRemainingInGame = 0.0f; + spoolFile = NULL; + routePacketFinished = False; + lastCreationMessage = Now(); + + // + // HACK - Init analysis bits + // + #if defined(TRACE_ON) + trace_manager.ResetTraces(); + #endif +} + +// +//############################################################################# +// GetApplicationManager +//############################################################################# +// +ApplicationManager* + Application::GetApplicationManager() +{ + PlugIteratorOf manager_link(this); + ApplicationManager *mgr; + while ((mgr = manager_link.ReadAndNext()) != NULL) + { + if (mgr->GetClassID() == ApplicationManagerClassID) + { + return mgr; + } + } + return NULL; +} + +Scalar + Application::GetApplicationLoopFrameRate() +{ + ApplicationManager *mgr = GetApplicationManager(); + Check(mgr); + return mgr->GetFrameRate(); +} + +// +//############################################################################# +// Initialize +//############################################################################# +// +void + Application::Initialize() +{ + Check(this); + + // + //---------------------------- + // Create the interest Manager + //---------------------------- + // + interestManager = MakeInterestManager(); + Register_Object(interestManager); + + // + //-------------------------------------------------------------------------- + // Create the network manager + //-------------------------------------------------------------------------- + // + networkManager = MakeNetworkManager(); + Register_Object(networkManager); + + // + //-------------------------------------------------------------------------- + // Create the registry, load static object streams + //-------------------------------------------------------------------------- + // + registry = MakeRegistry(); + if (registry) + { + Register_Object(registry); + registry->LoadStaticObjectStreamResource(); + } + + // + //-------------------------------------------------------------------------- + // Create the mode manager + //-------------------------------------------------------------------------- + // + modeManager = MakeModeManager(); + Register_Object(modeManager); + + // + //-------------------------------------------------------------------------- + // Create the controls manager + //-------------------------------------------------------------------------- + // + controlsManager = MakeControlsManager(); + Register_Object(controlsManager); + + // + //-------------------------------------------------------------------------- + // Create the intercom manager + //-------------------------------------------------------------------------- + // + intercomManager = MakeIntercomManager(); + Register_Object(intercomManager); + + // + //-------------------------------------------------------------------------- + // Add background tasks + //-------------------------------------------------------------------------- + // + LoadBackgroundTasks(); + executeFrames = True; + applicationState.SetState(WaitingForEgg); + + // + //-------------------------------------------------------------------------- + // Create the audio renderer + //-------------------------------------------------------------------------- + // + Verify(audioRenderer == NULL); + if ((audioRenderer = MakeAudioRenderer()) != NULL) + { + Register_Object(audioRenderer); + audioRenderer->Initialize(); + } + + // + //-------------------------------------------------------------------------- + // Create the video renderer + //-------------------------------------------------------------------------- + // + Verify(videoRenderer == NULL); + if ((videoRenderer = MakeVideoRenderer()) != NULL) + { + Register_Object(videoRenderer); + } + + // + //-------------------------------------------------------------------------- + // Create the gauge renderer + //-------------------------------------------------------------------------- + // + Verify(gaugeRenderer == NULL); + + if ((gaugeRenderer = MakeGaugeRenderer()) != NULL) + { + Register_Object(gaugeRenderer); + } +} + +// +//############################################################################# +// LoadBackgroundTasks +//############################################################################# +// +void + Application::LoadBackgroundTasks() +{ + Check(this); + + ApplicationTask *application_task; + + application_task = new RoutePacketTask; + Register_Object(application_task); + backgroundTasks->AddTask(application_task); + + application_task = new ProcessEventTask; + Register_Object(application_task); + backgroundTasks->AddTask(application_task); + + application_task = new AudioRendererTask; + Register_Object(application_task); + backgroundTasks->AddTask(application_task); + + application_task = new GaugeRendererTask; + Register_Object(application_task); + backgroundTasks->AddTask(application_task); + + application_task = new NetworkManagerTask; + Register_Object(application_task); + backgroundTasks->AddTask(application_task); + + application_task = new CompleteCyclesTask; + Register_Object(application_task); + backgroundTasks->AddTask(application_task); + + application_task = new FryDeathRowTask; + Register_Object(application_task); + backgroundTasks->AddTask(application_task); +} + +// +//############################################################################# +// MakeInterestManager +//############################################################################# +// +InterestManager* + Application::MakeInterestManager() +{ + return new InterestManager; +} + +// +//############################################################################# +// MakeNetworkManager +//############################################################################# +// +NetworkManager* + Application::MakeNetworkManager() +{ + return new NetworkManager(NetworkManager::DefaultData); +} + +// +//############################################################################# +// MakeRegistry +//############################################################################# +// +Registry* + Application::MakeRegistry() +{ + Fail("Application::MakeRegistry - Should never reach here"); + return NULL; +} + +// +//############################################################################# +// MakeModeManager +//############################################################################# +// +ModeManager* + Application::MakeModeManager() +{ + Fail("Application::MakeModeManager - Should never reach here"); + return NULL; +} + +// +//############################################################################# +// MakeControlsManager +//############################################################################# +// +ControlsManager* + Application::MakeControlsManager() +{ + Fail("Application::MakeControlsManager - Should never reach here"); + return NULL; +} + +// +//############################################################################# +// MakeIntercomManager +//############################################################################# +// +IcomManager* + Application::MakeIntercomManager() +{ + Fail("Application::MakeIntercomManager - Should never reach here"); + return NULL; +} + +// +//############################################################################# +// ExecuteForeground +//############################################################################# +// +Logical + Application::ExecuteForeground( + Time start_of_frame, + Scalar frame_duration + ) +{ + SET_FOREGROUND_PROCESSING(); + + Check(this); + Verify(application == this); + + if (!executeFrames) + { + CLEAR_FOREGROUND_PROCESSING(); + return executeFrames; + } + + Time + frame_ticks; + frame_ticks = frame_duration; + + // + //-------------------------------------------------------------------------- + // Controls Manager + // + // Poll all devices, update all control variables. + // + // This is executed before the update manager so that the + // models have valid control values. It is not necessary for + // the controls to operate at the frame rate of this loop. If + // the controls manager can run run at a lower rate it can + // throttle itself internally. + //-------------------------------------------------------------------------- + // + Check(controlsManager); +Time startControls = Now(); + controlsManager->Execute(); +Time endControls = Now(); + + if (GetApplicationState() == WaitingForEgg) + { + CLEAR_FOREGROUND_PROCESSING(); + return executeFrames; + } + + // + //-------------------------------------------------------------------------- + // Update Manager + // + // Execute replicants. + // Execute master entities if they are interesting here or + // elsewhere. + // Inform interest manager of possible interest zone change. + // If the master entity has provided and update message then + // send it to replicants. + // + // This is executed before the interest manager so that the + // interest manager can merge all interest zone changes before + // broadcasting interest arena deltas and building interesting + // entity lists. + // + // This is executed before the renderers so that the watchers + // have executed on the model and are ready for use by the + // renderers. + //-------------------------------------------------------------------------- + // + SET_UPDATE_MANAGER(); + +Time startUpdate = Now(); + Check(updateManager); + updateManager->Execute(start_of_frame); +Time endUpdate = Now(); + + CLEAR_UPDATE_MANAGER(); + + // + //-------------------------------------------------------------------------- + // Interest Manager + // + // Update the net interest arena. + // Calculate which interest zones should be released and which + // interest zones should be loaded + // Send a becoming uninteresting and becoming interesting + // message to the entity. + // Broadcast the interest arena change + // + // The renderer manager call, update interest origins will + // update only those interest origins required by the renderers + // executing this frame. + // + // This is executed before the renderer manager so that when + // the renderers execute they execute upon interest lists that + // are valid as of the end of a model/update frame. + // + // In theory the interest manager does not have to run every + // frame. If throttled less, this would cause fuzz at interest + // zone borders, which may or may not be acceptable depending + // on the size of the interest arena. + //-------------------------------------------------------------------------- + // +Time startInterest = Now(); + Check(rendererManager); + rendererManager->UpdateInterestOrigins(start_of_frame); + Check(interestManager); + interestManager->Execute(); +Time endInterest = Now(); + + // + //-------------------------------------------------------------------------- + // Renderer Manager + // + // Execute renderers. + // Get interest list from interest manager. + // Poll watchers. + // + // It is not necessary for all renderers to operate at the frame + // rate of this loop. If a renderer can run at a lower rate it + // does so via the renderer manager which will govern if a + // renderer executes this frame. + //-------------------------------------------------------------------------- + // + SET_RENDERER_MANAGER(); +Time startRender = Now(); + Check(rendererManager); + rendererManager->Execute(start_of_frame, frame_ticks, frame_ticks); +Time endRender = Now(); + CLEAR_RENDERER_MANAGER(); + + // + //-------------------------------------------------------------------------- + // Intercom Manager + //-------------------------------------------------------------------------- + // +Time startIntercom = Now(); + Check(intercomManager); + intercomManager->Execute(); +Time endIntercom = Now(); + + // + //-------------------------------------------------------------------------- + // Execution statistics + //-------------------------------------------------------------------------- + // + if (GetApplicationState() == RunningMission) + { + secondsRemainingInGame = + currentMission->GetGameLength() - (Now() - gameStarted); + } + routePacketFinished = False; + + CLEAR_FOREGROUND_PROCESSING(); + + return executeFrames && !Exit_Code; +} + +// +//############################################################################# +// ExecuteBackgroundTask +//############################################################################# +// +#define QUIET_TIME_OUT 3.0f +void + Application::ExecuteBackgroundTask() +{ + Check(this); + + // + //------------------------------------------------------------------------ + // If we are processing the map's creation messages, don't allow any other + // processing to happen until nothing appears for the timeout period + //------------------------------------------------------------------------ + // + if (GetApplicationState() == CreatingMission) + { + Check(networkManager); + + if (networkManager->RoutePacket()) + { + return; + } + + if (ProcessOneEvent(DefaultEventPriority)) + { + return; + } + + if (ProcessOneEvent(LowEventPriority)) + { + lastCreationMessage = Now(); + } + else + { + Scalar wait = Now() - lastCreationMessage; + if (wait > QUIET_TIME_OUT) + { + applicationState.SetState(LoadingMission); + networkManager->Marker("MUNGA MARKER - Starting renderer load...\n"); + networkManager->Mode(NetworkManager::UnreliableMode); + #if defined(LAB_ONLY) + DEBUG_STREAM << "Starting renderer load...\n" << flush; + #endif + } + } + return; + } + + // + // If there exists a high priority event, execute it + // + if (ProcessOneEvent(HighEventPriority)) + { + return; + } + + // + // if + // we are not finished routing packets this frames or + // we are not running the game + // then + // attempt to route a network packet + // we are finished routing packets for this frame + // + if ( + !routePacketFinished || + applicationState.GetState() != RunningMission + ) + { + Check(networkManager); + if (networkManager->RoutePacket()) + { + return; + } + } + routePacketFinished = True; + + // + // Execute lower priority tasks + // + Check(backgroundTasks); + backgroundTasks->Execute(); +} + +// +//############################################################################# +// Stop +//############################################################################# +// +void + Application::Stop() +{ + Check(this); + + // + // Dump analysis sample + // + #if defined(USE_TIME_ANALYSIS) + DEBUG_STREAM << "\nGame timing statistics:\n" << flush; + trace_manager.SnapshotTimingAnalysis(True); + #endif + #if defined(USE_TRACE_LOG) + trace_manager.SaveTraceLog("trace.log"); + #endif + #if defined(USE_EVENT_STATISTICS) + event_statistics_manager.Report(); + #endif + + // + // Set state variables to end game status + // + executeFrames = False; + DEBUG_STREAM << flush << flush; + applicationState.SetState(StoppingMission); +} + +// +//############################################################################# +// Shutdown +//############################################################################# +// +Logical + Application::Shutdown(int remainingApps) +{ + Check(this); + + // + //-------------------------------------------------------------------------- + // Shutdown gauge renderer + //-------------------------------------------------------------------------- + // + if (gaugeRenderer != NULL) + { + Check(gaugeRenderer); + gaugeRenderer->Shutdown(); + gaugeRenderer->UnlinkFromEntity(); + } + // + //-------------------------------------------------------------------------- + // Shutdown video renderer + //-------------------------------------------------------------------------- + // + if (videoRenderer != NULL) + { + Check(videoRenderer); + videoRenderer->Shutdown(); + videoRenderer->UnlinkFromEntity(); + } + // + //-------------------------------------------------------------------------- + // Shutdown audio renderer + //-------------------------------------------------------------------------- + // + if (audioRenderer != NULL) + { + Check(audioRenderer); + audioRenderer->Shutdown(); + audioRenderer->UnlinkFromEntity(); + } + + // + //-------------------------------------------------------------------------- + // Delete the viewpoint entity + //-------------------------------------------------------------------------- + // + if (viewpointEntity != NULL) + { + Unregister_Object(viewpointEntity); + delete viewpointEntity; + viewpointEntity = NULL; + } + + // + //-------------------------------------------------------------------------- + // Shutdown the interest manager + //-------------------------------------------------------------------------- + // + Check(interestManager); + interestManager->Shutdown(); + + // + //-------------------------------------------------------------------------- + // Shutdown the host manager + //-------------------------------------------------------------------------- + // + Check(hostManager); + hostManager->Shutdown(); + + // + //-------------------------------------------------------------------------- + // Shutdown the network manager + //-------------------------------------------------------------------------- + // + Check(networkManager); + networkManager->Shutdown(); + + // + //-------------------------------------------------- + // Delete the current mission if it has been created + //-------------------------------------------------- + // + if (currentMission) + { + Unregister_Object(currentMission); + delete currentMission; + currentMission = NULL; + } + + // + //--------------------------------- + // Allow the process to start again + //--------------------------------- + // + executeFrames = True; + applicationState.SetState(WaitingForEgg); +#if 0 + return !Exit_Code; +#else + return False; +#endif +} + +// +//############################################################################# +// Terminate +//############################################################################# +// +void + Application::Terminate() +{ + Check(this); + + // + //-------------------------------------------------------------------------- + // Delete the gauge renderer + //-------------------------------------------------------------------------- + // + if (gaugeRenderer != NULL) + { + Unregister_Object(gaugeRenderer); + delete gaugeRenderer; + gaugeRenderer = NULL; + } + + // + //-------------------------------------------------------------------------- + // Delete the video renderer + //-------------------------------------------------------------------------- + // + if (videoRenderer != NULL) + { + Unregister_Object(videoRenderer); + delete videoRenderer; + videoRenderer = NULL; + } + + // + //-------------------------------------------------------------------------- + // Delete the audio renderer + //-------------------------------------------------------------------------- + // + if (audioRenderer != NULL) + { + Unregister_Object(audioRenderer); + delete audioRenderer; + audioRenderer = NULL; + } + + // + //----------------------------------------------------------------------- + // Delete the intercom manager + //----------------------------------------------------------------------- + // + if (intercomManager != NULL) + { + Unregister_Object(intercomManager); + delete intercomManager; + intercomManager = NULL; + } + + // + //----------------------------------------------------------------------- + // Delete the controls manager + //----------------------------------------------------------------------- + // + if (controlsManager != NULL) + { + Unregister_Object(controlsManager); + delete controlsManager; + controlsManager = NULL; + } + + // + //------------------------ + // Delete the mode manager + //------------------------ + // + if (modeManager) + { + Unregister_Object(modeManager); + delete modeManager; + modeManager = NULL; + } + + // + //----------------------------------------------------------------------- + // Delete the registry + //----------------------------------------------------------------------- + // + if (registry != NULL) + { + Unregister_Object(registry); + delete registry; + registry = NULL; + } + + // + //----------------------------------------------------------------------- + // Delete the network manager + //----------------------------------------------------------------------- + // + if (networkManager != NULL) + { + Unregister_Object(networkManager); + delete networkManager; + networkManager = NULL; + } + + // + //---------------------------- + // Delete the interest manager + //---------------------------- + // + if (interestManager != NULL) + { + Unregister_Object(interestManager); + delete interestManager; + interestManager = NULL; + } +} + +// +//############################################################################# +// ~Application +//############################################################################# +// +Application::~Application() +{ + // + // Verify that these managers have been deleted + // + Verify(interestManager == NULL); + Verify(networkManager == NULL); + Verify(registry == NULL); + Verify(controlsManager == NULL); + Verify(intercomManager == NULL); + Verify(audioRenderer == NULL); + Verify(videoRenderer == NULL); + Verify(gaugeRenderer == NULL); + + // + // Verify that the mission has been deleted + // + Verify(currentMission == NULL); + + // + // Verify that the viewpoint entity has been deleted + // + Verify(viewpointEntity == NULL); + + // + // Destroy these managers + // + Unregister_Object(backgroundTasks); + delete backgroundTasks; + backgroundTasks = NULL; + + Unregister_Object(rendererManager); + delete rendererManager; + rendererManager = NULL; + + Unregister_Object(updateManager); + delete updateManager; + updateManager = NULL; + + Unregister_Object(hostManager); + delete hostManager; + hostManager = NULL; + + Unregister_Object(entityManager); + delete entityManager; + entityManager = NULL; + + resourceFile = NULL; + + // + // Destroy the event queue + // HACK - the event queue is transparently created as an array, + // therefore must be deleted as one + // + Unregister_Object(eventQueue); + delete[] eventQueue; + eventQueue = NULL; +} + +// +//############################################################################# +// StateQueryMessageHandler +//############################################################################# +// +void + Application::StateQueryMessageHandler( +#if DEBUG_LEVEL>0 + StateQueryMessage *message +#else + StateQueryMessage * +#endif + ) +{ + Check(this); + Check(message); + Verify(message->messageID == StateQueryMessageID); + + // + //-------------------------------------------------------------------------- + // Send the console our application state + //-------------------------------------------------------------------------- + // + Host *console_host; + + Check(GetHostManager()); + if ((console_host = GetHostManager()->GetConsoleHost()) != NULL) + { + Check(console_host); + + unsigned int appState = applicationState.GetState(); + + ConsoleApplicationStateResponseMessage + response_message( + 0, // GetHostManager()->GetLocalHostID(), + applicationState.GetState(), + GetApplicationID() + ); + + SendMessage( + console_host->GetHostID(), + ConsoleClientID, + &response_message + ); + } +} + +// +//############################################################################# +// CreateMission +//############################################################################# +// +void + Application::CreateMission(NotationFile *egg_notation_file) +{ + Check(this); + Check(egg_notation_file); + + // + //-------------------------------------------------------------------------- + // Create mission from egg notation file + //-------------------------------------------------------------------------- + // + currentMission = MakeMission(egg_notation_file, resourceFile); + Register_Object(currentMission); + secondsRemainingInGame = currentMission->GetGameLength(); + + // + //---------------------------------------------------------------------- + // Now, start up the network connect process. The network must have at + // least established the local host before returning, so that the player + // data load can work + //---------------------------------------------------------------------- + // + NetworkManager *net_mgr = GetNetworkManager(); + Check(net_mgr); + net_mgr->StartConnecting(currentMission); + currentMission->SetPlayerData(egg_notation_file); + + InterestManager *interest_mgr = GetInterestManager(); + Check(interest_mgr); + interest_mgr->LoadInterestArenas(currentMission); +} + +// +//############################################################################# +// MakeMission +//############################################################################# +// +Mission* + Application::MakeMission( + NotationFile*, + ResourceFile* + ) +{ + Fail("Application::MakeMisson - Should never reach here"); + return NULL; +} + +// +//############################################################################# +// LoadMissionMessageHandler +//############################################################################# +// +void + Application::LoadMissionMessageHandler(Message *) +{ + Check(this); + // + //-------------------------------------------------------------------------- + // Load the interest manager + //-------------------------------------------------------------------------- + // + #ifdef USE_TIME_ANALYSIS + trace_manager.StartTimingAnalysis(); + #endif + Check(interestManager); + interestManager->LoadMission(currentMission); + + // + //-------------------------------------------------------------------------- + // Make the player + //-------------------------------------------------------------------------- + // + Registry* registry = GetRegistry(); + Check(registry); + missionPlayer = registry->MakePlayer(currentMission); + Register_Object(missionPlayer); + + // + //-------------------------------------------------------------------------- + // Set application state to loading + //-------------------------------------------------------------------------- + // + applicationState.SetState(CreatingMission); + #if defined(LAB_ONLY) + DEBUG_STREAM << "Starting entity creation...\n" << flush; + #endif +} + +// +//############################################################################# +// MakeAndLinkViewpointEntity +//############################################################################# +// +Entity* + Application::MakeAndLinkViewpointEntity(Entity::MakeMessage* message) +{ + Check(this); + Check(message); + + // + //-------------------------------------------------------------------------- + // Create the viewpoint entity + //-------------------------------------------------------------------------- + // + #if DEBUG_LEVEL>0 + HostManager *host = GetHostManager(); + Check(host); + Verify(message->entityID.GetHostID() == host->GetLocalHostID()); + #endif + + Verify(viewpointEntity == NULL); + viewpointEntity = MakeViewpointEntity(message); + + // + //-------------------------------------------------------------------------- + // Post a message to check the status of the load + //-------------------------------------------------------------------------- + // + CheckLoadMessage check_load_message; + Post(DefaultEventPriority, this, &check_load_message); + + // + //-------------------------------------------------------------------------- + // Load audio renderer + //-------------------------------------------------------------------------- + // + if (audioRenderer != NULL) + { + Check(audioRenderer); + audioRenderer->LinkToEntity(viewpointEntity); + audioRenderer->LoadMission(GetCurrentMission()); + audioRenderer->SetRendererStatusToRunning(); + } + + // + //-------------------------------------------------------------------------- + // Load video renderer + //-------------------------------------------------------------------------- + // + if (videoRenderer != NULL) + { + Check(videoRenderer); + videoRenderer->LinkToEntity(viewpointEntity); + videoRenderer->LoadMission(GetCurrentMission()); + videoRenderer->SetRendererStatusToRunning(); + } + + // + //-------------------------------------------------------------------------- + // Load gauge renderer + //-------------------------------------------------------------------------- + // + if (gaugeRenderer != NULL) + { + Check(gaugeRenderer); + gaugeRenderer->LinkToEntity(viewpointEntity); + gaugeRenderer->LoadMission(GetCurrentMission()); + gaugeRenderer->SetRendererStatusToRunning(); + } + + return viewpointEntity; +} + +// +//############################################################################# +// MakeViewpointEntity +//############################################################################# +// +Entity* + Application::MakeViewpointEntity(Entity::MakeMessage*) +{ + Fail("Application::MakeViewpointEntity - Should never reach here"); + return NULL; +} + +// +//############################################################################# +// MakeAudioRenderer +//############################################################################# +// +AudioRenderer* + Application::MakeAudioRenderer() +{ + Fail("Application::MakeAudioRenderer - Should never reach here"); + return NULL; +} + +// +//############################################################################# +// MakeVideoRenderer +//############################################################################# +// +VideoRenderer* + Application::MakeVideoRenderer() +{ + Fail("Application::MakeVideoRenderer - Should never reach here"); + return NULL; +} + +// +//############################################################################# +// MakeGaugeRenderer +//############################################################################# +// +GaugeRenderer* + Application::MakeGaugeRenderer() +{ + Fail("Application::MakeGaugeRenderer - Should never reach here"); + return NULL; +} + +// +//############################################################################# +// CheckLoadMessageHandler +//############################################################################# +// +void + Application::CheckLoadMessageHandler( + CheckLoadMessage *message + ) +{ + Check(this); + Check(message); + Verify(message->messageID == CheckLoadMessageID); + + // + //-------------------------------------------------------------------------- + // If the application is already running then ignore this message + //-------------------------------------------------------------------------- + // + switch (applicationState.GetState()) + { + case CreatingMission: + case LoadingMission: + case WaitingForLaunch: + if (eventQueue->IsPriorityEmpty(MinEventPriority)) + { + Host *console_host; + + if (applicationState.GetState() == LoadingMission) + { + ResourceFile *res_file = GetResourceFile(); + Check(res_file); + res_file->ReleaseUnlockedResources(); + #if defined(LAB_ONLY) + DEBUG_STREAM << "Waiting for translocation!\n" << flush; + #endif + #if defined(USE_TIME_ANALYSIS) + DEBUG_STREAM << "Loading time usage:\n" << flush; + trace_manager.SnapshotTimingAnalysis(True); + #endif + } + applicationState.SetState(WaitingForLaunch); + Check(GetHostManager()); + + console_host = GetHostManager()->GetConsoleHost(); + if ( + ( + (console_host == NULL) || + ( + console_host != NULL && + console_host->GetConnectStatus() != Host::OnLineConnectionStatus + ) + ) + ) + { + // + // In the absence of the console just post the message to run. + // An IN-PROCESS console (hosted network mission) has no + // connection to this pod but still owns the launch -- the + // gConsoleMarshalsLaunch flag holds us at WaitingForLaunch + // until every pod in the mesh is staged (BT412). + // + RunMissionMessage run_mission_message; + Post(DefaultEventPriority, this, &run_mission_message); + Tell("Sent ready message to ourselves\n"); + } + } + + // + //----------------------------------------------------------------------- + // Post this message again until the application is running + //----------------------------------------------------------------------- + // + Time post_time; + + post_time = Now(); + #if DEBUG_LEVEL<3 + post_time += 1.0f; + #else + post_time += 5.0; + #endif + + Post(DefaultEventPriority, this, message, post_time); + break; + } +} + +// +//############################################################################# +// RunMissionMessageHandler +//############################################################################# +// +void + Application::RunMissionMessageHandler( +#if DEBUG_LEVEL>0 + RunMissionMessage *message +#else + RunMissionMessage * +#endif + ) +{ + Check(this); + Check(message); + Verify(message->messageID == RunMissionMessageID); + + // + //-------------------------------------------------------------------------- + // If the application is already running then ignore this message + //-------------------------------------------------------------------------- + // + switch (GetApplicationState()) + { + case RunningMission: + return; + + case LaunchingMission: + // + // Start analysis sample + // + #if defined(USE_TRACE_LOG) + { + char *log_size_str = getenv("LOGSIZE"); + if (log_size_str) + { + size_t log_size = atoi(log_size_str); + if (log_size > 0) + { + trace_manager.CreateTraceLog(log_size,True); + } + } + } + #endif + #ifdef USE_TIME_ANALYSIS + trace_manager.StartTimingAnalysis(); + #endif + + Tell("Application::RunMissionMessageHandler - running mission\n"); + applicationState.SetState(RunningMission); + gameStarted = Now(); + break; + + case WaitingForLaunch: + { + Tell("Application::RunMissionMessageHandler - Translocation\n"); + applicationState.SetState(LaunchingMission); + Player *player = GetMissionPlayer(); + Check(player); + Player::MissionStartingMessage + launch( + Player::MissionStartingMessageID, + sizeof(Player::MissionStartingMessage) + ); + player->Dispatch(&launch); + break; + } + + default: + Fail("Application::RunMissionMessageHandler - Not ready to run!\n"); + break; + } +} + +// +//############################################################################# +// SuspendMissionMessageHandler +//############################################################################# +// +void + Application::SuspendMissionMessageHandler( +#if DEBUG_LEVEL>0 + SuspendMissionMessage *message +#else + SuspendMissionMessage * +#endif + ) +{ + Check(this); + Check(message); + Verify(message->messageID == SuspendMissionMessageID); + + // + //-------------------------------------------------------------------------- + // The application should be either running or already suspended + //-------------------------------------------------------------------------- + // + switch (GetApplicationState()) + { + case RunningMission: + { + Player::MissionEndingMessage + player_message( + Player::MissionEndingMessageID, + sizeof(Player::MissionEndingMessage) + ); + Player *player; + + Tell("Application::SuspendMissionMessageHandler - Suspending\n"); + applicationState.SetState(SuspendingMission); + + player = GetMissionPlayer(); + Check(player); + player->Dispatch(&player_message); + } + break; + + case SuspendingMission: + // + // Already suspended + // + break; + + default: + // + // Any other state is an error + // + Fail("Application::SuspendMissionMessageHandler - Illegal state"); + break; + } +} + +// +//############################################################################# +// ResumeMissionMessageHandler +//############################################################################# +// +void + Application::ResumeMissionMessageHandler( +#if DEBUG_LEVEL>0 + ResumeMissionMessage *message +#else + ResumeMissionMessage * +#endif + ) +{ + Check(this); + Check(message); + Verify(message->messageID == ResumeMissionMessageID); + + // + //-------------------------------------------------------------------------- + // The application should be in the suspended state or resuming + //-------------------------------------------------------------------------- + // + switch (GetApplicationState()) + { + case SuspendingMission: + { + Player::MissionStartingMessage + launch( + Player::MissionStartingMessageID, + sizeof(Player::MissionStartingMessage) + ); + Player *player; + + Tell("Application::ResumeMissionMessageHandler - Resuming mission\n"); + applicationState.SetState(ResumingMission); + player = GetMissionPlayer(); + Check(player); + player->Dispatch(&launch); + } + break; + + case ResumingMission: + Tell("Application::ResumeMissionMessageHandler - Running mission\n"); + applicationState.SetState(RunningMission); + gameStarted = Now(); + break; + + default: + Fail("Application::ResumeMissionMessageHandler - Illegal state\n"); + break; + } +} + +// +//############################################################################# +// StopMissionMessageHandler +//############################################################################# +// +void + Application::StopMissionMessageHandler( +#if DEBUG_LEVEL>0 + StopMissionMessage *message +#else + StopMissionMessage * +#endif + ) +{ + Check(this); + Check(message); + Verify(message->messageID == StopMissionMessageID); + + // + //-------------------------------------------------------------------------- + // If the application is already stopping then ignore the message + //-------------------------------------------------------------------------- + // + switch (GetApplicationState()) + { + case StoppingMission: + return; + + case EndingMission: + case AbortingMission: + Stop(); + break; + + default: + { + applicationState.SetState(EndingMission); + Player *player = GetMissionPlayer(); + if (player) + { + networkManager->Mode(NetworkManager::ReliableMode); + Check(player); + Player::MissionEndingMessage + launch( + Player::MissionEndingMessageID, + sizeof(Player::MissionEndingMessage) + ); + player->Dispatch(&launch); + } + else + { + Stop(); + } + break; + } + } +} + +// +//############################################################################# +// StopMissionMessageHandler +//############################################################################# +// +void + Application::AbortMissionMessageHandler( +#if DEBUG_LEVEL>0 + AbortMissionMessage *message +#else + AbortMissionMessage * +#endif + ) +{ + Check(this); + Check(message); + Verify(message->messageID == AbortMissionMessageID); + + // + //-------------------------------------------------------------------------- + // If the application is already stopping then ignore the message + //-------------------------------------------------------------------------- + // + switch (GetApplicationState()) + { + case StoppingMission: + return; + + case EndingMission: + case AbortingMission: + Stop(); + break; + + default: + { + applicationState.SetState(AbortingMission); + Player *player = GetMissionPlayer(); + if (player) + { + Check(player); + Player::MissionEndingMessage + launch( + Player::MissionEndingMessageID, + sizeof(Player::MissionEndingMessage) + ); + player->Dispatch(&launch); + } + else + { + Stop(); + } + break; + } + } +} + +// +//############################################################################# +// KeyCommandMessageHandler +//############################################################################# +// +void + Application::KeyCommandMessageHandler( + ReceiverDataMessageOf *message + ) +{ + Check(this); + Check(message); + switch (message->dataContents) + { + case '&': + if (GetApplicationState() != StoppingMission) + { + Exit_Code = 1; + Stop(); + DEBUG_STREAM << "Mission stopped by keystroke!\n" << flush; + if (GetApplicationState() == WaitingForEgg) + { + applicationState.SetState(EndingMission); + } + } + break; + + #if defined(USE_TRACE_LOG) + case ' ': + trace_manager.MarkTraceLog(); + break; + case '/': + trace_manager.ResumeTraceLogging(); + break; + case '\\': + trace_manager.SuspendTraceLogging(); + break; + #endif + } +} + +//~~~~~~~~~~~~~~~~~~~~~~ Application__CheckLoadMessage ~~~~~~~~~~~~~~~~~~~~~~~~ + +Application__CheckLoadMessage::Application__CheckLoadMessage(): + NetworkClient::Message( + Application::CheckLoadMessageID, + sizeof(Application__CheckLoadMessage) + ) +{ +} + +#ifdef TEST_CLASS +# include "app.tcp" +#endif diff --git a/restoration/source410/MUNGA/APP.HPP b/restoration/source410/MUNGA/APP.HPP index a1f15249..06f5b091 100644 --- a/restoration/source410/MUNGA/APP.HPP +++ b/restoration/source410/MUNGA/APP.HPP @@ -409,7 +409,7 @@ public: static const HandlerEntry MessageHandlerEntries[]; //static MessageHandlerSet MessageHandlers; - static MessageHandlerSet& GetMessageHandlers(); + static MessageHandlerSet MessageHandlers; void StateQueryMessageHandler(StateQueryMessage *message); @@ -435,7 +435,7 @@ public: // Shared Data Support // public: - static Derivation *GetClassDerivations(); + static Derivation ClassDerivations; static SharedData DefaultData; static Logical DoSuppressGauges() { return suppressGauges; } @@ -505,7 +505,7 @@ protected: MakeVideoRenderer(); virtual GaugeRenderer* - MakeGaugeRenderer(int *secondaryIndex, int *aux1Index, int *aux2Index); + MakeGaugeRenderer(); virtual ModeManager* MakeModeManager(); diff --git a/restoration/source410/MUNGA/CULTURAL.CPP b/restoration/source410/MUNGA/CULTURAL.CPP new file mode 100644 index 00000000..c3e14b10 --- /dev/null +++ b/restoration/source410/MUNGA/CULTURAL.CPP @@ -0,0 +1,1093 @@ +# if !defined(MUNGA_HPP) +# include +# endif +#pragma hdrstop + +# if !defined(CULTURAL_HPP) +# include +# endif +# if !defined(TERRAIN_HPP) +# include +# endif +# if !defined(FILEUTIL_HPP) +# include +# endif +# if !defined(BOXTREE_HPP) +# include +# endif +# if !defined(BOXSOLID_HPP) +# include +# endif +# if !defined(SCNROLE_HPP) +# include +# endif +# if !defined(MISSION_HPP) +# include +# endif +# if !defined(EXPLODE_HPP) +# include +# endif +# if !defined(APP_HPP) +# include +# endif +# if !defined(INTEREST_HPP) +# include +# endif +# if !defined(HOSTMGR_HPP) +# include +# endif +# if !defined(NTTMGR_HPP) +# include +# endif +# if !defined(NAMELIST_HPP) +# include +# endif +# if !defined(CONSOLE_HPP) +# include +# endif + +//########################################################################## +//##################### Class CulturalIcon ########################## +//########################################################################## + +//############################################################################# +// Shared Data Support +// +Derivation + CulturalIcon::ClassDerivations(UnscalableTerrain::ClassDerivations, "CulturalIcon"); + + +CulturalIcon::SharedData + CulturalIcon::DefaultData( + CulturalIcon::ClassDerivations, + CulturalIcon::MessageHandlers, + CulturalIcon::AttributeIndex, + CulturalIcon::StateCount, + (UnscalableTerrain::MakeHandler)CulturalIcon::Make + ); +//############################################################################# +// Message Support +// +const Receiver::HandlerEntry + CulturalIcon::MessageHandlerEntries[]= +{ + MESSAGE_ENTRY(CulturalIcon, TakeDamage), + MESSAGE_ENTRY(CulturalIcon, SetBurningState) +}; + +CulturalIcon::MessageHandlerSet + CulturalIcon::MessageHandlers(ELEMENTS(CulturalIcon::MessageHandlerEntries), CulturalIcon::MessageHandlerEntries, UnscalableTerrain::MessageHandlers); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// + + +void + CulturalIcon::SetBurningStateMessageHandler(Message * /*burning_message*/) +{ + + SetSimulationState(CulturalIcon::BurningState); + ForceUpdate(DefaultUpdateModelFlag); + AlwaysExecute(); + +} +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + CulturalIcon::TakeDamageMessageHandler(TakeDamageMessage *damage_message) +{ + Check(damage_message); + + + if (damage_message->damageZone == -1 ) + { + damage_message->damageZone = 0; + } + + if (GetSimulationState() == CulturalIcon::DefaultState) + { + // + //~~~~~~~~~~~~~~~~~~ + // Update Replicants + //~~~~~~~~~~~~~~~~~~ + // + if (GetInstance() != ReplicantInstance) + { + ForceUpdate(DamageZoneUpdateModelFlag | DefaultUpdateModelFlag); + AlwaysExecute(); + } + // + //~~~~~~~~~~~~~~~~~~~~~ + // Call Derived Classes + //~~~~~~~~~~~~~~~~~~~~~ + // + UnscalableTerrain::TakeDamageMessageHandler(damage_message); + + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Update Collision Volumes if we died + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + + for(int ii=0;iiGetDamageZoneState() == DamageZone::BurningState) + { + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Create the explosion + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + Origin explode_origin = localOrigin; + + ResourceDescription::ResourceID explosion_ID; + + if ((damage_message->damageData.damageType == Damage::CollisionDamageType )&& + (crunchExplosionResourceID != -1)) + { + explosion_ID = crunchExplosionResourceID; + } + else + { + explosion_ID = explosionResourceID; + } + + Explosion::MakeMessage exp_message( + Explosion::MakeMessageID, + sizeof(Explosion::MakeMessage), + RegisteredClass::ExplosionClassID, + EntityID::Null, + explosion_ID, + Explosion::DefaultFlags, + explode_origin, + GetEntityID(), + GetEntityID() + ); + + #if (DEBUG_LEVEL > 0) + Explosion *new_exp = + #endif + Explosion::Make(&exp_message); + Register_Object(new_exp); + + Message dummy_message(SetBurningStateMessageID, sizeof(Message)); + Check(application); + Time now = Now(); + now += timeDelay; + application->Post(CreationEventPriority, this, &dummy_message, now); + + SetSimulationState(WaitingToBurn); + + UpdateCollisionVolumes(); + break; + } + } + } + Check_Fpu(); +} + + + + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + CulturalIcon::UpdateCollisionVolumes() +{ + Check(this); + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Get the Tree for these Collision Volumes + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + InterestManager *interest_mgr = + application->GetInterestManager(); + Check(interest_mgr); + InterestZone *zone = + interest_mgr->GetInterestZone(interestZoneID); + Check(zone); + BoxedSolidTree* tree = zone->GetCollisionRoot(); + Check(tree); + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Update Volumes based on RemoveVolume Flag + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + BoxedSolid *box = collisionVolumes; + while (box) + { + BoxedSolid *next_box = box->GetNextSolid(); + if (RemoveCollisionVolumeOnDeath()) + { + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Delete the Collision Volume + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + tree->Remove(box); + Unregister_Object(box); + delete box; + } + else + { + // + //~~~~~~~~~~~~~~~~~~~~~~ + // Move Collision Volume + //~~~~~~~~~~~~~~~~~~~~~~ + // + box->minY += destroyedYTranslation; + box->maxY += destroyedYTranslation; + } + box = next_box; + } + collisionVolumes = NULL; + Check_Fpu(); +} + +//############################################################################# +// Attribute Support +// +const CulturalIcon::IndexEntry + CulturalIcon::AttributePointers[]= +{ + ATTRIBUTE_ENTRY(CulturalIcon, TeamName, teamName) +}; + +CulturalIcon::AttributeIndexSet + CulturalIcon::AttributeIndex(ELEMENTS(CulturalIcon::AttributePointers), + CulturalIcon::AttributePointers, + UnscalableTerrain::AttributeIndex + ); +//############################################################################# +// Construction and Destruction +// + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +CulturalIcon::CulturalIcon( + MakeMessage *creation_message, + SharedData &shared_data +) : + UnscalableTerrain(creation_message, shared_data) +{ + + Str_Copy(teamName, "Defualt", sizeof(teamName)); + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Read in the ModelResource Information + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + ResourceDescription *res = + application->GetResourceFile()->SearchList( + resourceID, + ResourceDescription::GameModelResourceType + ); + Check(res); + res->Lock(); + ModelResource* model_resource = (ModelResource*)res->resourceAddress; + Check_Pointer(model_resource); + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Determine if we move or Destroy the + // Collision volume in Death of the map entity + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + if (model_resource->sinkCollisionVolume) + { + destroyedYTranslation = model_resource->destroyedYTranslation; + } + else + { + destroyedYTranslation = 0.0f; + SetRemoveCollisionVolumeFlag(); + } + + timeDelay = model_resource->timeDelay; + + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Is Stopping Collision Volume ? + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + if (model_resource->stoppingCollisionVolume) + { + SetStoppingCollisionVolumeFlag(); + } + + explosionResourceID = model_resource->explosionResourceID; + crunchExplosionResourceID = model_resource->crunchExplosionResourceID; + res->Unlock(); + + //DEBUG_STREAM << model_resource->crunchExplosionResourceID << endl << flush; + + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Read in DamageZone Information from the Resource + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + ResourceDescription *dmg_res = + application->GetResourceFile()->SearchList( + resourceID, + ResourceDescription::DamageZoneStreamResourceType + ); + Check(dmg_res); + dmg_res->Lock(); + DynamicMemoryStream damage_stream ( + dmg_res->resourceAddress, + dmg_res->resourceSize + ); + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~ + // skip over DamageZoneCount + //~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + damage_stream.AdvancePointer(sizeof(damageZoneCount)); + // + //~~~~~~~~~~~~~~~~~~~~~~~ + // Create the DamageZones + //~~~~~~~~~~~~~~~~~~~~~~~ + // + for(int ii=0;iiUnlock(); + Check_Fpu(); +} +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// + + + +void + CulturalIcon::ReadUpdateRecord(Simulation::UpdateRecord *message) +{ + Check(this); + Check_Pointer(message); + + UnscalableTerrain::ReadUpdateRecord(message); + + if (simulationState.GetOldState() != GetSimulationState() && (GetSimulationState() == BurningState)) + { + UpdateCollisionVolumes(); + } + Check_Fpu(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// + +Logical + CulturalIcon::CreateMakeMessage( + MakeMessage *creation_message, + NotationFile *model_file, + const ResourceDirectories *directories +) +{ + Check(creation_message); + Check(model_file); + + if (!UnscalableTerrain::CreateMakeMessage(creation_message, model_file, directories)) + { + return False; + } + + creation_message->messageLength = sizeof(MakeMessage); + creation_message->classToCreate = CulturalIconClassID; + creation_message->instanceFlags = MasterInstance|DynamicFlag|MapFlag|TrappedFlag; + return True; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +CulturalIcon* + CulturalIcon::Make(MakeMessage *creation_message) +{ + Check_Fpu(); + return new CulturalIcon(creation_message); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +CulturalIcon::~CulturalIcon() +{ + +} +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +int + CulturalIcon::CreateModelResource( + #if DEBUG_LEVEL>0 + ResourceFile *resource_file, + const char *model_name, + NotationFile *model_file, + const ResourceDirectories *directories, + ModelResource* model + #else + ResourceFile *resource_file, + const char *model_name, + NotationFile *model_file, + const ResourceDirectories *, + ModelResource* model + #endif +) +{ + Check(resource_file); + Check_Pointer(model_name); + Check(model_file); + Check_Pointer(directories); + + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Allocate memory for the resource + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + ModelResource *local_model = model; + if (!local_model) + { + local_model = new ModelResource; + Register_Pointer(local_model); + } + if ( + !model_file->GetEntry( + "gamedata", + "DestroyedYTranslation", + &local_model->destroyedYTranslation + ) + ) + { + local_model->sinkCollisionVolume = False; + local_model->destroyedYTranslation = 0.0f; + } + else + { + local_model->sinkCollisionVolume = True; + } + + if (!model_file->GetLogicalEntry( + "gamedata", + "StoppingCollisionVolume", + &local_model->stoppingCollisionVolume + ) + ) + { + local_model->stoppingCollisionVolume = False; + } + + if ( + !model_file->GetEntry( + "gamedata", + "TimeDelay", + &local_model->timeDelay + ) + ) + { + DEBUG_STREAM << model_name << " TimeDelay is missing " << endl << flush; + Fail("Exiting"); + } + + + // + //---------------------------------------------------------------------- + // Read in the Model Filename of the Explosion renderable, then find its + // resource ID in the resource file + //---------------------------------------------------------------------- + // + const char *explosion = "Unspecified"; + if ( + !model_file->GetEntry( + "gamedata", + "ExplosionModelFile", + &explosion + ) + ) + { + cout << model_name << " missing ExplosionModelFile!\n"; + Check_Fpu(); + return False; + } + + + ResourceDescription *res = NULL; + + if (strcmp(explosion,"Unspecified")) + { + res = resource_file->FindResourceDescription( + explosion, + ResourceDescription::ModelListResourceType + ); + } + if (!res) + { + cout << model_name << " cannot find " << explosion + << " in resource file!\n"; + Check_Fpu(); + return False; + } + if (res) + { + local_model->explosionResourceID = res->resourceID; + } + + + + const char *crunch_explosion = "Unspecified"; + + model_file->GetEntry( + "gamedata", + "CrunchExplosionModelFile", + &crunch_explosion + ); + + + local_model->crunchExplosionResourceID = -1; + + if (strcmp(crunch_explosion,"Unspecified")) + { + //res = NULL; + res = resource_file->FindResourceDescription( + crunch_explosion, + ResourceDescription::ModelListResourceType + ); + + if (!res) + { + cout << model_name << " cannot find " << crunch_explosion + << " in resource file!\n"; + Check_Fpu(); + return False; + } + else + { + local_model->crunchExplosionResourceID = res->resourceID; + } + + + } + + //DEBUG_STREAM << ":" << local_model->crunchExplosionResourceID << endl << flush; + + + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Write the model to the resource + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + if (!model) + { + ResourceDescription *new_res = + resource_file->AddResource( + model_name, + ResourceDescription::GameModelResourceType, + 1, + ResourceDescription::Preload, + local_model, + sizeof(*local_model) + ); + Unregister_Pointer(local_model); + delete local_model; + Check(new_res); + Check_Fpu(); + return new_res->resourceID; + } + else + { + Check_Fpu(); + return 0; + } +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +int + CulturalIcon::CreateDamageZoneStream( + ResourceFile *resource_file, + const char *model_name, + NotationFile *model_file, + const ResourceDirectories *directories + ) +{ + Check(resource_file); + Check_Pointer(model_name); + Check(model_file); + Check_Pointer(directories); + + // + //------------------- + // Find the .dmg file + //------------------- + // + const char* dmg_file_cname; + if ( + !model_file->GetEntry( + "gamedata", + "DamageZones", + &dmg_file_cname + ) + ) + { + cerr << model_name << " is missing .dmg file specification!\n"; + return -1; + } + + CString dmg_filename = + MakePathedFilename(directories->modelDirectory, dmg_file_cname); + + NotationFile *dmg_file = new NotationFile(dmg_filename); + Register_Object(dmg_file); + int page_count = dmg_file->PageCount(); + if (!page_count) + { + cerr << dmg_filename << " is empty or missing!\n"; + Unregister_Object(dmg_file); + delete dmg_file; + return -1; + } + + DynamicMemoryStream damage_stream; + + damage_stream << page_count; + NameList *dmg_namelist = dmg_file->MakePageList(); + Register_Object(dmg_namelist); + + NameList::Entry *dmg_entry = dmg_namelist->GetFirstEntry(); + + CString dmg_page_name; + while(dmg_entry) + { + dmg_page_name = dmg_entry->GetName(); + DamageZone::CreateStreamedDamageZone( + model_file, + model_name, + NULL, + dmg_page_name, + &damage_stream, + dmg_file, + directories + ); + dmg_entry = dmg_entry->GetNextEntry(); + } + + // + //~~~~~~~~~~~~~~~~~~~~~~~ + // Add Stream to Resource + //~~~~~~~~~~~~~~~~~~~~~~~ + // + ResourceDescription *new_res = + resource_file->AddResourceMemoryStream( + model_name, + ResourceDescription::DamageZoneStreamResourceType, + 1, + ResourceDescription::Preload, + &damage_stream + ); + Check(new_res); + + Unregister_Object(dmg_file); + delete dmg_file; + Unregister_Object(dmg_namelist); + delete dmg_namelist; + + return new_res->resourceID; +} + +//########################################################################## +//#################### Class Landmark ########################## +//########################################################################## + +//############################################################################# +// Shared Data Support +// +Derivation + Landmark::ClassDerivations(CulturalIcon::ClassDerivations, "Landmark"); + + +Landmark::SharedData + Landmark::DefaultData( + Landmark::ClassDerivations, + Landmark::MessageHandlers, + Landmark::AttributeIndex, + Landmark::StateCount, + (Landmark::MakeHandler)Landmark::Make + ); +//############################################################################# +// Message Support +// +const Receiver::HandlerEntry + Landmark::MessageHandlerEntries[]= +{ + MESSAGE_ENTRY(Landmark, TakeDamage) +}; + +Landmark::MessageHandlerSet + Landmark::MessageHandlers( + ELEMENTS(Landmark::MessageHandlerEntries), + Landmark::MessageHandlerEntries, + CulturalIcon::MessageHandlers + ); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Landmark::TakeDamageMessageHandler(TakeDamageMessage *damage_message) +{ + Check(damage_message); + + if (owningTeam == NULL) + { + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Initialize the owning team pointer + // with the Teams entity Group + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + Check(application); + EntityManager *entity_manager = application->GetEntityManager(); + Check(entity_manager); + EntityGroup *team_group = entity_manager->UseGroup("Teams"); + if (team_group) + { + ChainIteratorOf team_iterator(team_group->groupMembers); + Team *current_team; + while((current_team = (Team*) team_iterator.ReadAndNext() ) != NULL) + { + if (!strcmp(current_team->teamName, teamName)) + { + owningTeam = current_team; + break; + } + } + } + } + + + + if (owningTeam == NULL) + { + DEBUG_STREAM << "TEAM : '" << teamName << "' was never found! " << endl << flush; + exit (-1); + } + + + if (GetSimulationState() != BurningState) + { + CulturalIcon::TakeDamageMessageHandler(damage_message); + + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Calculate the Score Loss based + // on the Scenario Data + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + Check(scenarioRole); + #if 0 + Logical landmark_destroyed = GetSimulationState() == BurningState; + Scalar score_loss = scenarioRole->CalcDamageReceivedScore( + damage_message->damageData.damageAmount + ); + + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Tell the Console about the Damage + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + Check(application); + HostManager *host_manager = application->GetHostManager(); + Check(host_manager); + Host *console_host = host_manager->GetConsoleHost(); + + if (console_host) + { + Check(console_host); + ConsoleLandmarkDamagedMessage landmark_damaged_message( + damage_message->inflictingEntity.GetHostID(), + landmarkID, + damage_message->damageData.damageAmount, + landmark_destroyed, + score_loss + ); + + application->SendMessage( + console_host->GetHostID(), + NetworkClient::ConsoleClientID, + &landmark_damaged_message + ); + } + #endif + } +} + +Logical + CulturalIcon::TestInstance() const +{ + return IsDerivedFrom(ClassDerivations); +} + +//############################################################################# +// Construction and Destruction +// + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Landmark::Landmark( + MakeMessage *creation_message, + SharedData &shared_data +) : + CulturalIcon ( creation_message, shared_data) +{ + scenarioRole = NULL; + owningTeam = NULL; + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Initialize the owning team pointer + // with the Teams entity Group + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + Check(application); + EntityManager *entity_manager = application->GetEntityManager(); + Check(entity_manager); + EntityGroup *team_group = entity_manager->UseGroup("Teams"); + if (team_group) + { + ChainIteratorOf team_iterator(team_group->groupMembers); + Team *current_team; + while((current_team = (Team*) team_iterator.ReadAndNext() ) != NULL) + { + if (!strcmp(current_team->teamName, creation_message->teamName)) + { + owningTeam = current_team; + break; + } + } + } + + // + // If the team is null, that's ok. It will either show up over the network + // or be a free for all + // + + + Str_Copy(teamName, creation_message->teamName, sizeof(teamName)); + + + Check(application->GetCurrentMission()); + scenarioRole = + application->GetCurrentMission()->GetScenarioRole(creation_message->roleName); + if (!scenarioRole) + { + + scenarioRole = new ScenarioRole("Role::MapAssigned",creation_message->roleName); + Register_Object(scenarioRole); + application->GetCurrentMission()->AddScenarioRole(scenarioRole); + } + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Add this landmark to the Landmark Entity Group + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + EntityGroup *landmark_group = entity_manager->UseGroup("Landmarks"); + Check(landmark_group); + landmark_group->Add(this); + + Check_Fpu(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Landmark::~Landmark() +{ + +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + Landmark::CreateMakeMessage( + MakeMessage *creation_message, + NotationFile *model_file, + const ResourceDirectories *directories +) +{ + Check(creation_message); + Check(model_file); + + if (!CulturalIcon::CreateMakeMessage(creation_message, model_file, directories)) + { + return False; + } + + creation_message->messageLength = sizeof(MakeMessage); + creation_message->classToCreate = LandmarkClassID; + + char *p; + + // + //---------------------------- + // landmarkID allocated + // by map stream creation + //---------------------------- + // + + // + //~~~~~~~~~~~~~~~ + // Get the teamName + //~~~~~~~~~~~~~~~ + // + if ((p = strtok(NULL, ",")) == NULL) + { + cerr << "teamName missing!\n"; + return False; + } + Str_Copy(creation_message->teamName,p, sizeof(creation_message->teamName)); + + + // + //~~~~~~~~~~~~~~~~~ + // Get the roleName + //~~~~~~~~~~~~~~~~~ + // + if ((p = strtok(NULL, ",")) == NULL) + { + cerr << "roleName missing!\n"; + return False; + } + Str_Copy(creation_message->roleName,p, sizeof(creation_message->roleName)); + + + // + //~~~~~~~~~~~~~~~~~~~~~~ + // Get the Landmark Name + //~~~~~~~~~~~~~~~~~~~~~~ + // + if ((p = strtok(NULL, ",")) == NULL) + { + cerr << "Landmark Name missing!\n"; + return False; + } + Str_Copy(creation_message->landmarkName,p, sizeof(creation_message->landmarkName)); + + + return True; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Landmark* + Landmark::Make(MakeMessage *creation_message) +{ + Check_Fpu(); + return new Landmark(creation_message); +} + + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +int + Landmark::CreateModelResource( + ResourceFile *resource_file, + const char *model_name, + NotationFile *model_file, + const ResourceDirectories *directories, + ModelResource* model +) +{ + Check(resource_file); + Check_Pointer(model_name); + Check(model_file); + Check_Pointer(directories); + + + CulturalIcon::CreateModelResource(resource_file, model_name, model_file, directories, model); + + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Allocate memory for the resource + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + ModelResource *local_model = model; + if (!local_model) + { + local_model = new ModelResource; + Register_Pointer(local_model); + } + +#if 0 + const char *role_model_file; + if (!model_file->GetEntry( + "gamedata", + "RoleModelFile", + &role_model_file + ) + ) + { + cerr<FindResourceDescription( + role_model_file, + ResourceDescription::ModelListResourceType + ); + if (!res) + { + cout << model_name << " cannot find " << role_model_file + << " in resource file!\n"; + goto Dump_And_Die; + } + local_model->roleResourceID = res->resourceID; + } +#endif + + + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Write the model to the resource + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + if (!model) + { + ResourceDescription *new_res = + resource_file->AddResource( + model_name, + ResourceDescription::GameModelResourceType, + 1, + ResourceDescription::Preload, + local_model, + sizeof(*local_model) + ); + Unregister_Pointer(local_model); + delete local_model; + Check(new_res); + Check_Fpu(); + return new_res->resourceID; + } + else + { + Check_Fpu(); + return 0; + } +} + +Logical + Landmark::TestInstance() const +{ + return IsDerivedFrom(ClassDerivations); +} diff --git a/restoration/source410/MUNGA/DROPZONE.CPP b/restoration/source410/MUNGA/DROPZONE.CPP new file mode 100644 index 00000000..5ea8cf48 --- /dev/null +++ b/restoration/source410/MUNGA/DROPZONE.CPP @@ -0,0 +1,459 @@ +# if !defined(MUNGA_HPP) +# include +# endif +#pragma hdrstop + +# if !defined(DROPZONE_HPP) +# include +# endif +# if !defined(RANDOM_HPP) +# include +# endif +# if !defined(APP_HPP) +# include +# endif +# if !defined(HOSTMGR_HPP) +# include +# endif +# if !defined(NTTMGR_HPP) +# include +# endif +# if !defined(NOTATION_HPP) +# include +# endif +# if !defined(NAMELIST_HPP) +# include +# endif +# if !defined(PLAYER_HPP) +# include +# endif + +#define DOWN_TIME 5.0f + +//############################################################################# +//############################### DropZone ################################# +//############################################################################# + +//############################################################################# +// Shared Data Support +// +Derivation + DropZone::ClassDerivations(Entity::ClassDerivations,"DropZone"); + +DropZone::SharedData + DropZone::DefaultData( + DropZone::ClassDerivations, + DropZone::MessageHandlers, + DropZone::AttributeIndex, + DropZone::StateCount, + (Entity::MakeHandler)DropZone::Make + ); + +//############################################################################# +// Message Support +// +const Receiver::HandlerEntry + DropZone::MessageHandlerEntries[]= +{ + MESSAGE_ENTRY(DropZone, AssignDropZone) +}; + +DropZone::MessageHandlerSet + DropZone::MessageHandlers(ELEMENTS(DropZone::MessageHandlerEntries), DropZone::MessageHandlerEntries, Entity::MessageHandlers); + +//############################################################################# +// Construction and Destruction +// + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +DropZone::DropZone( + DropZone::MakeMessage *creation_message, + DropZone::SharedData &virtual_data +): + Entity(creation_message, virtual_data) +{ + Check_Pointer(this); + Check_Pointer(creation_message); + + SetValidFlag(); + dropZoneCount = 0; + dropZones = NULL; + + // + //-------------------------------------------------------------- + // Name the drop zone, and enter the zone in the drop zone group + //-------------------------------------------------------------- + // + Str_Copy(dropZoneName, creation_message->dropZoneName, sizeof(dropZoneName)); + EntityManager *entity_manager = application->GetEntityManager(); + Check(entity_manager); + EntityGroup* drop_zones = entity_manager->UseGroup("DropZones"); + Check(drop_zones); + drop_zones->Add(this); + + // + //----------------------------------------------------------------------- + // Now, interpret the data to create the appropriate number of drop zones + //----------------------------------------------------------------------- + // + MemoryStream + stream( + creation_message, + creation_message->messageLength, + sizeof(*creation_message) + ); + dropZoneCount = creation_message->dropZoneCount; + Verify(dropZoneCount > 0); + dropZones = new Origin[dropZoneCount]; + Register_Pointer(dropZones); + lastUsageTime = new Time[dropZoneCount]; + Register_Pointer(lastUsageTime); + lastUsedBy = new EntityID[dropZoneCount]; + Register_Pointer(lastUsedBy); + lastDeathCount = new int[dropZoneCount]; + Register_Pointer(lastDeathCount); + + for (int i=0; i= 0 && index < dropZoneCount); + Check(application); + + return + !lastUsageTime[index].ticks + || Now() - lastUsageTime[index] > DOWN_TIME + && application->GetApplicationState() == Application::RunningMission; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + DropZone::AssignDropZoneMessageHandler(AssignDropZoneMessage* message) +{ + Check(this); + Check_Pointer(message); + + Check(application); + HostManager *host = application->GetHostManager(); + Check(host); + Entity *entity = host->GetEntityPointer(message->requestingEntity); + Check(entity); + + // + //--------------------------------------------------------------------- + // If we have allocated a dropzone within the last ten seconds for this + // player, resend the data + //--------------------------------------------------------------------- + // + Origin *drop_zone = NULL; + int + lowest, highest, remaining, i; + for (i=0; irequestingEntity + && lastDeathCount[i] == message->deathCount + ) + { + lastUsageTime[i] = Now(); + drop_zone = &dropZones[i]; + goto Found_One; + } + } + + // + //------------------------------------------------------------------------ + // Figure out how many drop zones are available. If none are, repost this + // message to ourself + //------------------------------------------------------------------------ + // + lowest = dropZoneCount; + highest = -1; + remaining = 0; + for (i=0; i highest) + { + highest = i; + } + } + } + + // + //----------------------------------------------------- + // Now, randomly look about until we find one available + //----------------------------------------------------- + // + highest = highest - lowest + 1; + while (remaining) + { + i = lowest + Random(highest); + Verify(i < dropZoneCount && i >= 0); + if (IsAvailable(i)) + { + // + //------------------------------------------------------------------- + // Check to see if vehicle attached to a player is within 2 meters of + // this drop zone. If so, mark it unavailable for 3 seconds + //------------------------------------------------------------------- + // + EntityManager *entity_mgr = application->GetEntityManager(); + Check(entity_mgr); + EntityGroup *player_group = entity_mgr->FindGroup("Players"); + if ( + player_group + && application->GetApplicationState() + == Application::RunningMission + ) + { + Player *player; + ChainIteratorOf iterator(player_group->groupMembers); + while ((player = (Player*)iterator.ReadAndNext()) != NULL) + { + Check(player); + Entity *vehicle = player->GetPlayerVehicle(); + if (vehicle && player != entity) + { + Check(vehicle); + Vector3D distance; + distance.Subtract( + vehicle->localOrigin.linearPosition, + dropZones[i].linearPosition + ); + if (distance.LengthSquared() <= 4.0f) + { + lastUsedBy[i] = NULL; + lastUsageTime[i] = Now(); + lastUsageTime[i] -= DOWN_TIME - 1.0f; + --remaining; + if (i == lowest) + { + ++lowest; + --highest; + } + else if (i == lowest + highest - 1) + { + --highest; + } + break; + } + } + } + + // + //---------------------------------------------------------- + // If someone was in this spot, keep looking for another one + //---------------------------------------------------------- + // + if (player) + { + continue; + } + } + + lastUsageTime[i] = Now(); + drop_zone = &dropZones[i]; + lastUsedBy[i] = message->requestingEntity; + lastDeathCount[i] = message->deathCount; + remaining = 0; + } + } + + + // + //---------------------------------------------------------------- + // If no drop_zone could be found, repost the message to ourselves + //---------------------------------------------------------------- + // + if (!drop_zone) + { + Time when=Now(); + when += 0.1f; + application->Post(MaxEventPriority, this, message, when); + return; + } + + // + //-------------------------------------------------------------------- + // Send a message back to the requesting object what sent this message + //-------------------------------------------------------------------- + // +Found_One: + ReplyMessage + reply( + message->replyMessageID, + sizeof(ReplyMessage), + *drop_zone, + message->deathCount + ); + entity->Dispatch(&reply); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + DropZone::CreateMakeMessage( + MakeMessage *creation_message, + const char* model_name, + const char* resource_name, + NotationFile *map_file + ) +{ + Check(creation_message); + Check(map_file); + Check_Pointer(model_name); + Check_Pointer(resource_name); + + if (!Entity::CreateMakeMessage(creation_message, map_file, NULL)) + { + return False; + } + + creation_message->classToCreate = RegisteredClass::DropZoneClassID; + creation_message->instanceFlags = MapFlag|TrappedFlag; + + // + //----------------------------------------------- + // Count up the number of drop zones in our model + //----------------------------------------------- + // + Enumeration save_modes = map_file->GetModes(); + map_file->SetMode(NotationFile::CleanListMode); + + NameList *zone_list = + map_file->MakeEntryList(model_name, "dropzone"); + Register_Object(zone_list); + creation_message->dropZoneCount = zone_list->EntryCount(); + creation_message->messageLength = + sizeof(*creation_message) + + creation_message->dropZoneCount*sizeof(Origin); + if (!creation_message->dropZoneCount) + { + cout << "Error: " << model_name << " hasn't specified any drop zones!\n"; +Dump_And_Die: + Unregister_Object(zone_list); + delete zone_list; + map_file->PutModes(save_modes); + return False; + } + + // + //--------------------------------------------- + // Allocate a buffer to hold the drop zone data + //--------------------------------------------- + // + MemoryStream + stream( + creation_message, + creation_message->messageLength, + sizeof(*creation_message) + ); + + // + //---------------------------- + // zero out the drop zone name + //---------------------------- + // + for (int ii=0; iidropZoneName); ii++) + { + creation_message->dropZoneName[ii] = '\0'; + } + + Str_Copy( + creation_message->dropZoneName, + resource_name, + sizeof(creation_message->dropZoneName) + ); + + // + //----------------- + // Read in the data + //----------------- + // + NameList::Entry *drop_zone = zone_list->GetFirstEntry(); + while (drop_zone) + { + Point3D translation; + EulerAngles tmp_rotation; + + const char* zone_data = drop_zone->GetChar(); + sscanf( + zone_data, + "%f %f %f %f %f %f", + &translation.x, + &translation.y, + &translation.z, + &tmp_rotation.pitch, + &tmp_rotation.yaw, + &tmp_rotation.roll + ); + + ((Origin*)stream.GetPointer())->linearPosition = translation; + ((Origin*)stream.GetPointer())->angularPosition = tmp_rotation; + stream.AdvancePointer(sizeof(Origin)); + drop_zone = drop_zone->GetNextEntry(); + } + + Unregister_Object(zone_list); + delete zone_list; + map_file->PutModes(save_modes); + + return True; +} + +Logical + DropZone::TestInstance() const +{ + return IsDerivedFrom(ClassDerivations); +} diff --git a/restoration/source410/MUNGA/EXPLODE.CPP b/restoration/source410/MUNGA/EXPLODE.CPP new file mode 100644 index 00000000..28bce8e9 --- /dev/null +++ b/restoration/source410/MUNGA/EXPLODE.CPP @@ -0,0 +1,794 @@ +# if !defined(MUNGA_HPP) +# include +# endif +#pragma hdrstop + +# if !defined(EXPLODE_HPP) +# include +# endif +# if !defined(MOVER_HPP) +# include +# endif +# if !defined(BOXSOLID_HPP) +# include +# endif +# if !defined(COLLASST_HPP) +# include +# endif +# if !defined(DAMAGE_HPP) +# include +# endif +# if !defined(RANDOM_HPP) +# include +# endif +# if !defined(APP_HPP) +# include +# endif +# if !defined(OBJSTRM_HPP) +# include +# endif +# if !defined(HOSTMGR_HPP) +# include +# endif +# if !defined(NOTATION_HPP) +# include +# endif +# if !defined(NAMELIST_HPP) +# include +# endif + +//############################################################################# +//############################ Explosion ################################ +//############################################################################# + +//############################################################################# +// Shared Data Support +// +Derivation + Explosion::ClassDerivations(Entity::ClassDerivations, "Explosion"); + +Explosion::SharedData + Explosion::DefaultData( + Explosion::ClassDerivations, + Explosion::MessageHandlers, + Explosion::AttributeIndex, + Explosion::StateCount, + (Entity::MakeHandler)Explosion::Make + ); + +void + Explosion::ExplosionSimulation(Scalar) +{ + Check(application); + if ((Now() - creationTime) > explosionDuration) + { + CondemnToDeathRow(); + } +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void Explosion::SplashDamage +( EntityID inflicting, + Damage &damage, + Scalar collisionRadius, + Vector3D offset, + Entity * excluded) // Excluded should really be a set of entities! +{ + Check(this); + Check(entityHit); + if (excluded) + { + Check(excluded); + } + Check_Pointer(&damage); + Verify(0 < collisionRadius); + + + // + // The list of volumes we intersect + // + BoxedSolidCollisionList collision_list; + collision_list.Reset(); + + // + // Create the collision assistant to check movers against + // + CollisionAssistant *collision_assistant; + + collision_assistant = new CollisionAssistant(entityHit->GetInterestZoneID()); + Register_Object(collision_assistant); + Check(collision_assistant); + + BoxedSolidResource box; + Check_Pointer(&box); + box.solidType = BoxedSolid::YAxisCylinderType; + box.materialType = BoxedSolid::ConcreteMaterial; + const Vector3D min = Vector3D(-collisionRadius,-collisionRadius,-collisionRadius); + const Vector3D max = Vector3D(collisionRadius,collisionRadius,collisionRadius); + ExtentBox ext_box = ExtentBox(min,max); + box.solidExtents = ext_box; + box.sliceExtents = ext_box; + + BoxedSolidResource local_box; + local_box.Instance(box,localOrigin); + + BoxedSolid *splash_volume = BoxedSolid::MakeBoxedSolid(&local_box, this, NULL); + Register_Object(splash_volume); + + // + //--------------------------------- + // Test against the tangible movers + //--------------------------------- + // + Check(collision_assistant); + CollisionAssistant::MovingEntityIterator iterator(collision_assistant); + Entity *entity; + Mover *mover; + Check(splash_volume); + while ((entity = iterator.ReadAndNext()) != NULL) + { + // + //------------------------------------------------------------------ + // If we are checking against ourselves, skip it + //------------------------------------------------------------------ + // + Check(entity); + if (entity == this) + { + continue; + } + + // + //-------------------------------------------------- + // If we have a mover class object, check against it + //-------------------------------------------------- + // + if (entity->IsDerivedFrom(Mover::ClassDerivations)) + { + mover = Cast_Object(Mover *,entity); + Check(mover); + + mover->CheckVolumeAgainstBoxedSolidChain(&collision_list, splash_volume); + } + } + + // + //------------------------------------------------------------------------- + // Test against the static world + //------------------------------------------------------------------------- + // + InterestManager *interest_mgr = application->GetInterestManager(); + Check(interest_mgr); + InterestZone *zone = interest_mgr->GetInterestZone(interestZoneID); + Check(zone); + BoxedSolidTree* tree = zone->GetCollisionRoot(); + Check(tree); + tree->FindBoundingBoxesContaining( + splash_volume, + collision_list + ); + + Check_Fpu(); + Unregister_Object(collision_assistant); + delete collision_assistant; + Unregister_Object(splash_volume); + delete splash_volume; + + // + //------------------------------------------------------------------------- + // Make a sorted list of all the entities from the collision list, + // sorted by their distance from the explosion's origin. + //------------------------------------------------------------------------- + // + VChainOf radius_chain(NULL,False); + VChainIteratorOf radius_chain_iterator(radius_chain); + + Vector3D radius; + Entity *target_entity; + + + // + + for(int i = 0;i < collision_list.GetCollisionCount(); i++) + { + BoxedSolidCollision bsc = collision_list[i]; + Check(&bsc); + target_entity = (Entity*) ((bsc.GetTreeVolume())->GetOwningSimulation()); + Check(target_entity); + Verify(target_entity->IsDerivedFrom(Entity::ClassDerivations)); + if ((target_entity != entityHit) && (target_entity != this) && (target_entity != excluded)) + { + radius = Vector3D::Identity; + radius.Subtract(target_entity->localOrigin.linearPosition,localOrigin.linearPosition); + radius_chain.AddValue(target_entity, radius); + } + } + + // While remaining_bursts > 0, advance through list, pick a number of bursts + // to inflict, and call SendDamage to the current entity. + + Damage some_damage = damage; + int possible_targets = 0; + int damageable_targets = 0; + radius_chain_iterator.First(); + while ((target_entity = (Entity*) radius_chain_iterator.GetCurrent()) != NULL) + { + Check(target_entity); + radius = radius_chain_iterator.GetValue(); + radius_chain_iterator.Next(); + possible_targets++; + if (target_entity->damageZones) + { + + damageable_targets++; + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Set the damage data + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + some_damage.burstCount =damage.burstCount / (pow(radius.Length(), 1.2f)); + Min_Clamp(some_damage.burstCount,1); + #if DEBUG_LEVEL > 0 + DEBUG_STREAM << "At radius " << radius.Length() << ", applied burstCount is " << some_damage.burstCount << endl << flush; + DEBUG_STREAM << "Damage per burst is " << some_damage.damageAmount << endl << flush; + #endif + Vector3D force = Vector3D::Identity; + force.Multiply(radius,localToWorld); + some_damage.damageForce = force; + Point3D origin_point = Point3D::Identity; + origin_point.Add(localOrigin.linearPosition,offset); + some_damage.impactPoint = origin_point; + //some_damage.impactPoint.Add(origin_point,radius); + + // + //------------------------------------------ + // Send a damage message to the current target entity + //------------------------------------------ + // + + if (target_entity->GetEntityID() == inflicting) + { + DEBUG_STREAM << "Splash damage hurting inflicting entity." << endl << flush; + } + + if (excluded && target_entity->GetEntityID() == excluded->GetEntityID() ) + { + DEBUG_STREAM << "Splash damage hurting excluded entity!" << endl << flush; + } + + Entity::TakeDamageMessage take_damage( + Entity::TakeDamageMessageID, + sizeof(Entity::TakeDamageMessage), + inflicting, + -1, // We can't know what damage zone we hit + some_damage + ); + target_entity->Dispatch(&take_damage); + } + } + + #if DEBUG_LEVEL >0 + DEBUG_STREAM << "There were " << possible_targets << "entities within range, only " << damageable_targets << " had damage zones" << endl << flush; + #endif + Check_Fpu(); +} + +//############################################################################# +// Construction and Destruction +// + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Explosion::Explosion( + Explosion::MakeMessage *creation_message, + Explosion::SharedData &virtual_data +): + Entity(creation_message, virtual_data) +{ + Check_Pointer(this); + Check_Pointer(creation_message); + + // + //~~~~~~~~~~~~~~~~~~~~~~~ + // zero out any rotation + //~~~~~~~~~~~~~~~~~~~~~~~ + // + localOrigin.angularPosition = Quaternion::Identity; + + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Get the explosion model resource + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + ResourceDescription *resource_description; + ModelResource *model_resource; + + Check(application); + Check(application->GetResourceFile()); + resource_description = + application->GetResourceFile()->SearchList( + resourceID, + ResourceDescription::GameModelResourceType + ); + Check(resource_description); + resource_description->Lock(); + model_resource = (ModelResource*)resource_description->resourceAddress; + Check_Pointer(model_resource); + + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Get the creating entity and entity hit by explosion + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + Check(application->GetHostManager()); + entityHit = + application->GetHostManager()->GetEntityPointer( + creation_message->entityHitID + ); + Check(entityHit); + + if (creation_message->creatingEntityID != EntityID::Null) + { + creatingEntity = + application->GetHostManager()->GetEntityPointer( + creation_message->creatingEntityID + ); + Check(creatingEntity); + } + else + { + creatingEntity = NULL; + } + + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Calculate the localHitPosition in terms + // local coordinate system of the entityHit + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + localHitPosition.MultiplyByInverse( + localOrigin.linearPosition, + entityHit->localToWorld + ); + + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Get the explosion duration + //~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + explosionDuration = model_resource->explosionDuration; + +#if 0 + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // If an explosion resource table is being used then + // use it to set the resource + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + if (model_resource->resourceTableObjectID != NullObjectID) + { + // + // If the explosion hit us, set the material to our craft, + // If the explosion hit an opponent, set the material to other craft, + // If the explosion hit something else then get the material... + // + Enumeration material_type; + + Check(application); + Entity *viewpoint_entity = application->GetViewpointEntity(); + Check(viewpoint_entity); + Verify(creation_message->entityHitID != EntityID::Null); + + // ECH 8/25/95 - Is this the best way to get our vehicle? + if ( + creation_message->entityHitID == + viewpoint_entity->GetEntityID() + ) + { + material_type = BoxedSolid::OurCraftMaterial; + } + else + { + // ECH 8/25/95 - Is this the best way to identify other vehicles? + if ( + entityHit != NULL && + entityHit->GetPlayerLink() != NULL + ) + { + material_type = BoxedSolid::OtherCraftMaterial; + } + else + { + // ECH 8/25/95 - How to get material? Just use this for now. + material_type = BoxedSolid::ConcreteMaterial; + } + } + + // + // Get resource table pointer, + // Then set the appropriate resource ID + // + Plug *plug; + ExplosionResourceTable *resource_table; + ResourceDescription::ResourceID new_resource_ID; + + plug = PlugStreamManager::FindPlug(model_resource->resourceTableObjectID); + resource_table = Cast_Object(ExplosionResourceTable*, plug); + Check(resource_table); + new_resource_ID = resource_table->FindResourceID(material_type); + if (new_resource_ID != ResourceDescription::NullResourceID) + { + resourceID = new_resource_ID; + } + } +#else + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // If an explosion resource table is being used then + // use it to set the resource + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + if (model_resource->resourceTableObjectID != NullObjectID) + { + // + // Get resource table pointer, + // Then set the appropriate resource ID + // + Plug *plug; + ExplosionResourceTable *resource_table; + ResourceDescription::ResourceID new_resource_ID; + + plug = PlugStreamManager::FindPlug(model_resource->resourceTableObjectID); + resource_table = Cast_Object(ExplosionResourceTable*, plug); + Check(resource_table); + new_resource_ID = resource_table->FindResourceID(entityHit); + if (new_resource_ID != ResourceDescription::NullResourceID) + { + resourceID = new_resource_ID; + } + } +#endif + + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Set performance and entity validity + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + resource_description->Unlock(); + SetPerformance(&Explosion::ExplosionSimulation); + SetValidFlag(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Explosion* + Explosion::Make(Explosion::MakeMessage *creation_message) +{ + Check(application); + HostManager *host_mgr = application->GetHostManager(); + Check(host_mgr); + Entity *entity = host_mgr->GetEntityPointer(creation_message->entityHitID); + if (entity) + { + return new Explosion(creation_message); + } + Tell( + "Warning: Explosion ignored - entity " << creation_message->entityHitID + << " couldn't be found!\n" + ); + return NULL; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Explosion::~Explosion() +{ +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + Explosion::TestInstance() const +{ + return IsDerivedFrom(ClassDerivations); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// CreateModelResource +// +ResourceDescription::ResourceID + Explosion::CreateModelResource( + ResourceFile *resource_file, + const char *model_name, + NotationFile *model_file, + const ResourceDirectories* + ) +{ + Check(resource_file); + Check_Pointer(model_name); + Check(model_file); + + ModelResource local_model; + if( + !model_file->GetEntry( + "gamedata", + "ExplosionDuration", + &local_model.explosionDuration + ) + ) + { + cerr<GetEntry( + "gamedata", + "ExplosionResourceTable", + &resource_table_name + ) + ) + { + // + // Get the object ID and set it in the model resource + // + local_model.resourceTableObjectID = + PlugStreamManager::FindPlugName(resource_table_name); + if (local_model.resourceTableObjectID == NullObjectID) + { + cout << "resource_table_name == " << resource_table_name << "\n"; + Fail("Explosion::CreateModelResource - ExplosionResourceTable not found"); + } + Verify(local_model.resourceTableObjectID != NullObjectID); + } + else + { + local_model.resourceTableObjectID = NullObjectID; + } + + ResourceDescription *resource_description = + resource_file->AddResource( + model_name, + ResourceDescription::GameModelResourceType, + 1, + ResourceDescription::Preload, + &local_model, + sizeof(ModelResource) + ); + Check(resource_description); + return resource_description->resourceID; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Enumeration + Explosion::GetInterestPriority(Entity *linked_entity) +{ + Check(this); + Check(linked_entity); + + return + ( + (linked_entity == creatingEntity) ? + HighInterestPriority : + LowInterestPriority + ); +} + +//############################################################################# +//###################### ExplosionResourceTable ######################### +//############################################################################# + +// +//############################################################################# +//############################################################################# +// +ExplosionResourceTable::ExplosionResourceTable(PlugStream *stream): + Plug(stream), + resourceIDSocket(NULL, True) +{ + Check(stream); + Check(&resourceIDSocket); + + CollectionSize table_size; + *stream >> table_size; + + for (CollectionSize i = 0; i < table_size; i++) + { + Enumeration material_type; + ResourceDescription::ResourceID resource_ID; + ResourceIDPlug *resource_ID_Plug; + + *stream >> material_type >> resource_ID; + + resource_ID_Plug = new ResourceIDPlug(resource_ID); + Register_Object(resource_ID_Plug); + resourceIDSocket.AddValue(resource_ID_Plug, material_type); + } +} + +// +//############################################################################# +//############################################################################# +// +ExplosionResourceTable::~ExplosionResourceTable() +{ + TableIteratorOf + iterator(&resourceIDSocket); + + Check(&iterator); + iterator.DeletePlugs(); +} + +// +//############################################################################# +//############################################################################# +// +void + ExplosionResourceTable::BuildFromPage( + ObjectStream *stream, + NameList *name_list, + ClassID class_ID, + ObjectID object_ID + ) +{ + Check(stream); + Check(name_list); + + Plug::BuildFromPage(stream, name_list, class_ID, object_ID); + + // + //-------------------------------------------------------------------------- + // Write number of entries + //-------------------------------------------------------------------------- + // + CollectionSize table_size = 0; + NameList::Entry *entry; + + Check(name_list); + entry = name_list->GetFirstEntry(); + while (entry != NULL) + { + Check(entry); + if (entry->IsName("table_entry")) + table_size++; + entry = entry->GetNextEntry(); + } + *stream << table_size; + + // + //-------------------------------------------------------------------------- + // Write entries + //-------------------------------------------------------------------------- + // + #if DEBUG_LEVEL>0 + CollectionSize i = 0; + #endif + + Check(name_list); + entry = name_list->GetFirstEntry(); + while (entry != NULL) + { + Check(entry); + if (entry->IsName("table_entry")) + { + CString table_entry, token; + Enumeration material_type; + ResourceDescription *resource_description; + ResourceDescription::ResourceID resource_ID; + + Check_Pointer(entry->GetChar()); + table_entry = entry->GetChar(); + + // + // Material + // + Check_Pointer(table_entry.GetNthToken(0)); + material_type = atol(table_entry.GetNthToken(0)); + + // + // Resource + // + Check_Pointer(table_entry.GetNthToken(1)); + Check(stream->GetResourceFile()); + resource_description = + stream->GetResourceFile()->FindResourceDescription( + table_entry.GetNthToken(1), + ResourceDescription::ModelListResourceType + ); + Check(resource_description); + resource_ID = resource_description->resourceID; + + *stream << material_type << resource_ID; + #if DEBUG_LEVEL>0 + i++; + #endif + } + entry = entry->GetNextEntry(); + } + #if DEBUG_LEVEL>0 + Verify(i == table_size); + #endif +} + +// +//############################################################################# +//############################################################################# +// +Logical + ExplosionResourceTable::TestInstance() const +{ + Plug::TestInstance(); + Check(&resourceIDSocket); + return True; +} + +// +//############################################################################# +//############################################################################# +// +ResourceDescription::ResourceID + ExplosionResourceTable::FindResourceID(Enumeration material_type) +{ + Check(this); + + ResourceIDPlug *resource_ID_Plug; + if ((resource_ID_Plug = resourceIDSocket.Find(material_type)) != NULL) + { + Check(resource_ID_Plug); + return resource_ID_Plug->GetItem(); + } + return ResourceDescription::NullResourceID; +} + +// +//############################################################################# +//############################################################################# +// +ResourceDescription::ResourceID + ExplosionResourceTable::FindResourceID(Entity *entity_hit) +{ + Check(this); + Check(entity_hit); + + // + // If the explosion hit us, set the material to our craft, + // If the explosion hit an opponent, set the material to other craft, + // If the explosion hit something else then get the material... + // + Enumeration material_type; + Entity *viewpoint_entity; + + Check(application); + viewpoint_entity = application->GetViewpointEntity(); + Check(viewpoint_entity); + + // ECH 8/25/95 - Is this the best way to get our vehicle? + if (entity_hit->GetEntityID() == viewpoint_entity->GetEntityID()) + { + material_type = BoxedSolid::OurCraftMaterial; + } + // ECH 8/25/95 - Is this the best way to identify other vehicles? + else if (entity_hit->GetPlayerLink() != NULL) + { + material_type = BoxedSolid::OtherCraftMaterial; + } + else + { + // ECH 8/25/95 - How to get material? Just use this for now. + material_type = BoxedSolid::ConcreteMaterial; + } + + // + // Return the appropriate resource ID + // + return FindResourceID(material_type); +} diff --git a/restoration/source410/MUNGA/NETWORK.CPP b/restoration/source410/MUNGA/NETWORK.CPP new file mode 100644 index 00000000..e4ed6dfc --- /dev/null +++ b/restoration/source410/MUNGA/NETWORK.CPP @@ -0,0 +1,44 @@ +//===========================================================================// +// File: network.cpp // +// Project: MUNGA Brick: Network // +// Contents: Implementation details for network clients // +//---------------------------------------------------------------------------// +// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. // +// All Rights reserved worldwide // +// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // +//===========================================================================// + +#include +#pragma hdrstop + +#if !defined(NETWORK_HPP) +# include +#endif + +// +//############################################################################# +//############################################################################# +// +Derivation + NetworkClient::ClassDerivations( + Receiver::ClassDerivations, + "NetworkClient" + ); + +NetworkClient::SharedData + NetworkClient::DefaultData( + NetworkClient::ClassDerivations, + Receiver::MessageHandlers + ); + +Derivation + NetworkManager::ClassDerivations( + NetworkClient::ClassDerivations, + "NetworkManager" + ); + +NetworkManager::SharedData + NetworkManager::DefaultData( + NetworkManager::ClassDerivations, + Receiver::MessageHandlers + ); diff --git a/restoration/source410/MUNGA/PLAYER.CPP b/restoration/source410/MUNGA/PLAYER.CPP new file mode 100644 index 00000000..3ce1dffc --- /dev/null +++ b/restoration/source410/MUNGA/PLAYER.CPP @@ -0,0 +1,893 @@ +# if !defined(MUNGA_HPP) +# include +# endif +#pragma hdrstop + +# if !defined(PLAYER_HPP) +# include +# endif +# if !defined(ICOM_HPP) +# include +# endif +# if !defined(CAMSHIP_HPP) +# include +# endif +# if !defined(DROPZONE_HPP) +# include +# endif +# if !defined(MISSION_HPP) +# include +# endif +# if !defined(AUDIO_HPP) +# include +# endif +# if !defined(DIRECTOR_HPP) +# include +# endif +# if !defined(APP_HPP) +# include +# endif +# if !defined(HOSTMGR_HPP) +# include +# endif +# if !defined(NTTMGR_HPP) +# include +# endif +# if !defined(CONSOLE_HPP) +# include +# endif +# if !defined(APPMSG_HPP) +# include +# endif + +//############################################################################# +//####################### Player::StatusMessage ######################### +//############################################################################# + +Player__StatusMessage::Player__StatusMessage(Player *player_involved, int message_type, Scalar display_time) +{ + playerInvolved = player_involved; + messageType = message_type; + displayTime = display_time; +} + +//############################################################################# +//############################### Player ################################ +//############################################################################# + +//############################################################################# +// Shared Data Support +// +Derivation + Player::ClassDerivations(Entity::ClassDerivations, "Player"); + +Player::SharedData + Player::DefaultData( + Player::ClassDerivations, + Player::MessageHandlers, + Player::AttributeIndex, + Player::StateCount, + (Entity::MakeHandler)Player::Make + ); + +//############################################################################# +// Attribute Support +// + +const Player::IndexEntry + Player::AttributePointers[]= +{ + ATTRIBUTE_ENTRY(Player, CurrentScore, currentScore), + ATTRIBUTE_ENTRY(Player, PlayerRanking, playerRanking), + ATTRIBUTE_ENTRY(Player, DropZoneLocation, dropZoneLocation), + ATTRIBUTE_ENTRY(Player, StatusMessagePointer,statusMessagePointer), + ATTRIBUTE_ENTRY(Player, PlayerBitmapIndex, playerBitmapIndex), + ATTRIBUTE_ENTRY(Player, PlayerHighlighted, playerHighlighted) +}; + +Player::AttributeIndexSet + Player::AttributeIndex(ELEMENTS(Player::AttributePointers), + Player::AttributePointers, + Entity::AttributeIndex + ); + +//############################################################################# +// Message Support +// +const Receiver::HandlerEntry + Player::MessageHandlerEntries[]= +{ + MESSAGE_ENTRY(Player, DropZoneReply), + MESSAGE_ENTRY(Player, Score), + MESSAGE_ENTRY(Player, VehicleDead), + MESSAGE_ENTRY(Player, MissionStarting), + MESSAGE_ENTRY(Player, MissionEnding) +}; + +Player::MessageHandlerSet + Player::MessageHandlers(ELEMENTS(Player::MessageHandlerEntries), Player::MessageHandlerEntries, Entity::MessageHandlers); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Player::MissionStartingMessageHandler(Message *) +{ + Check(this); + Tell("Player::MissionStartingMessageHandler - starting fade in\n"); + fadeTimeRemaining = 3.0f; + SetSimulationState(MissionStartingState); + Check_Fpu(); +} +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Player::MissionEndingMessageHandler(Message *) +{ + Check(this); + fadeTimeRemaining = 3.0f; + ForceUpdate(); + SetSimulationState(MissionEndingState); + Check_Fpu(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Enumeration + Player::GetAudioRepresentation( +#if DEBUG_LEVEL>0 + Entity *linked_entity +#else + Entity * +#endif + ) +{ + Check(this); + Check(linked_entity); + Check_Fpu(); + + return + (GetInstance() == MasterInstance) ? + InternalAudioRepresentation : ExternalAudioRepresentation; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Player::ScoreMessageHandler(ScoreMessage *message) +{ + Check(this); + Check(message); + + currentScore += message->scoreAward; + + // + // HACK - ECH 7/6/95 - Allow the player vehicle to respond to score + // messages, allows attribute system to be used for scoring + // + Check(playerVehicle); + playerVehicle->RespondToScoreMessage(message); + Check_Fpu(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Player::DropZoneReplyMessageHandler( + DropZone::ReplyMessage * //message + ) +{ + Check(this); + Fail("Drop zone reply should not be handled by base player class!\n"); +} +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Player::CreatePlayerVehicle(Origin camera_origin) +{ + Check(this); + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Create any MUNGA level vehicles + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + if (IsCameraShipPlayer()) + { + Check(application); + ResourceFile *resources = application->GetResourceFile(); + Check(resources); + Check_Pointer(playerMission->GetGameModel()); + + HostManager *host_manager = application->GetHostManager(); + Check(host_manager); + ResourceDescription *camera_res = + resources->FindResourceDescription( + playerMission->GetGameModel(), + ResourceDescription::ModelListResourceType + ); + Check(camera_res); + CameraShip::MakeMessage + create_camera( + CameraShip::MakeMessageID, + sizeof(CameraShip::MakeMessage), + EntityID(host_manager->GetLocalHostID()), + CameraShipClassID, + EntityID::Null, + camera_res->resourceID, + CameraShip::DefaultFlags, + camera_origin, + Motion::Identity, + Motion::Identity + ); + CameraShip *camera = + (CameraShip*)application->MakeAndLinkViewpointEntity(&create_camera); + Register_Object(camera); + playerVehicle = camera; + } + Check_Fpu(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Player::VehicleDeadMessageHandler(VehicleDeadMessage *message) +{ + Check(this); + Check(message); + Check(application); + + + //DEBUG_STREAM << "VEHICLEDEAD : " << endl << flush; + + // + //------------------------------------------------------------------------- + // If we have let the player fry, send a message to the dropzone to give us + // a new location to return to + //------------------------------------------------------------------------- + // + if ( + message->deathCount == deathCount + && GetSimulationState() != DropZoneAcquiredState) + { + DropZone *dropzone; + + + + // + //--------------------------------------------------------------------- + // If no dropzone has been assigned to this death, find the closest one + //--------------------------------------------------------------------- + // + if (message->dropZoneID == EntityID::Null) + { + + //DEBUG_STREAM << " Find Closest" << endl << flush; + + EntityManager *entity_manager = application->GetEntityManager(); + Check(entity_manager); + EntityGroup *dropzones = entity_manager->FindGroup("DropZones"); + Check(dropzones); + ChainIteratorOf iterator(dropzones->groupMembers); + + DropZone *closest_dropzone; + Vector3D range; + Scalar closest_range; + + while ((dropzone = (DropZone*)iterator.ReadAndNext()) != NULL) + { + Check(dropzone); + + if (!strnicmp(dropzone->GetDropZoneName(), "win", 3)) + { + continue; + } + + closest_dropzone = dropzone; + range.Subtract( + localOrigin.linearPosition, + dropzone->localOrigin.linearPosition + ); + closest_range = range.LengthSquared(); + break; + } + + while ((dropzone = (DropZone*)iterator.ReadAndNext()) != NULL) + { + Check(dropzone); + if (!strnicmp(dropzone->GetDropZoneName(), "win", 3)) + { + continue; + } + range.Subtract( + localOrigin.linearPosition, + dropzone->localOrigin.linearPosition + ); + Scalar len = range.LengthSquared(); + if (len < closest_range) + { + closest_dropzone = dropzone; + closest_range = len; + } + } + message->dropZoneID = closest_dropzone->GetEntityID(); + dropzone = closest_dropzone; + } + + // + //---------------------------------------------- + // Otherwise, get this one from the host manager + //---------------------------------------------- + // + else + { + //DEBUG_STREAM << " Use Assigned" << endl << flush; + + HostManager *host = application->GetHostManager(); + Check(host); + dropzone = + Cast_Object( + DropZone*, + host->GetEntityPointer(message->dropZoneID) + ); + } + + Check(dropzone); + DropZone::AssignDropZoneMessage + request( + DropZone::AssignDropZoneMessageID, + sizeof(DropZone::AssignDropZoneMessage), + GetEntityID(), + DropZoneReplyMessageID, + deathCount + ); + dropzone->Dispatch(&request); + Time when = Now(); + when += 2.0f; + application->Post(HighEventPriority, this, message, when); + } + Check_Fpu(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Player::HuntForDropZone(Scalar) +{ + Check(this); + Check(playerMission); + + // + //---------------------------------------------------------------------- + // See if our designated drop zone is around yet. If the dropzone group + // does not exist, then no dropzones at all are available + //---------------------------------------------------------------------- + // + Check(application); + EntityManager *entity_manager = application->GetEntityManager(); + Check(entity_manager); + EntityGroup *dropzones = entity_manager->FindGroup("DropZones"); + if (!dropzones) + { + Check_Fpu(); + return; + } + + Check(dropzones); + ChainIteratorOf iterator(dropzones->groupMembers); + DropZone *dropzone; + const char* zone_name = playerMission->GetDropZoneName(); + while ((dropzone = (DropZone*)iterator.ReadAndNext()) != NULL) + { + if (!strcmp(dropzone->GetDropZoneName(), zone_name)) + { + break; + } + } + + // + //------------------------------------------------------------------------ + // If it is, reset our performance, and send a message to the drop zone to + // give us a location + //------------------------------------------------------------------------ + // + if (dropzone) + { + + //DEBUG_STREAM << "FOUND DROPZONE" << endl << flush; + + Check(dropzone); + SetPerformance(&Player::DoNothingOnce); + VehicleDeadMessage + dead( + VehicleDeadMessageID, + sizeof(VehicleDeadMessage), + dropzone->GetEntityID() + ); + dead.deathCount = -2; + + DropZone::AssignDropZoneMessage + request( + DropZone::AssignDropZoneMessageID, + sizeof(DropZone::AssignDropZoneMessage), + GetEntityID(), + DropZoneReplyMessageID, + deathCount + ); + dropzone->Dispatch(&request); + Time when = Now(); + when += 2.0f; + application->Post(HighEventPriority, this, &dead, when); + } + Check_Fpu(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Player::ManageApplicationStatus(Scalar time_slice) +{ + // + //-------------------------------------------------------------------------- + // If we are in the game start/stop phase, count the timer down and send the + // appropriate message to the application when done + //-------------------------------------------------------------------------- + // + Check(this); + Check(application); + switch (GetSimulationState()) + { + case MissionStartingState: + Verify(fadeTimeRemaining <= 3.0f); + fadeTimeRemaining -= time_slice; + if (fadeTimeRemaining <= 0.0f) + { + SetSimulationState(VehicleTranslocatedState); + Check(application); + switch (application->GetApplicationState()) + { + case Application::LaunchingMission: + { + Application::RunMissionMessage message; + application->Dispatch(&message); + } + break; + case Application::ResumingMission: + { + Application::ResumeMissionMessage message; + application->Dispatch(&message); + } + break; + } + } + break; + case MissionEndingState: + fadeTimeRemaining -= time_slice; + if (fadeTimeRemaining <= 0.0f) + { + Check(application); + switch (application->GetApplicationState()) + { + case Application::EndingMission: + { + // Fill in appropriate exit code here. GAH + Application::StopMissionMessage message(NullExitCodeID); + application->Dispatch(&message); + } + break; + case Application::AbortingMission: + { + // Fill in appropriate exit code here. GAH + Application::AbortMissionMessage message(NullExitCodeID); + application->Dispatch(&message); + } + break; + case Application::SuspendingMission: + { + Application::SuspendMissionMessage message; + application->Dispatch(&message); + } + break; + } + } + break; + } + Check_Fpu(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Player::CameraShipSimulation(Scalar time_slice) +{ + Check(this); + CalcRanking(); + + ManageApplicationStatus(time_slice); + Check_Fpu(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Player::PlayerSimulation(Scalar time_slice) +{ + Check(this); + + //------------------------------- + // Calculate the player's ranking + //------------------------------- + CalcRanking(); + + //---------------------------------- + // ...manage the application status? + //---------------------------------- + ManageApplicationStatus(time_slice); + + //------------------------------- + // Copy vehicle position + //------------------------------- + if (playerVehicle) + { + Check(playerVehicle); + localOrigin = playerVehicle->localOrigin; + localToWorld = playerVehicle->localToWorld; + } + + //--------------------------------- + // Service the status message queue + //--------------------------------- + StatusMessageUpdate(time_slice); + + Check_Fpu(); +} +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Player::GoToVehicle(Scalar) +{ + Check(this); + if (playerVehicle) + { + Check(playerVehicle); + localOrigin = playerVehicle->localOrigin; + localToWorld = playerVehicle->localToWorld; + } + Check_Fpu(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +int + Player::CalcRanking() +{ + + // + //--------------------------------------- + // Get all players from the entity group + //--------------------------------------- + // + EntityGroup *player_group = + application->GetEntityManager()->FindGroup("Players"); + if(player_group) + { + int num_players = 0; + Player *active_player; + // + //----------------------------------------------------- + // Iterate through the players add to the sorted chain + //----------------------------------------------------- + // + ChainIteratorOf iterator(player_group->groupMembers); + VChainOf player_rank(NULL, False); + while ((active_player = (Player*) iterator.ReadAndNext()) != NULL) + { + if(active_player->IsScoringPlayer()) + { + player_rank.AddValue(active_player, active_player->currentScore); + ++num_players; + // + //~~~~~~~~~~~~~~~~~~~~~~~~~ + // Reset Player Highlighted + //~~~~~~~~~~~~~~~~~~~~~~~~~ + // + active_player->playerHighlighted = False; + } + else + { + active_player->playerRanking = -1; + } + + } + --num_players; + // + //------------------------------------------------ + // Iterate through the chain assigning the rank + //------------------------------------------------ + // + VChainIteratorOf rank_iterator(player_rank); + + + while ((active_player = rank_iterator.ReadAndNext()) != NULL) + { + active_player->playerRanking = num_players; + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // If player in first place turn on player highlighted + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + if (!active_player->playerRanking) + { + active_player->playerHighlighted = True; + } + --num_players; + } + Check_Fpu(); + } + return 1; +} +//############################################################################# +// Update Support +// +void + Player::ReadUpdateRecord(Simulation::UpdateRecord *message) +{ + Check(this); + Check_Pointer(message); + Entity::ReadUpdateRecord(message); + UpdateRecord* record = (UpdateRecord*) message; + + currentScore = record->currentScore; + dropZoneLocation = record->dropZoneLocation; + Check_Fpu(); +} +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Player::WriteUpdateRecord( + Simulation::UpdateRecord *record, + int update_model + ) +{ + Check(this); + Check_Pointer(record); + + Entity::WriteUpdateRecord(record, update_model); + + UpdateRecord* update = (UpdateRecord*) record; + + update->recordLength = sizeof(*update); + update->currentScore = currentScore; + update->dropZoneLocation = dropZoneLocation; + Check_Fpu(); +} + + +//############################################################################# +// Construction and Destruction +// + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Player::Player( + Player::MakeMessage *creation_message, + Player::SharedData &virtual_data +): + Entity(creation_message, virtual_data), + statusMessageQueue(NULL) +{ + Check_Pointer(this); + Check_Pointer(creation_message); + + scenarioRole = NULL; + //--------------------------------- + // Initialize data + //--------------------------------- + statusMessagePointer = NULL; + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Initialize the playerMission + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + playerMission = application->GetCurrentMission(); + Check(playerMission); + // + //--------------------------------- + // Set the resource ID for a player + //--------------------------------- + // + Check(application); + Check(application->GetResourceFile()); + ResourceDescription *resource_description = + application->GetResourceFile()->FindResourceDescription( + "player", + ResourceDescription::ModelListResourceType + ); + if (resource_description != NULL) + { + Verify(resourceID == ResourceDescription::NullResourceID); + resourceID = resource_description->resourceID; + } + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Get the host type associated with the entity ID + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + HostType host_type; + + HostID host_ID = entityID.GetHostID(); + Check(application); + HostManager *host_mgr = application->GetHostManager(); + Check(host_mgr); + Host *local_host = host_mgr->GetLocalHost(); + Check(local_host); + if (host_ID == local_host->GetHostID()) + { + host_type = local_host->GetHostType(); + } + else + { + HostManager::RemoteHostIterator iterator(host_mgr); + local_host = iterator.Find(host_ID); + Check(local_host); + host_type = local_host->GetHostType(); + } + + if (IsCameraShipPlayer()) + { + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Make A CameraPlayers Entity Group + // since cameras are not involved in + // standard game play they need a + // separate Entity Group! + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + playerBitmapIndex = -1; + } + else + { + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Make A Regular Players Entity Group + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + Check(application); + EntityManager *entity_manager = application->GetEntityManager(); + Check(entity_manager); + EntityGroup *players = entity_manager->UseGroup("Players"); + Check(players); + players->Add(this); + playerBitmapIndex = creation_message->playerBitmapIndex; + } + + SetValidFlag(); + playerVehicle = NULL; + if (GetInstance() != ReplicantInstance) + { + Check(application->GetCurrentMission()); + playerMission = application->GetCurrentMission(); + SetPerformance(&Player::HuntForDropZone); + } + else + { + SetPerformance(&Player::GoToVehicle); + playerMission = NULL; + } + + playerRanking = 0; + deathCount = -2; + + //------------------------------------- + // Clear score + //------------------------------------- + currentScore = 0.0f; + //------------------------------------- + // Create intercom object + //------------------------------------- + Check(application); + IcomManager + *intercom_manager = application->GetIntercomManager(); + Check(intercom_manager); + + intercomPointer = intercom_manager->MakeIcom(GetOwnerID()); + Check(intercomPointer); + // registered in MakeIcom() + + playerHighlighted = False; + fadeTimeRemaining = 0.0f; + Check_Fpu(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Player* Player::Make(Player::MakeMessage *creation_message) +{ + Check_Fpu(); + return new Player(creation_message, DefaultData); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Player::~Player() +{ + Check(this); + + //-------------------------------------------- + // Delete intercom object + //-------------------------------------------- + Check(intercomPointer); + Unregister_Object(intercomPointer); + delete intercomPointer; + intercomPointer = NULL; + + Check_Fpu(); +} + + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Player::AddStatusMessage(StatusMessage *status_message) +{ + Check(this); + Check_Pointer(status_message); + statusMessageQueue.Add(status_message); + Check_Fpu(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Player::StatusMessageUpdate(Scalar time_slice) +{ + Check(this); + //------------------------------------- + // We handle this queue as a STACK. + // The most recent message is presented + // first, causing older messages to + // wait "below" them on the stack. + // This allows a default message to + // sit at the "bottom" of the stack + // and allow others to override it + // temporarily. + //------------------------------------- + // + ChainIteratorOf + iterator(statusMessageQueue); + //---------------------------------------- + // ...we really want iterator.GetLast(), + // but since it doesn't exist we'll + // do it directly. + //---------------------------------------- + statusMessagePointer = NULL; + { + StatusMessage + *the_message; + + while ((the_message = iterator.ReadAndNext()) != NULL) + { + statusMessagePointer = the_message; + } + } + //---------------------------------------- + // If a message exists, decrement the + // timer: discard it if timed out. + //---------------------------------------- + if (statusMessagePointer != NULL) + { + Check_Pointer(statusMessagePointer); + + statusMessagePointer->displayTime -= time_slice; + if (statusMessagePointer->displayTime <= (Scalar) 0.0f) + { + Unregister_Object(statusMessagePointer); + delete statusMessagePointer; + statusMessagePointer = NULL; + } + } + Check_Fpu(); +} + +Logical + Player::TestInstance() const +{ + return IsDerivedFrom(ClassDerivations); +} diff --git a/restoration/source410/MUNGA/RANDOM.CPP b/restoration/source410/MUNGA/RANDOM.CPP new file mode 100644 index 00000000..f55b1d11 --- /dev/null +++ b/restoration/source410/MUNGA/RANDOM.CPP @@ -0,0 +1,180 @@ +# if !defined(MUNGA_HPP) +# include +# endif +#pragma hdrstop + +# if !defined(RANDOM_HPP) +# include +# endif + +int RandomGenerator::Numbers[250]; +int RandomGenerator::Index = -1; + +RandomGenerator Random; + +// +//########################################################################### +//########################################################################### +// +void RandomGenerator::Init() +{ + int i, msb, mask; + + // + //-------------------------------------------------------------------- + // After making sure the table is built only once, initialize the + // Borland C++ random numbers with the low word of the current time in + // milliseconds, and initialize the index pointer + //-------------------------------------------------------------------- + // + char *seed_spec = getenv("RANDOM"); + unsigned seed; + if (seed_spec) + { + seed = (unsigned)atol(seed_spec); + } + else + { + seed = (unsigned)time(NULL); + } + #if defined(TEST_CLASS) + cout << "Random Seed = " << seed << endl; + #endif + srand(seed); + Index = 0; + + // + //------------------------------------------------------------------ + // Load the random number buffer, then go thru and set the sign bit + // randomly, increasing the range of random numbers from 0..32767 to + // 0..65535 + //------------------------------------------------------------------ + // + for (i=0; i<250; i++) + { + Numbers[i] = rand(); + } + + // + //-------------------------------------------------------------------- + // In order to preserve a good random number mix for the XOR function, + // mask and set the bits of 16 words in a descending manner as in + // 1xx..., 01xx..., 001xx..., 0001xx..., ... + //-------------------------------------------------------------------- + // + mask = RAND_MAX >> 1; + msb = mask + 1; + int rand_size; + for (rand_size=0; !(msb&(1<>= 1; + msb >>= 1; + i += 11; + } +} + +// +//########################################################################### +//########################################################################### +// +int RandomGenerator::GetRandomInt() +{ + int indent, result; + + // + //------------------------------------------------------------------ + // The random number generated will be the result of an XOR with the + // element 103 positions further (wrapping around) in the table + //------------------------------------------------------------------ + // + indent = (Index>=147)?Index-147:Index+103; + result = Numbers[Index]^Numbers[indent]; + + // + //------------------------------------------------------------------------ + // Replace the current random number with the new one generated, increment + // the buffer index pointer, and return the number + //------------------------------------------------------------------------ + // + Numbers[Index] = result; + if (++Index == ELEMENTS(Numbers)) + Index=0; + return result; +} + +// +//########################################################################### +//########################################################################### +// +RandomGenerator::operator Scalar() +{ + Scalar result; + + result = GetRandomInt(); + result /= (float)(RAND_MAX + 1); + return result; +} + +// +//########################################################################### +//########################################################################### +// +int RandomGenerator::operator ()(int range) +{ + int result, max; + + max = RAND_MAX - ((RAND_MAX + 1)%range); + do + { + result = GetRandomInt(); + } while (result>max); + return result%range; +} + +// +//########################################################################### +//########################################################################### +// +Die::Die(int n) +{ + dieSides = (n>1)?n:2; + highestRandom = RAND_MAX - ((RAND_MAX+1)%dieSides); +} + +// +//########################################################################### +//########################################################################### +// +Die::operator int() +{ + int result; + + // + //------------------------------------------------------------------------ + // In order to not skew the probabilities to the low numbers, make sure + // that the random # used is not greater than the limit determined for the + // number of sides. + //------------------------------------------------------------------------ + // + do + { + result = Random.GetInt(); + } while (result>highestRandom); + + // + //------------------------------------------------------------------- + // Once the base random number is determined, do modulus division and + // increment by 1 to map into the die range. + //------------------------------------------------------------------- + // + return result % dieSides + 1; +} + +#if defined(TEST_CLASS) + #include "random.tcp" +#endif diff --git a/restoration/source410/MUNGA/RECEIVER.CPP b/restoration/source410/MUNGA/RECEIVER.CPP new file mode 100644 index 00000000..69c6e769 --- /dev/null +++ b/restoration/source410/MUNGA/RECEIVER.CPP @@ -0,0 +1,641 @@ +# if !defined(MUNGA_HPP) +# include +# endif +#pragma hdrstop + +# if !defined(RECEIVER_HPP) +# include +# endif +# if !defined(EVENT_HPP) +# include +# endif + +//############################################################################# +//############################# Receiver ################################ +//############################################################################# + +const Receiver::Handler + Receiver::NullHandler=NULL; + +Receiver::SharedData + Receiver::DefaultData( + Receiver::ClassDerivations, + Receiver::MessageHandlers + ); + +Derivation + Receiver::ClassDerivations("Receiver"); + +const Receiver::HandlerEntry + Receiver::MessageHandlerEntries[]= +{ + { + Receiver::WatcherChangedMessageID, + "WatcherChanged", + (Receiver::Handler)&Receiver::DefaultMessageHandler + }, + { + Receiver::LoadResourceFinishedMessageID, + "LoadResourceFinished", + (Receiver::Handler)&Receiver::DefaultMessageHandler + } +}; + +Receiver::MessageHandlerSet + Receiver::MessageHandlers(ELEMENTS(Receiver::MessageHandlerEntries), Receiver::MessageHandlerEntries); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +#if defined(USE_SIGNATURE) + int + Is_Signature_Bad(const volatile Receiver__Message *) + { + return False; + } +#endif + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void +#if DEBUG_LEVEL>0 + Receiver::DefaultMessageHandler(Message* message) +#else + Receiver::DefaultMessageHandler(Message*) +#endif +{ + Tell( + "Default Handler activated on message ID " << message->messageID << endl + ); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Receiver::Receive(Message *what) +{ + // + //------------------------------------------------------------------------- + // Service the message taps by creating an iterator to step through all the + // MessageTaps registered with the Derivation object for the receiver's + // class. Each tap will do whatever it thinks best about this receiver + // having received this message + //------------------------------------------------------------------------- + // + Check(this); + Check_Pointer(what); + ChainIteratorOf i(GetDerivation()->activeTaps); + MessageTap *tap; + while ((tap = i.ReadAndNext()) != NULL) + { + tap->Scan(this,what); + } + + // + //-------------------------------------------------------------------------- + // Now, see if the receiver can handle this type of message, and if so, send + // the message to the returned method handler + //-------------------------------------------------------------------------- + // + Receiver::SharedData *sharedData = GetSharedData(); + Handler handler = sharedData->activeMessageHandlers->Find(what->messageID); + if (handler != Receiver::NullHandler) + { + (this->*handler)(what); + } +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Receiver::Receive(Event *event) +{ + Receive(event->messageToSend); + Unregister_Object(event); + delete event; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Receiver::FlushEvents(int) // max_priority doesn't work yet!!!! +{ + Check(this); + PlugIteratorOf i(this); + Event *event; + while ((event = i.ReadAndNext()) != NULL) + { + if (event->GetClassID() == EventClassID) + { + Unregister_Object(event); + delete event; + } + } +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Receiver::FlushMatchingEvents( + Receiver::MessageID target_message, + int // max_priority doesn't work yet!!!! + ) +{ + Check(this); + PlugIteratorOf + i(this); + Event* event; + while ((event = i.ReadAndNext()) != NULL) + { + if ( + event->GetClassID() == EventClassID && ( + target_message == Receiver::AnyMessageID + || event->messageToSend->messageID == target_message + ) + ) + { + Unregister_Object(event); + delete event; + } + } +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Receiver::ProcessDeferredQueue() +{ + // + //------------------------------------------------ + // Find a delay queue, and return if there is none + //------------------------------------------------ + // + Check(this); + PlugIteratorOf i(this); + DeferredEventQueue *deferred_queue; + while ((deferred_queue = i.ReadAndNext()) != NULL) + { + if (deferred_queue->GetClassID() == DeferredEventQueueClassID) + { + break; + } + } + if (!deferred_queue) + { + return; + } + + // + //-------------------------------------------------------------- + // Now, tell the queue to process all its events, then delete it + //-------------------------------------------------------------- + // + deferred_queue->ProcessAllEvents(); + Unregister_Object(deferred_queue); + delete deferred_queue; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + Receiver::TestInstance() const +{ + return IsDerivedFrom(ClassDerivations); +} + +//############################################################################# +//######################### Receiver::Message ########################### +//############################################################################# + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + Receiver::Message::TestInstance() const +{ + return True; +} + +//############################################################################# +//######################### Receiver::DynamicMessage ########################## +//############################################################################# + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Receiver__DynamicMessage::Receiver__DynamicMessage( + Receiver::MessageID message_ID, + size_t message_size +) +{ + Receiver::Message new_message(message_ID, message_size); + WriteBytes(&new_message, message_size); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +MemoryStream& + Receiver::DynamicMessage::WriteBytes( + const void *ptr, + size_t number_of_bytes + ) +{ + DynamicMemoryStream::WriteBytes(ptr, number_of_bytes); + + Receiver::Message *message = GetMessagePointer(); + size_t new_size = GetBytesUsed(); + message->messageLength = new_size; + return *this; +} + +//############################################################################# +//############################ MessageTap ############################### +//############################################################################# + +MemoryBlock + MessageTap::AllocatedMemory(sizeof(MessageTap), 30, 30, "Message Taps"); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +MessageTap::MessageTap( + Derivation *derivation, + Receiver *client, + Receiver::ScanCallback call_back +): + Plug(MessageTapClassID) +{ + // + //--------------------------- + // Initialize the message tap + //--------------------------- + // + Check(client); + clientReceiver = client; + scanCallback = call_back; + matchingReceiver = NULL; + matchingMessageID = Receiver::AnyMessageID; + + // + //-------------------------------------------- + // Hook the tap up to the specified derivation + //-------------------------------------------- + // + Check(derivation); + derivation->AppendMessageTap(this); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +MessageTap::MessageTap( + Derivation *derivation, + Receiver *client, + Receiver::ScanCallback call_back, + Receiver::MessageID messageID, + Receiver *receiver +): + Plug(MessageTapClassID) +{ + // + //--------------------------- + // Initialize the message tap + //--------------------------- + // + Check(client); + clientReceiver = client; + scanCallback = call_back; + + matchingReceiver = receiver; + matchingMessageID = messageID; + + // + //-------------------------------------------- + // Hook the tap up to the specified derivation + //-------------------------------------------- + // + Check(derivation); + derivation->AppendMessageTap(this); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + MessageTap::Scan( + Receiver *receiver, + Receiver::Message *message + ) +{ + Check(this); + Check(message); + + if ( + (!matchingReceiver || matchingReceiver == receiver) + && ( + matchingMessageID == Receiver::AnyMessageID + || matchingMessageID == message->messageID + ) + ) + { + (clientReceiver->*scanCallback)(message,receiver); + } +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + MessageTap::TestInstance() const +{ + return True; +} + +//############################################################################# +//##################### Receiver::InheritanceSet ######################## +//############################################################################# + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + Receiver::InheritanceSet::TestInstance() const +{ + return True; +} + +//############################################################################# +//#################### Receiver::MessageHandlerSet ###################### +//############################################################################# + +const Receiver::MessageHandlerSet + Receiver::MessageHandlerSet::NullSet; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Receiver__MessageHandlerSet::~Receiver__MessageHandlerSet() +{ + if (messageHandlers) + { + Unregister_Pointer(messageHandlers); + delete[] messageHandlers; + messageHandlers = NULL; + } +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Receiver::MessageHandlerSet::Build( + Receiver::MessageID count, + const Receiver::HandlerEntry handler_table[], + const Receiver::MessageHandlerSet *inheritance + ) +{ + // + //------------------------------------------------------- + // Find out the highest message type we have to deal with + //------------------------------------------------------- + // + Check(this); + Check_Pointer(handler_table); + entryCount = 0; + Receiver::MessageID i; + for (i=0; i entryCount) + { + entryCount = handler_table[i].entryID; + } + } + if (inheritance) + { + Check(inheritance); + if (entryCount < inheritance->entryCount) + { + entryCount = inheritance->entryCount; + } + #if DEBUG_LEVEL>0 + else if (entryCount > inheritance->entryCount) + { + i = inheritance->entryCount+1; + goto Check_Table; + } + #endif + } + else + { + Verify(entryCount == count); + #if DEBUG_LEVEL>0 + i = 1; +Check_Table: + while (i <= entryCount) + { + int j; + for (j=0; j count); + #endif + } + + // + //----------------------------------------------------------------------- + // Allocate the memory for the new handler set, and copy the inherited + // handlers to the new table. We are guaranteed to have enough space for + // the inherited table + //----------------------------------------------------------------------- + // + messageHandlers = new Receiver::HandlerEntry[entryCount]; + Check_Pointer(messageHandlers); + Register_Pointer(messageHandlers); + i = 0; + if (inheritance) + { + for (; ientryCount; ++i) + { + messageHandlers[i] = inheritance->messageHandlers[i]; + } + } + + // + //---------------------------------------------------------------------- + // Step through the new table supplied, placing each handler in the slot + // determined by the message type + //---------------------------------------------------------------------- + // + for (i=0; i= 0 && index < entryCount); + messageHandlers[index] = handler_table[i]; + } +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +const Receiver::HandlerEntry* + Receiver::MessageHandlerSet::Find(const char* name) const +{ + Check(this); + Check_Pointer(name); + + for (int i=0; i + i(classDerivations); + Derivation *derivation; + while ((derivation = i.ReadAndNext()) != NULL) + { + derivation->AppendMessageTap(tap); + } +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + Derivation::IsDescendedFrom(Derivation& parent) +{ + Check(this); + Check(&parent); + + // + //------------------------------ + // We are descended from ourself + //------------------------------ + // + if (&parent == this) + { + return True; + } + + // + //---------------------------------------------------------------------- + // Find our parent derivation, and ask him + // sending each of them this same method + //---------------------------------------------------------------------- + // + PlugIteratorOf i(this); + Derivation *derivation; + while ((derivation = i.ReadAndNext()) != NULL) + { + if (derivation->GetClassID() == DerivationClassID) + { + return derivation->IsDescendedFrom(parent); + } + } + return False; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + Derivation::IsDescendedFrom(const char* parent) +{ + Check(this); + Check_Pointer(parent); + + // + //------------------------------ + // We are descended from ourself + //------------------------------ + // + Check_Pointer(className); + if (!strcmp(className, parent)) + { + return True; + } + + // + //---------------------------------------------------------------------- + // Find our parent derivation, and ask him + // sending each of them this same method + //---------------------------------------------------------------------- + // + PlugIteratorOf i(this); + Derivation *derivation; + while ((derivation = i.ReadAndNext()) != NULL) + { + Check(derivation); + if (derivation->GetClassID() == DerivationClassID) + { + return derivation->IsDescendedFrom(parent); + } + } + return False; +} + +//############################################################################# +//###################### Receiver::SharedData ########################## +//############################################################################# + +Logical + Receiver::SharedData::TestInstance() const +{ + return True; +} + +#if defined(TEST_CLASS) +# include "receiver.tcp" +#endif diff --git a/restoration/source410/MUNGA/ROTATION.CPP b/restoration/source410/MUNGA/ROTATION.CPP new file mode 100644 index 00000000..c7e37f89 --- /dev/null +++ b/restoration/source410/MUNGA/ROTATION.CPP @@ -0,0 +1,1344 @@ +# if !defined(MUNGA_HPP) +# include +# endif +#pragma hdrstop + +# if !defined(ROTATION_HPP) +# include +# endif +# if !defined(LINMTRX_HPP) +# include +# endif + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + Close_Enough( + const Hinge &a1, + const Hinge &a2, + Scalar e + ) +{ + return a1.axisNumber == a2.axisNumber + && Close_Enough(a1.rotationAmount, a2.rotationAmount, e); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Hinge& + Hinge::Lerp( + const Hinge& v1, + const Hinge& v2, + Scalar t + ) +{ + Check_Pointer(this); + Check(&v1); + Check(&v2); + Verify(v1.axisNumber == v2.axisNumber); + + axisNumber = v1.axisNumber; + rotationAmount.Lerp(v1.rotationAmount, v2.rotationAmount, t); + return *this; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +ostream& operator<<(ostream& stream, const Hinge& angles) +{ + Check(&angles); + stream << angles.rotationAmount << " about "; + switch (angles.axisNumber) + { + case X_Axis: + stream << "X Axis"; + break; + case Y_Axis: + stream << "Y Axis"; + break; + case Z_Axis: + stream << "Z Axis"; + break; + } + return stream; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + Hinge::TestInstance() const +{ + return (unsigned)axisNumber <= Z_Axis; +} + +#if defined(USE_SIGNATURE) + int + Is_Signature_Bad(const volatile Hinge *) + { + return False; + } +#endif + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EulerAngles ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +const EulerAngles + EulerAngles::Identity(0.0f,0.0f,0.0f); + +#if defined(USE_SIGNATURE) + int + Is_Signature_Bad(const volatile EulerAngles *) + { + return False; + } +#endif + +// +//############################################################################# +//############################################################################# +// +EulerAngles& + EulerAngles::operator=(const EulerAngles &angles) +{ + Check_Pointer(this); + Check(&angles); + + pitch = angles.pitch; + yaw = angles.yaw; + roll = angles.roll; + return *this; +} + +// +//############################################################################# +//############################################################################# +// +EulerAngles& + EulerAngles::operator=(const YawPitchRoll &angles) +{ + Check_Pointer(this); + Check(&angles); + + LinearMatrix m; + m = angles; + *this = m; + + return *this; +} + +// +//############################################################################# +//############################################################################# +// +EulerAngles& + EulerAngles::operator=(const Hinge &hinge) +{ + Check_Pointer(this); + Check(&hinge); + + pitch = 0.0f; + yaw = 0.0f; + roll = 0.0f; + + switch (hinge.axisNumber) + { + case X_Axis: + pitch = hinge.rotationAmount; + break; + case Y_Axis: + yaw = hinge.rotationAmount; + break; + case Z_Axis: + roll = hinge.rotationAmount; + break; + } + return *this; +} + +// +//############################################################################# +//############################################################################# +// +EulerAngles& + EulerAngles::operator=(const Quaternion &quaternion) +{ + Check_Pointer(this); + Check(&quaternion); + + LinearMatrix m; + m = quaternion; + return *this = m; +} + +// +//############################################################################# +//############################################################################# +// +EulerAngles& + EulerAngles::operator=(const LinearMatrix &matrix) +{ + Check_Pointer(this); + Check(&matrix); + + SinCosPair + p,y,r; + + y.sine = -matrix(0,2); + if (Close_Enough(y.sine,1.0f,0.0001f)) { + y.cosine = 0.0f; + r.sine = 0.0f; + r.cosine = 1.0f; + p.sine = matrix(1,0); + p.cosine = matrix(2,0); + } + else if (Close_Enough(y.sine,-1.0f,0.0001f)) { + y.cosine = 0.0f; + r.sine = 0.0f; + r.cosine = 1.0f; + p.sine = -matrix(1,0); + p.cosine = -matrix(2,0); + } + else { + y.cosine = Sqrt(1.0f - y.sine*y.sine); + p.sine = matrix(1,2) / y.cosine; + p.cosine = matrix(2,2) / y.cosine; + r.sine = matrix(0,1) / y.cosine; + r.cosine = matrix(0,0) / y.cosine; + + if ( + !Close_Enough(p.sine*y.sine*r.cosine - p.cosine*r.sine,matrix(1,0)) + ) { + y.sine = -y.sine; + p.sine = -p.sine; + p.cosine = -p.cosine; + r.sine = -r.sine; + r.cosine = -r.cosine; + } + } + + pitch = p; + yaw = y; + roll = r; + return *this; +} + +// +//############################################################################# +//############################################################################# +// +Logical + Small_Enough( + const EulerAngles& angles, + Scalar e + ) +{ + Check(&angles); + + return + Small_Enough(angles.pitch,e) + && Small_Enough(angles.yaw,e) + && Small_Enough(angles.roll,e); +} + +// +//############################################################################# +//############################################################################# +// +Logical + Close_Enough( + const EulerAngles& a1, + const EulerAngles& a2, + Scalar e + ) +{ + Check(&a1); + Check(&a2); + + return + Close_Enough(a1.pitch,a2.pitch,e) + && Close_Enough(a1.yaw,a2.yaw,e) + && Close_Enough(a1.roll,a2.roll,e); +} + +// +//############################################################################# +//############################################################################# +// +EulerAngles& + EulerAngles::Multiply( + const EulerAngles &q1, + const EulerAngles &q2 + ) +{ + Check_Pointer(this); + Check(&q1); + Check(&q2); + + pitch = q1.pitch + q2.pitch; + yaw = q1.yaw + q2.yaw; + roll = q1.roll + q2.roll; + + #if DEBUG_LEVEL>0 + if (!TestInstance()) + { + Dump(q1); + Dump(q2); + Dump(*this); + Fail("EulerAngle multiplication is unstable!\n"); + } + #endif + return *this; +} + +// +//############################################################################# +//############################################################################# +// +EulerAngles& + EulerAngles::Multiply( + const EulerAngles &q, + Scalar t + ) +{ + Check_Pointer(this); + Check(&q); + + pitch = q.pitch * t; + yaw = q.yaw * t; + roll = q.roll * t; + return *this; +} + +// +//############################################################################# +//############################################################################# +// +EulerAngles& + EulerAngles::MultiplyScaled( + const EulerAngles &q1, + const EulerAngles &q2, + Scalar t + ) +{ + Check_Pointer(this); + Check(&q1); + Check(&q2); + Verify(t>=0.0f); + + pitch = q1.pitch + q2.pitch * t; + yaw = q1.yaw + q2.yaw * t; + roll = q1.roll + q2.roll * t; + return *this; +} + +// +//############################################################################# +//############################################################################# +// +EulerAngles& + EulerAngles::Lerp( + const EulerAngles &a1, + const EulerAngles &a2, + Scalar t + ) +{ + Check_Pointer(this); + Check(&a1); + Check(&a2); + + pitch = ::Lerp(a1.pitch,a2.pitch,t); + yaw = ::Lerp(a1.yaw,a2.yaw,t); + roll = ::Lerp(a1.roll,a2.roll,t); + return *this; +} + +// +//############################################################################# +//############################################################################# +// +EulerAngles& + EulerAngles::Normalize() +{ + Check_Pointer(this); + + pitch.Normalize(); + yaw.Normalize(); + roll.Normalize(); + return *this; +} + +// +//############################################################################# +//############################################################################# +// +ostream& operator<<(ostream& stream, const EulerAngles& angles) +{ + return stream << '<' << angles.pitch << ',' << angles.yaw << ',' << angles.roll << '>'; +} + +// +//############################################################################# +//############################################################################# +// +Logical + EulerAngles::TestInstance() const +{ + return True; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ YawPitchRoll ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +const YawPitchRoll + YawPitchRoll::Identity(0.0f,0.0f,0.0f); + +#if defined(USE_SIGNATURE) + int + Is_Signature_Bad(const volatile YawPitchRoll *) + { + return False; + } +#endif + +// +//############################################################################# +//############################################################################# +// +YawPitchRoll& + YawPitchRoll::operator=(const YawPitchRoll &angles) +{ + Check_Pointer(this); + Check(&angles); + + pitch = angles.pitch; + yaw = angles.yaw; + roll = angles.roll; + return *this; +} + +// +//############################################################################# +//############################################################################# +// +YawPitchRoll& + YawPitchRoll::operator=(const EulerAngles &angles) +{ + Check_Pointer(this); + Check(&angles); + + LinearMatrix m; + m = angles; + *this = m; + + return *this; +} + +// +//############################################################################# +//############################################################################# +// +YawPitchRoll& + YawPitchRoll::operator=(const Hinge &hinge) +{ + Check_Pointer(this); + Check(&hinge); + + pitch = 0.0f; + yaw = 0.0f; + roll = 0.0f; + + switch (hinge.axisNumber) + { + case X_Axis: + pitch = hinge.rotationAmount; + break; + case Y_Axis: + yaw = hinge.rotationAmount; + break; + case Z_Axis: + roll = hinge.rotationAmount; + break; + } + return *this; +} + +// +//############################################################################# +//############################################################################# +// +YawPitchRoll& + YawPitchRoll::operator=(const Quaternion &quaternion) +{ + Check_Pointer(this); + Check(&quaternion); + + LinearMatrix m; + m = quaternion; + return *this = m; +} + +// +//############################################################################# +//############################################################################# +// +YawPitchRoll& + YawPitchRoll::operator=(const LinearMatrix &matrix) +{ + Check_Pointer(this); + Check(&matrix); + + SinCosPair + x,y,z; + + x.sine = -matrix(2,1); + if (Close_Enough(x.sine,1.0f,0.0001f)) { + x.cosine = 0.0f; + z.sine = 0.0f; + z.cosine = 1.0f; + y.sine = matrix(1,0); + y.cosine = matrix(0,0); + } + else if (Close_Enough(x.sine,-1.0f,0.0001f)) { + x.cosine = 0.0f; + z.sine = 0.0f; + z.cosine = 1.0f; + y.sine = matrix(0,2); + y.cosine = matrix(0,0); + } + else { + x.cosine = Sqrt(1.0f - x.sine*x.sine); + y.sine = matrix(2,0) / x.cosine; + y.cosine = matrix(2,2) / x.cosine; + z.sine = matrix(0,1) / x.cosine; + z.cosine = matrix(1,1) / x.cosine; + + if ( + !Close_Enough(y.cosine*z.cosine + x.sine*y.sine*z.sine,matrix(0,0)) + ) + { + x.sine = -x.sine; + y.sine = -y.sine; + y.cosine = -y.cosine; + z.sine = -z.sine; + z.cosine = -z.cosine; + } + } + + pitch = x; + yaw = y; + roll = z; + return *this; +} + +// +//############################################################################# +//############################################################################# +// +Logical + Small_Enough( + const YawPitchRoll& angles, + Scalar e + ) +{ + Check(&angles); + + return + Small_Enough(angles.pitch,e) + && Small_Enough(angles.yaw,e) + && Small_Enough(angles.roll,e); +} + +// +//############################################################################# +//############################################################################# +// +Logical + Close_Enough( + const YawPitchRoll& a1, + const YawPitchRoll& a2, + Scalar e + ) +{ + Check(&a1); + Check(&a2); + + return + Close_Enough(a1.pitch,a2.pitch,e) + && Close_Enough(a1.yaw,a2.yaw,e) + && Close_Enough(a1.roll,a2.roll,e); +} + +// +//############################################################################# +//############################################################################# +// +YawPitchRoll& + YawPitchRoll::Normalize() +{ + Check_Pointer(this); + + pitch.Normalize(); + yaw.Normalize(); + roll.Normalize(); + return *this; +} + +// +//############################################################################# +//############################################################################# +// +ostream& operator<<(ostream& stream, const YawPitchRoll& angles) +{ + return stream << '<' << angles.yaw << ',' << angles.pitch << ',' << angles.roll << '>'; +} + +// +//############################################################################# +//############################################################################# +// +Logical + YawPitchRoll::TestInstance() const +{ + return True; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Quaternion ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +const Quaternion + Quaternion::Identity(0.0f, 0.0f, 0.0f, 1.0f); + +#if defined(USE_SIGNATURE) + int + Is_Signature_Bad(const volatile Quaternion *) + { + return False; + } +#endif + +// +//############################################################################# +//############################################################################# +// +Quaternion::Quaternion( + Scalar x, + Scalar y, + Scalar z, + Scalar w +) +{ + this->x = x; + this->y = y; + this->z = z; + this->w = w; +} + +// +//############################################################################# +//############################################################################# +// +Quaternion& + Quaternion::operator=(const Quaternion &q) +{ + Check_Pointer(this); + Check(&q); + + x = q.x; + y = q.y; + z = q.z; + w = q.w; + return *this; +} + +// +//############################################################################# +//############################################################################# +// +Quaternion& + Quaternion::operator=(const Hinge &hinge) +{ + Check_Pointer(this); + Check(&hinge); + + Radian temp; + temp = hinge.rotationAmount * 0.5f; + SinCosPair half_angle; + half_angle = temp; + + w = half_angle.cosine; + x = 0.0f; + y = 0.0f; + z = 0.0f; + + switch (hinge.axisNumber) + { + case X_Axis: + x = half_angle.sine; + break; + case Y_Axis: + y = half_angle.sine; + break; + case Z_Axis: + z = half_angle.sine; + break; + } + return *this; +} + +// +//############################################################################# +//############################################################################# +// +Quaternion& + Quaternion::operator=(const EulerAngles &angles) +{ + Check_Pointer(this); + Check(&angles); + + LinearMatrix m; + m = angles; + Check(&m); + *this = m; + #if DEBUG_LEVEL>0 + if (!TestInstance()) + { + Dump(angles); + Dump(*this); + Fail("Quaternion construction from angles is unstable!\n"); + } + #endif + return *this; +} +// +//############################################################################# +//############################################################################# +// +Quaternion& + Quaternion::operator=(const YawPitchRoll &angles) +{ + LinearMatrix lin_matrix; + lin_matrix = angles; + *this = lin_matrix; + return *this; +} +// +//############################################################################# +//############################################################################# +// +Quaternion& + Quaternion::operator=(const LinearMatrix &matrix) +{ + Check_Pointer(this); + Check(&matrix); + + // + //------------------------------------------------------------------------ + // Compute the w component. If it is close enough to zero, then we have a + // 180 degree pivot, so figure out the correct axis to rotate around + //------------------------------------------------------------------------ + // + w = (1.0f + matrix(0,0) + matrix(1,1) + matrix(2,2)) * 0.25f; + if (Small_Enough(w,1e-2)) + { + Verify(w >= -SMALL); + if (w<0.0f) + { + w = 0.0f; + } + + // + //---------------------------------------------------------------- + // Figure out the length of each component of the axis of rotation + //---------------------------------------------------------------- + // + Scalar temp = (1.0f + matrix(0,0)) * 0.5f - w; + Min_Clamp(temp, 0.0f); + x = Sqrt(temp); + temp = (1.0f + matrix(1,1)) * 0.5f - w; + Min_Clamp(temp, 0.0f); + y = Sqrt(temp); + temp = (1.0f + matrix(2,2)) * 0.5f - w; + Min_Clamp(temp, 0.0f); + z = Sqrt(temp); + w = Sqrt(w); + + // + //------------------------------------------- + // Now figure out the signs of the components + //------------------------------------------- + // + if (matrix(0,1) < matrix(1,0)) + { + z = -z; + } + if (matrix(2,0) < matrix(0,2)) + { + y = -y; + } + if (matrix(1,2) < matrix(2,1)) + { + x = -x; + } + } + + // + //---------------------------------------------------------- + // Otherwise, determine x, y, and z directly from the matrix + //---------------------------------------------------------- + // + else + { + Verify(w>0.0f); + w = Sqrt(w); + x = (matrix(1,2) - matrix(2,1)) * 0.25f / w; + y = (matrix(2,0) - matrix(0,2)) * 0.25f / w; + z = (matrix(0,1) - matrix(1,0)) * 0.25f / w; + } + + #if DEBUG_LEVEL>0 + if (!TestInstance()) + { + Dump(matrix); + Dump(*this); + Fail("Quaternion construction from matrix is unstable!\n"); + } + #endif + return *this; +} + + +// +//############################################################################# +//############################################################################# +// +Scalar + Quaternion::GetAngle() +{ + Check(this); + + Scalar sine_of_half = Sqrt(x*x + y*y + z*z); + if (Small_Enough(sine_of_half)) + { + return 0.0f; + } + + SinCosPair half_angle(sine_of_half, w); + Radian angle; + angle = half_angle; + + return angle * 2.0f; +} + +// +//############################################################################# +//############################################################################# +// +void + Quaternion::GetAxis(UnitVector *axis) +{ + Check(this); + Check_Pointer(axis); + + Scalar len = Sqrt(x*x + y*y + z*z); + if (Small_Enough(len)) + { + axis->x = 1.0f; + axis->y = 0.0f; + axis->z = 0.0f; + } + else + { + axis->x = x / len; + axis->y = y / len; + axis->z = z / len; + } + + Check(axis); + return; +} + +// +//############################################################################# +//############################################################################# +// +Quaternion& + Quaternion::Multiply(const Quaternion &q1, const Quaternion &q2) +{ + Check_Pointer(this); + Check(&q1); + Check(&q2); + Verify(this != &q1 && this != &q2); + + x = q1.w*q2.x + q2.w*q1.x + q1.y*q2.z - q1.z*q2.y; + y = q1.w*q2.y + q2.w*q1.y + q1.z*q2.x - q1.x*q2.z; + z = q1.w*q2.z + q2.w*q1.z + q1.x*q2.y - q1.y*q2.x; + w = q1.w*q2.w - q1.x*q2.x - q1.y*q2.y - q1.z*q2.z; + #if DEBUG_LEVEL>0 + if (!TestInstance()) + { + Dump(q1); + Dump(q2); + Dump(*this); + Fail("Quaternion multiplication is unstable!\n"); + } + #endif + return *this; +} + +// +//############################################################################# +//############################################################################# +// +Quaternion& + Quaternion::Multiply( + const Quaternion &q, + Scalar t + ) +{ + Check_Pointer(this); + Check(&q); + + // + //--------------------------------------------------------- + // Figure out the half the angle of rotation and scale that + //--------------------------------------------------------- + // + Scalar sine_of_half = Sqrt(q.x*q.x + q.y*q.y + q.z*q.z); + if (Small_Enough(sine_of_half)) + { + *this = Identity; + return *this; + } + + SinCosPair half_angle(sine_of_half, q.w); + Radian angle; + angle = half_angle; + angle *= t; + half_angle = angle; + + // + //----------------------------------------------------------------- + // Build the scaled quaternion out of the components of the old one + //----------------------------------------------------------------- + // + w = half_angle.cosine; + sine_of_half = half_angle.sine / sine_of_half; + x = q.x * sine_of_half; + y = q.y * sine_of_half; + z = q.z * sine_of_half; + + #if DEBUG_LEVEL>0 + if (!TestInstance()) + { + Dump(q); + Dump(t); + Dump(*this); + Fail("Quaternion multiplication is unstable!\n"); + } + #endif + return *this; +} + +// +//############################################################################# +//############################################################################# +// +Quaternion& + Quaternion::MultiplyScaled( + const Quaternion &q1, + const Quaternion &q2, + Scalar t + ) +{ + Check_Pointer(this); + Verify(this != &q1); + Check(&q1); + Check(&q2); + Verify(t>=0.0f); + + Quaternion scaled_quat; + scaled_quat.Multiply(q2, t); + Multiply(q1, scaled_quat); + + #if DEBUG_LEVEL>0 + if (!TestInstance()) + { + Dump(q1); + Dump(q2); + Dump(t); + Dump(*this); + Fail("Quaternion multiplication is unstable!\n"); + } + #endif + return *this; +} + +// +//############################################################################# +//############################################################################# +// +Quaternion& + Quaternion::Add( + const Quaternion &source, + const Vector3D &delta + ) +{ + Check_Pointer(this); + Check(&source); + Check(&delta); + Verify(&source != this); + + // + //--------------------------------------------------------------- + // See if there is any rotation to apply to the source quaternion + //--------------------------------------------------------------- + // + Scalar rotation = delta.Length(); + if (Small_Enough(rotation)) + { + return *this = source; + } + + // + //--------------------------------------------------------------------- + // Build a quaternion from the delta vector, treating the length as the + // amount of rotation and the direction of the vector as the axis of + // rotation + //--------------------------------------------------------------------- + // + SinCosPair half_angle; + half_angle = 0.5f * Radian::Normalize(rotation); + rotation = half_angle.sine / rotation; + Quaternion q( + delta.x * rotation, + delta.y * rotation, + delta.z * rotation, + half_angle.cosine + ); + Check(&q); + return Multiply(source, q); +} + +// +//############################################################################# +//############################################################################# +// +Quaternion& + Quaternion::AddScaled( + const Quaternion &source, + const Vector3D &delta, + Scalar t + ) +{ + Check_Pointer(this); + Check(&source); + Check(&delta); + Verify(&source != this); + + // + //--------------------------------------------------------------- + // See if there is any rotation to apply to the source quaternion + //--------------------------------------------------------------- + // + Scalar rotation = delta.Length(); + if (Small_Enough(rotation)) + { + return *this = source; + } + + // + //--------------------------------------------------------------------- + // Build a quaternion from the delta vector, treating the length as the + // amount of rotation and the direction of the vector as the axis of + // rotation + //--------------------------------------------------------------------- + // + SinCosPair half_angle; + rotation *= t; + half_angle = 0.5f*rotation; + rotation = half_angle.sine / rotation; + Quaternion q( + delta.x * rotation, + delta.y * rotation, + delta.z * rotation, + half_angle.cosine + ); + Check(&q); + return Multiply(source, q); +} + +// +//############################################################################# +//############################################################################# +// +Quaternion& + Quaternion::Normalize() +{ + Scalar t = x*x + y*y + z*z; + if (t <= 1.0f) + { + t = Sqrt(1.0f - t); + if (w<0.0f) + { + x = -x; + y = -y; + z = -z; + } + w = t; + } + else + { + t = Sqrt(t); + x /= t; + y /= t; + z /= t; + w = 0.0f; + } + return *this; +} + +// +//############################################################################# +//############################################################################# +// +Quaternion& + Quaternion::Subtract( + const Quaternion &end, + const Quaternion &start + ) +{ + Check_Pointer(this); + Check(&start); + Check(&end); + + Quaternion inverse(start); + inverse.w = -inverse.w; + return Multiply(inverse, end); +} + +// +//############################################################################# +//############################################################################# +// +Quaternion& + Quaternion::Subtract( + const UnitVector &end, + const UnitVector &start + ) +{ + Check_Pointer(this); + Check(&start); + Check(&end); + + Vector3D + axis; + SinCosPair + delta; + delta.cosine = start*end; + + // + //---------------------------------------------------------------------- + // See if the vectors point in the same direction. If so, return a null + // rotation + //---------------------------------------------------------------------- + // + if (Close_Enough(delta.cosine, 1.0f)) + { + x = 0.0f; + y = 0.0f; + z = 0.0f; + w = 1.0f; + } + + // + //------------------------------------------------------------------------- + // See if the vectors directly oppose each other. If so, pick the smallest + // axis coordinate and generate a vector along it. Project this onto the + // base vector and subtract it out, leaving a perpendicular projection. + // Extend that out to unit length, then set the angle to PI + //------------------------------------------------------------------------- + // + else if (Close_Enough(delta.cosine, -1.0f)) + { + // + //--------------------------- + // Pick out the smallest axis + //--------------------------- + // + int + smallest=0; + Scalar + value=2.0f; + for (int i=X_Axis; i<=Z_Axis; ++i) + { + if (Abs(start[i]) < value) + { + smallest = i; + value = Abs(start[i]); + } + } + + // + //---------------------------------------- + // Set up a vector along the selected axis + //---------------------------------------- + // + axis.x = 0.0f; + axis.y = 0.0f; + axis.z = 0.0f; + axis[smallest] = 1.0f; + + // + //------------------------------------------------------------------- + // If the value on that axis wasn't zero, subtract out the projection + //------------------------------------------------------------------- + // + if (!Small_Enough(value)) + { + Vector3D t; + t.Multiply(start, start*axis); + axis.Subtract(axis, t); + axis.Normalize(axis); + } + + // + //---------------------- + // Convert to quaternion + //---------------------- + // + x = axis.x; + y = axis.y; + z = axis.z; + w = 0.0f; + } + + // + //-------------------------------------------------- + // Otherwise, generate the cross product and unitize + //-------------------------------------------------- + // + else + { + axis.Cross(start, end); + delta.sine = axis.Length(); + axis /= delta.sine; + + // + //--------------------------------------------------------------- + // Now compute sine and cosine of half the angle and generate the + // quaternion + //--------------------------------------------------------------- + // + delta.sine = Sqrt((1.0f - delta.cosine)*0.5f); + x = axis.x * delta.sine; + y = axis.y * delta.sine; + z = axis.z * delta.sine; + w = Sqrt((1.0f + delta.cosine)*0.5f); + } + return *this; +} + +// +//############################################################################# +//############################################################################# +// +Quaternion& + Quaternion::Subtract( + const Vector3D &end, + const Vector3D &start + ) +{ + Check_Pointer(this); + Check(&start); + Check(&end); + + UnitVector + s,e; + + s = start; + e = end; + return Subtract(e, s); +} + +// +//############################################################################# +//############################################################################# +// +Quaternion& + Quaternion::Lerp( + const Quaternion &q1, + const Quaternion &q2, + Scalar t + ) +{ + Check_Pointer(this); + Check(&q1); + Check(&q2); + + if (q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w >= 0.0f) + { + x = ::Lerp(q1.x, q2.x, t); + y = ::Lerp(q1.y, q2.y, t); + z = ::Lerp(q1.z, q2.z, t); + w = ::Lerp(q1.w, q2.w, t); + } + else + { + x = ::Lerp(q1.x, -q2.x, t); + y = ::Lerp(q1.y, -q2.y, t); + z = ::Lerp(q1.z, -q2.z, t); + w = ::Lerp(q1.w, -q2.w, t); + } + + Scalar len = x*x + y*y + z*z + w*w; + if (Small_Enough(len)) + { + x = 0.0f; + y = 0.0f; + z = 0.0f; + w = 1.0f; + } + else + { + len = 1.0f / Sqrt(len); + x *= len; + y *= len; + z *= len; + w *= len; + } + Check(this); + return *this; +} + +// +//############################################################################# +//############################################################################# +// +ostream& operator<<(ostream& stream, const Quaternion& q) +{ + return stream << '<' << q.x << ',' << q.y << ',' << q.z << ',' << q.w + << '>'; +} + +// +//############################################################################# +//############################################################################# +// +Logical Quaternion::TestInstance() const +{ +#if 0 + if (!Close_Enough(x*x + y*y + z*z + w*w,1.0f,2e-6)) + { + Scalar t = 1.0f - x*x - y*y - z*z - w*w; + + if (Small_Enough(t, 2e-6)) + { + Dump(*this); + Dump(1.0f - x*x - y*y - z*z - w*w); + return False; + } + } +#endif + return True; +} + +#if defined(TEST_CLASS) +# include "rotation.tcp" +#endif diff --git a/restoration/source410/MUNGA/SUBSYSTM.CPP b/restoration/source410/MUNGA/SUBSYSTM.CPP new file mode 100644 index 00000000..21a49b6a --- /dev/null +++ b/restoration/source410/MUNGA/SUBSYSTM.CPP @@ -0,0 +1,298 @@ +# if !defined(MUNGA_HPP) +# include +# endif +#pragma hdrstop + +# if !defined(SUBSYSTM_HPP) +# include +# endif +# if !defined(FILEUTIL_HPP) +# include +# endif +# if !defined(NOTATION_HPP) +# include +# endif +# if !defined(NAMELIST_HPP) +# include +# endif + +Subsystem::SharedData + Subsystem::DefaultData( + Subsystem::ClassDerivations, + Subsystem::MessageHandlers, + Subsystem::AttributeIndex, + Subsystem::StateCount + ); + +Derivation + Subsystem::ClassDerivations(Simulation::ClassDerivations, "Subsystem"); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Subsystem::WriteUpdateRecord( + UpdateRecord *message, + int update_model + ) +{ + Check(this); + Check_Pointer(message); + + Simulation::WriteUpdateRecord(message, update_model); + message->subsystemID = (Word)(subsystemID+1); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Subsystem::Subsystem( + Entity *entity, + int subsystem_ID, + SubsystemResource *model, + SharedData &shared_data +): + Simulation(model->classID, shared_data) +{ + owningEntity = entity; + subsystemID = subsystem_ID; + size_t name_size = strlen(model->subsystemName)+1; + subsystemName = new char[name_size]; + Register_Pointer(subsystemName); + Str_Copy(subsystemName, model->subsystemName, name_size); + segmentIndex = model->segmentIndex; + simulationFlags = model->subsystemFlags; + damageZone = NULL; +} + +Subsystem::Subsystem( + Entity *entity, + int subsystem_id, + const char* subsystem_name, + RegisteredClass::ClassID class_id, + SharedData &shared_data +): + Simulation(class_id, shared_data) +{ + owningEntity = entity; + subsystemID = subsystem_id; + size_t name_size = strlen(subsystem_name)+1; + subsystemName = new char[name_size]; + Register_Pointer(subsystemName); + Str_Copy(subsystemName, subsystem_name, name_size); + segmentIndex = -1; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Subsystem::~Subsystem() +{ + Unregister_Pointer(subsystemName); + delete[] subsystemName; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +ResourceDescription::ResourceID + Subsystem::CreateStreamedSubsystem( + NotationFile *model_file, + const char *model_name, + const char *subsystem_name, + SubsystemResource *subsystem_resource, + NotationFile *subsystem_file, + const ResourceDirectories *directories + ) +{ + Check(model_file); + Check_Pointer(model_name); + Check_Pointer(subsystem_name); + Check_Pointer(subsystem_resource); + Check(subsystem_file); + Check_Pointer(directories); + + for(int ii=0; ii<(sizeof(subsystem_resource->subsystemName));ii++) + { + subsystem_resource->subsystemName[ii] = '\0'; + } + subsystem_resource->subsystemModelSize = sizeof(*subsystem_resource); + + if (strlen(subsystem_name) > sizeof(subsystem_resource->subsystemName)-1) + { + DEBUG_STREAM << subsystem_name << " is too long. Maximum name size is " + << (sizeof(subsystem_resource->subsystemName)-1) << " character!\n"; + return False; + } + Str_Copy( + subsystem_resource->subsystemName, + subsystem_name, + sizeof(subsystem_resource->subsystemName)-1 + ); + + // + //------------------------------------------ + // If any flags were specified, read them in + //------------------------------------------ + // + const char* flags; + subsystem_resource->subsystemFlags = 0; + if( + subsystem_file->GetEntry( + subsystem_name, + "SubsystemFlags", + &flags + ) + ) + { + if (!strcmp(flags,"DontReplicateFlag")) + { + subsystem_resource->subsystemFlags |= Subsystem::DontReplicateFlag; + } + else + { + DEBUG_STREAM << subsystem_name << " has an unknown subsystem flag!\n" << flush; + return False; + } + } + + // + //-------------------------------------------------- + // Get the Segment Name to locate in the .skl file + //-------------------------------------------------- + // + const char* desired_page; + subsystem_resource->segmentIndex = -1; + if( + subsystem_file->GetEntry( + subsystem_name, + "SegmentPageName", + &desired_page + ) + ) + { + subsystem_resource->segmentIndex = + Get_Segment_Index(model_file, model_name, directories, desired_page); + } + return True; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + Subsystem::TestInstance() const +{ + return IsDerivedFrom(ClassDerivations); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + Subsystem::GenerateFault(int /*fault_index*/) +{ + Check(this); + Check_Fpu(); + return False; // fault not generated +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +int + Get_Segment_Index( + NotationFile *model_file, + const char* model_name, + const ResourceDirectories *directories, + const char *desired_page + ) +{ + //------------------------------------------ + // Get the Segment Index from the .skl file + //------------------------------------------ + // + const char* skl_entry; + if ( + !model_file->GetEntry( + "video", + "skeleton", + &skl_entry + ) + ) + { + cerr << model_name << " is missing .skl file specification!\n"; + return -1; + } + + char *skl_filename = + MakePathedFilename(directories->videoDirectory, skl_entry); + Register_Pointer(skl_filename); + + NotationFile *skl_file = new NotationFile(skl_filename); + Register_Object(skl_file); + if (!skl_file->PageCount()) + { + cerr << skl_filename << " is empty or missing!\n"; +Dump_And_Die: + Unregister_Pointer(skl_filename); + delete[] skl_filename; + Unregister_Object(skl_file); + delete skl_file; + return ResourceDescription::NullResourceID; + } + + // + // Make a pagelist of all the segments + // + NameList *segment_pages = skl_file->MakePageList(); + Register_Object(segment_pages); + + NameList::Entry *segment_entry = segment_pages->GetFirstEntry(); + char + segment_page_name[32]; + int + segment_index = -1; + int + current_index = 0; + while(segment_entry) + { + Str_Copy( + segment_page_name, + segment_entry->GetName(), + sizeof(segment_page_name) + ); + // + //--------------------------------------- + // skip labonly and damagezones + //--------------------------------------- + // + if( + (strcmp(segment_page_name, "LAB_ONLY") == 0) || + (strcmp(segment_page_name,"DamageZones") ==0) + ) + { + segment_entry = segment_entry->GetNextEntry(); + continue; + } + // + //------------------------------------- + // if names match save the index + //------------------------------------- + // + else if(strcmp(segment_page_name,desired_page) ==0) + { + segment_index = current_index; + break; + } + ++current_index; + segment_entry = segment_entry->GetNextEntry(); + } + if(segment_index == -1) + { + cout< +# endif +#pragma hdrstop + +# if !defined(TEAM_HPP) +# include +# endif +# if !defined(APP_HPP) +# include +# endif +# if !defined(NTTMGR_HPP) +# include +# endif + +//############################################################################# +//############################### Team ################################# +//############################################################################# + +//############################################################################# +// Shared Data Support +// +Derivation + Team::ClassDerivations(Entity::ClassDerivations, "Team"); + +Team::SharedData + Team::DefaultData( + Team::ClassDerivations, + Team::MessageHandlers, + Team::AttributeIndex, + Team::StateCount, + (Team::MakeHandler)Team::Make + ); +//############################################################################# +// Attribute Support +// + +const Team::IndexEntry + Team::AttributePointers[]= +{ + ATTRIBUTE_ENTRY(Team, TeamName, teamName), + ATTRIBUTE_ENTRY(Team, TeamScore, teamScore) +}; + +Team::AttributeIndexSet + Team::AttributeIndex(ELEMENTS(Team::AttributePointers), + Team::AttributePointers, + Entity::AttributeIndex + ); + +//############################################################################# +// Message Support +// + +const Receiver::HandlerEntry + Team::MessageHandlerEntries[]= +{ + MESSAGE_ENTRY(Team, Score) +}; + +Receiver::MessageHandlerSet + Team::MessageHandlers( + ELEMENTS(Team::MessageHandlerEntries), + Team::MessageHandlerEntries, + Entity::MessageHandlers + ); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Team::ScoreMessageHandler(ScoreMessage *score_message) +{ + Check(this); + Check(score_message); + + teamScore += score_message->scoreAward; + Check_Fpu(); +} +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +void + Team::TeamSimulation( + Scalar // time_slice + ) +{ + Check(this); + +} +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Team::Team( + MakeMessage *creation_message, + SharedData &shared_data +) : + Entity (creation_message, shared_data) +{ + Str_Copy(teamName, creation_message->teamName, sizeof(teamName)); + + teamScore = creation_message->initialScore; + // + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Add this to the Entity Group of Teams + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // + Check(application); + EntityManager *entity_manager = application->GetEntityManager(); + Check(entity_manager); + EntityGroup *team_group = entity_manager->UseGroup("Teams"); + Check(team_group); + team_group->Add(this); + + SetValidFlag(); + + Check_Fpu(); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Team::~Team() +{ + +} + + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Team* + Team::Make(MakeMessage *creation_message) +{ + Check_Fpu(); + return new Team(creation_message); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + Team::CreateMakeMessage( + MakeMessage *creation_message, + NotationFile *model_file, + const ResourceDirectories *directories +) +{ + Check(creation_message); + Check(model_file); + Check_Pointer(directories); + + if (!Entity::CreateMakeMessage(creation_message, model_file, directories)) + { + return False; + } + + creation_message->messageLength = sizeof(Team::MakeMessage); + creation_message->classToCreate = TeamClassID; + creation_message->instanceFlags = MasterInstance | TrappedFlag | MapFlag; + Str_Copy(creation_message->teamName, "DEFUALT", sizeof(creation_message->teamName)); + + char *p; +#if 0 + // + //~~~~~~~~~~~~~~~ + // Get the TeamID + //~~~~~~~~~~~~~~~ + // + if ((p = strtok(NULL, " ")) == NULL) + { + cerr << "teamID missing!\n"; + return False; + } + creation_message->teamID = atoi(p); +#endif + + // + //~~~~~~~~~~~~~~~~~~~~~~ + // Get the Initial Score + //~~~~~~~~~~~~~~~~~~~~~~ + // + if ((p = strtok(NULL, " ")) == NULL) + { + cerr << "InitialScore missing!\n"; + return False; + } + creation_message->initialScore = atoi(p); + + + // + //~~~~~~~~~~~~~~~ + // Get the TeamName + //~~~~~~~~~~~~~~~ + // + if ((p = strtok(NULL, ",")) == NULL) + { + cerr << "teamName missing!\n"; + return False; + } + Str_Copy(creation_message->teamName,p, sizeof(creation_message->teamName)); + + + + return True; +} + +Logical + Team::TestInstance() const +{ + return IsDerivedFrom(ClassDerivations); +} diff --git a/restoration/source410/MUNGA/TERRAIN.CPP b/restoration/source410/MUNGA/TERRAIN.CPP new file mode 100644 index 00000000..60899955 --- /dev/null +++ b/restoration/source410/MUNGA/TERRAIN.CPP @@ -0,0 +1,305 @@ +# if !defined(MUNGA_HPP) +# include +# endif +#pragma hdrstop + +# if !defined(TERRAIN_HPP) +# include +# endif +# if !defined(BOXSOLID_HPP) +# include +# endif +# if !defined(APP_HPP) +# include +# endif +# if !defined(INTEREST_HPP) +# include +# endif + +//############################################################################# +//############################### Terrain ################################# +//############################################################################# + +//############################################################################# +// Shared Data Support +// +Derivation + Terrain::ClassDerivations(Entity::ClassDerivations, "Terrain"); + +Terrain::SharedData + Terrain::DefaultData( + Terrain::ClassDerivations, + Terrain::MessageHandlers, + Terrain::AttributeIndex, + Terrain::StateCount, + (Entity::MakeHandler)Terrain::Make + ); + +//############################################################################# +// Attribute Support +// +const Terrain::IndexEntry + Terrain::AttributePointers[]= +{ + { + Terrain::LocalScaleAttributeID, + "LocalScale", + (Entity::AttributePointer)&Terrain::localScale + } +}; + +Terrain::AttributeIndexSet + Terrain::AttributeIndex(ELEMENTS(Terrain::AttributePointers), + Terrain::AttributePointers, + Entity::AttributeIndex + ); + +//############################################################################# +// Construction and Destruction +// + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Terrain::Terrain( + Terrain::MakeMessage *creation_message, + Terrain::SharedData &virtual_data +): + Entity(creation_message, virtual_data) +{ + localScale = creation_message->localScale; + SetValidFlag(); + + // + //--------------------------------------------------------------------- + // For now, load in the collision resources into the tree pointed to by + // this resource + //--------------------------------------------------------------------- + // + ResourceFile *res_file = application->GetResourceFile(); + Check(res_file); + ResourceDescription *res = + res_file->SearchList( + resourceID, + ResourceDescription::BoxedSolidStreamResourceType + ); + + collisionVolumes = NULL; + if (res) + { + Check(res); + res->Lock(); + InterestManager *interest_mgr = + application->GetInterestManager(); + Check(interest_mgr); + InterestZone *zone = + interest_mgr->GetInterestZone(interestZoneID); + Check(zone); + BoxedSolidTree* tree = zone->GetCollisionRoot(); + Check(tree); + BoxedSolidResource* solids = + (BoxedSolidResource*)res->resourceAddress; + int size = res->resourceSize / sizeof(BoxedSolidResource); + Dump(localOrigin); + while (size--) + { + // + // Don't forget about scaling... + // + BoxedSolidResource rot_box; + rot_box.Instance(*solids,localOrigin); + collisionVolumes = + BoxedSolid::MakeBoxedSolid(&rot_box, this, collisionVolumes); + Register_Object(collisionVolumes); + tree->Add(collisionVolumes, rot_box.sliceExtents); + ++solids; + } + res->Unlock(); + } +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + Terrain::CreateMakeMessage( + MakeMessage *creation_message, + NotationFile *model_file, + const ResourceDirectories *directories + ) +{ + Check(creation_message); + Check(model_file); + + if (!Entity::CreateMakeMessage(creation_message, model_file, directories)) + { + return False; + } + + creation_message->messageLength = sizeof(MakeMessage); + creation_message->classToCreate = TerrainClassID; + creation_message->instanceFlags = HermitInstance|TrappedFlag; + + char *p; + if ((p = strtok(NULL, " ")) == NULL) + { + cerr << "Scale missing!\n"; + return False; + } + creation_message->localScale = atof(p); + return True; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Terrain* + Terrain::Make(Terrain::MakeMessage *creation_message) +{ + return new Terrain(creation_message); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Terrain::~Terrain() +{ + BoxedSolid *box = collisionVolumes; + while (box) + { + BoxedSolid *next_box = box->GetNextSolid(); + Unregister_Object(box); + delete box; + box = next_box; + } +} + +Logical + Terrain::TestInstance() const +{ + return IsDerivedFrom(ClassDerivations); +} + +//############################################################################# +//######################### UnscalableTerrain ########################### +//############################################################################# + +//############################################################################# +// Shared Data Support +// +Derivation + UnscalableTerrain::ClassDerivations(Terrain::ClassDerivations, "UnscalableTerrain"); + + +UnscalableTerrain::SharedData + UnscalableTerrain::DefaultData( + UnscalableTerrain::ClassDerivations, + UnscalableTerrain::MessageHandlers, + UnscalableTerrain::AttributeIndex, + UnscalableTerrain::StateCount, + (Entity::MakeHandler)UnscalableTerrain::Make + ); + +//############################################################################# +// Construction and Destruction +// + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +UnscalableTerrain::UnscalableTerrain( + UnscalableTerrain::MakeMessage *creation_message, + UnscalableTerrain::SharedData &virtual_data +): + Entity(creation_message, virtual_data) +{ + + // + //--------------------------------------------------------------------- + // For now, load in the collision resources into the tree pointed to by + // this resource + //--------------------------------------------------------------------- + // + SetValidFlag(); + ResourceFile *res_file = application->GetResourceFile(); + Check(res_file); + ResourceDescription *res = + res_file->SearchList( + resourceID, + ResourceDescription::BoxedSolidStreamResourceType + ); + collisionVolumes = NULL; + + if (res) + { + Check(res); + res->Lock(); + InterestManager *interest_mgr = + application->GetInterestManager(); + Check(interest_mgr); + InterestZone *zone = + interest_mgr->GetInterestZone(interestZoneID); + Check(zone); + BoxedSolidTree* tree = zone->GetCollisionRoot(); + Check(tree); + BoxedSolidResource* solids = + (BoxedSolidResource*)res->resourceAddress; + int size = res->resourceSize / sizeof(BoxedSolidResource); + while (size--) + { + BoxedSolidResource rot_box; + rot_box.Instance(*solids,localOrigin); + collisionVolumes = + BoxedSolid::MakeBoxedSolid(&rot_box, this, collisionVolumes); + Register_Object(collisionVolumes); + tree->Add(collisionVolumes, rot_box.sliceExtents); + ++solids; + } + res->Unlock(); + } +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +Logical + UnscalableTerrain::CreateMakeMessage( + MakeMessage *creation_message, + NotationFile *model_file, + const ResourceDirectories *directories + ) +{ + Check(creation_message); + Check(model_file); + + if (!Entity::CreateMakeMessage(creation_message, model_file, directories)) + { + return False; + } + + creation_message->classToCreate = UnscalableTerrainClassID; + creation_message->instanceFlags = HermitInstance|TrappedFlag; + return True; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +UnscalableTerrain* + UnscalableTerrain::Make(UnscalableTerrain::MakeMessage *creation_message) +{ + return new UnscalableTerrain(creation_message); +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +UnscalableTerrain::~UnscalableTerrain() +{ + BoxedSolid *box = collisionVolumes; + while (box) + { + BoxedSolid *next_box = box->GetNextSolid(); + Unregister_Object(box); + delete box; + box = next_box; + } +} + +Logical + UnscalableTerrain::TestInstance() const +{ + return IsDerivedFrom(ClassDerivations); +} diff --git a/restoration/source410/MUNGA_L4/L4APP.CPP b/restoration/source410/MUNGA_L4/L4APP.CPP new file mode 100644 index 00000000..4a420e53 --- /dev/null +++ b/restoration/source410/MUNGA_L4/L4APP.CPP @@ -0,0 +1,73 @@ +//===========================================================================// +// File: l4app.cpp // +// Project: MUNGA Brick: L4Application // +// Contents: Implementation details for L4Application // +//---------------------------------------------------------------------------// +// Date Who Modification // +// -------- --- ---------------------------------------------------------- // +// // +//---------------------------------------------------------------------------// +// Copyright (C) 1994, Virtual World Entertainment, Inc. // +// All Rights reserved worldwide. // +// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // +//===========================================================================// + +#include +#pragma hdrstop + +#if !defined(L4APP_HPP) +# include +#endif + +// +//############################################################################# +//############################################################################# +// +const Receiver::HandlerEntry + L4Application::MessageHandlerEntries[]= +{ + MESSAGE_ENTRY(L4Application, LightsOut), + MESSAGE_ENTRY(L4Application, RunMission), + MESSAGE_ENTRY(L4Application, StopMission), + MESSAGE_ENTRY(L4Application, KeyCommand) +}; + +L4Application::MessageHandlerSet + L4Application::MessageHandlers( + ELEMENTS(L4Application::MessageHandlerEntries), + L4Application::MessageHandlerEntries, + Application::MessageHandlers + ); + +// +//############################################################################# +//############################################################################# +// +Derivation + L4Application::ClassDerivations( + Application::ClassDerivations, + "L4Application" + ); + +L4Application::SharedData + L4Application::DefaultData( + L4Application::ClassDerivations, + L4Application::MessageHandlers + ); + +// +//############################################################################# +//############################################################################# +// +Logical + L4Application::seeSolids = False; +CString + L4Application::eggNotationFileName; +unsigned long + L4Application::networkCommonFlatAddress = 0; +int + L4Application::missionReviewMode = 0; +CString + L4Application::rioPlaybackFileName; +CString + L4Application::rioRecordingFileName; diff --git a/restoration/source410/MUNGA_L4/L4GAUGE.CPP b/restoration/source410/MUNGA_L4/L4GAUGE.CPP new file mode 100644 index 00000000..714d9627 --- /dev/null +++ b/restoration/source410/MUNGA_L4/L4GAUGE.CPP @@ -0,0 +1,5171 @@ +# if !defined(MUNGAL4_HPP) +# include +# endif +#pragma hdrstop + +#define PRELOAD_ART + +# if !defined(PLAYER_HPP) +# include +# endif +# if !defined(L4APP_HPP) +# include +# endif +# if !defined(L4GAUGE_HPP) +# include +# endif +# if !defined(L4GREND_HPP) +# include +# endif + +// #define LOCAL_TEST + +#if defined(LOCAL_TEST) +# define Test_Tell(n) cout << n +#else +# define Test_Tell(n) +#endif + + +LookupTable + configureChannels[] = + { + {"red", L4GraphicsPort::RedChannel}, + {"green", L4GraphicsPort::GreenChannel}, + {"blue", L4GraphicsPort::BlueChannel}, + {"rgb", L4GraphicsPort::AllChannels}, + + {"direct", L4GraphicsPort::DirectColor}, + {"blank", L4GraphicsPort::BlankColor}, + + {"redtransparent", L4GraphicsPort::RedChannelTransparentZero}, + {"greentransparent", L4GraphicsPort::GreenChannelTransparentZero}, + {"bluetransparent", L4GraphicsPort::BlueChannelTransparentZero}, + {"rgbtransparent", L4GraphicsPort::AllChannelsTransparentZero}, + {NULL, -1} + }; + +LookupTable + configurePalettes[] = + { + {"native", SVGA16::NativePalette}, + {"clut0", SVGA16::SecondaryPalette}, + {"clut1", SVGA16::AuxiliaryPalette1}, + {"clut2", SVGA16::AuxiliaryPalette2}, + {NULL, -1} + }; + +LookupTable + configureFormat[] = + { + {"unsigned", NumericDisplay::unsignedFormat}, + {"signed", NumericDisplay::signedFormat}, + {"signedBlankedZeros", NumericDisplay::signedBlankedZerosFormat}, + {"absolute", NumericDisplay::absoluteFormat}, + {"time", NumericDisplay::timeFormat}, + {NULL, -1} + }; + +LookupTable + configureDirection[] = + { + {"left", WipeGaugeScalar::wipeLeft}, + {"down", WipeGaugeScalar::wipeDown}, + {"right", WipeGaugeScalar::wipeRight}, + {"up", WipeGaugeScalar::wipeUp}, + {NULL, -1} + }; + +char + *nameCopy(const char *old_name) +{ + Check_Pointer(old_name); + + char + *copy = strdup(old_name); + Register_Pointer(copy); + + return copy; +} + +//########################################################################### +// NumericDisplay +//########################################################################### +NumericDisplay::NumericDisplay( + L4Warehouse *the_warehouse, + int x_position, int y_position, + const char *font_name, + int number_of_digits, + NumericDisplay::NumericFormat requested_format, + int background_color, int foreground_color +) +{ + Check_Pointer(this); + + //------------------------------------------------------------ + // Save the font name + //------------------------------------------------------------ + digitMapName = nameCopy(font_name); + //------------------------------------------------------------ + // Order the font from the warehouse (pre-load for future use) + //------------------------------------------------------------ + Check(the_warehouse); + warehouse = the_warehouse; + + Check_Pointer(digitMapName); + + BitMap + *digit_map = warehouse->bitMapBin.Get(digitMapName); + //----------------------------------------------------------- + // Calculate font-specific values + //----------------------------------------------------------- + if (digit_map == NULL) + { + digitWidth = 0; + digitHeight = 0; + } + else + { + Check(digit_map); + digitWidth = (digit_map->Data.Size.x+1)/totalDigitsPerFont; + digitHeight = digit_map->Data.Size.y; + } + //----------------------------------------------------------- + // Set internal values + //----------------------------------------------------------- + if (number_of_digits < 1) + { + number_of_digits = 1; + } + + if (format == timeFormat) + { + if (number_of_digits > 8) + { + number_of_digits = 8; + } + largestValue = (Scalar) (99*60*60); + } + else + { + if (number_of_digits > maxDigits) + { + number_of_digits = maxDigits; + } + largestValue = (Scalar) (pow(10.0f, number_of_digits)-1.0); + } + + numberOfDigits = number_of_digits; + format = requested_format; + backgroundColor = background_color; + foregroundColor = foreground_color; + offsetX = x_position; + offsetY = y_position; + erased = True; + + ForceUpdate(); // ensure initialization + + //------------------------------------------------------------ + // Done with the font, release it + //------------------------------------------------------------ +# if !defined(PRELOAD_ART) + Check_Pointer(warehouse); + warehouse->bitMapBin.Release(digitMapName); +# endif + + Check_Fpu(); +} + +NumericDisplay::~NumericDisplay() +{ + Check(this); + //------------------------------------------------------------ + // Unlock preloaded art + //------------------------------------------------------------ +# if defined(PRELOAD_ART) + warehouse->bitMapBin.Release(digitMapName); +# endif + //------------------------------------------------------------ + // Delete the font name + //------------------------------------------------------------ + Unregister_Pointer(digitMapName); + delete[] digitMapName; + digitMapName = NULL; + + Check_Fpu(); +} + +Logical + NumericDisplay::TestInstance() const +{ + return True; +} + +void + NumericDisplay::ShowInstance(char *indent) +{ + Check(this); + + cout << indent << "NumericDisplay:\n"; + + char + temp[80]; + + Str_Copy(temp,indent, 80); + Str_Cat(temp,"...", 80); + + cout << temp << "backgroundColor=" << backgroundColor << "\n"; + cout << temp << "foregroundColor=" << foregroundColor << "\n"; + cout << temp << "numberOfDigits =" << numberOfDigits << "\n"; + cout << temp << "format ="; + switch(format) + { + case unsignedFormat: cout << "unsignedFormat\n"; break; + case signedFormat: cout << "signedFormat\n"; break; + case signedBlankedZerosFormat: cout << "signedBlankedZerosFormat\n"; break; + case absoluteFormat: cout << "absoluteFormat\n"; break; + case timeFormat: cout << "timeFormat\n"; break; + default: + cout << "**OUT OF RANGE**\n"; + } + + Check_Fpu(); +} + +void + NumericDisplay::ForceUpdate() +{ + Check(this); + //----------------------------------------------------------- + // Force update by clearing previous value and digits + //----------------------------------------------------------- + previousValue = -1.2345f; + + for(int i=0; ibitMapBin.Get(digitMapName); + + if (digit_map != NULL) + { + // + //----------------------------------------------------------- + // Get absolute value if required + //----------------------------------------------------------- + // + if(format == absoluteFormat) + { + if (current_value < 0.0) + { + current_value = - current_value; + } + } + Check_Fpu(); + + // + //----------------------------------------------------------- + // Draw only if value has changed + //----------------------------------------------------------- + // + if (previousValue != current_value) + { + previousValue = current_value; + + int + test_value((int) (current_value+.5)), + digit_height(digit_map->Data.Size.y), + i, + x, + sx; + Check_Fpu(); + + char + buffer[maxDigits+1], + *buffer_pointer; + + // + //-------------------------------------------------------- + // Get absolute value, limit to maximum + //-------------------------------------------------------- + // + if (test_value < 0) + { + test_value = - test_value; + } + + if (test_value > (int) largestValue) + { + test_value = (int) largestValue; + } + Check_Fpu(); + + // + //-------------------------------------------------------- + // Build buffer + //-------------------------------------------------------- + // + buffer_pointer = &buffer[numberOfDigits-1]; + + switch (format) + { + case absoluteFormat: + case unsignedFormat: + case signedBlankedZerosFormat: + for(i=numberOfDigits-1; i>=0; --i) + { + *buffer_pointer-- = (char) (test_value % 10); + test_value /= 10; + } + Check_Fpu(); + break; + + case signedFormat: + for(i=numberOfDigits-2; i>=0; --i) + { + *buffer_pointer-- = (char) (test_value % 10); + test_value /= 10; + } + *buffer_pointer = (char) + ((current_value >= 0.0) ? plusDigit : minusDigit); + Check_Fpu(); + break; + + case timeFormat: + { + int + n, + state; + + state = 0; + for(i=numberOfDigits; i>0; ) + { + switch(state++) + { + case 0: // seconds + case 1: // minutes + n = test_value % 60; + test_value /= 60; + break; + + case 2: // hours + n = test_value % 24; + test_value /= 24; + break; + + case 3: // days + n = test_value % 100; + break; + + default: // Oh, come on now! + n = 0; + break; + } + Check_Fpu(); + if (--i >= 0) + { + *buffer_pointer-- = (char) (n % 10); + } + if (--i >= 0) + { + *buffer_pointer-- = (char) (n / 10); + } + if (--i >= 0) + { + *buffer_pointer-- = (char) colonDigit; + } + } + } + break; + } + Check_Fpu(); + + // + //-------------------------------------------------------- + // Draw digits from buffer + //-------------------------------------------------------- + // + Logical + blanked = True; + + char + this_digit; + + for( + i=0, x=offsetX, buffer_pointer=buffer; + iMoveToAbsolute(x, offsetY); + //----------------------------------------------------- + // If blanked, draw filled rectangle + //----------------------------------------------------- + if (this_digit == blankedDigit) + { + graphics_view->SetColor(backgroundColor); + graphics_view->DrawFilledRectangleToRelative( + digitWidth, + digit_height + ); + } + //----------------------------------------------------- + // Else draw character + //----------------------------------------------------- + else + { + sx = digitWidth*this_digit; + + graphics_view->SetColor(foregroundColor); + graphics_view->DrawBitMapOpaque( + backgroundColor, + 0, //rotation + digit_map, + sx, 0, sx+digitWidth-1, digit_height + ); + } + } + } + } + } + //----------------------------------------------------------- + // Unlock the font: we're done + //----------------------------------------------------------- + Check(warehouse); + warehouse->bitMapBin.Release(digitMapName); + + Check_Fpu(); +} + +void + NumericDisplay::Erase( + GraphicsView *graphics_view + ) +{ + Check(this); + + if (!erased) + { + erased = True; + + graphics_view->SetColor(backgroundColor); + graphics_view->MoveToAbsolute(offsetX, offsetY); + graphics_view->DrawFilledRectangleToRelative( + digitWidth*numberOfDigits, + digitHeight + ); + } + Check_Fpu(); +} + + +//########################################################################### +// NumericDisplayScalar +//########################################################################### +MethodDescription + NumericDisplayScalar::methodDescription = + { + "numeric", + NumericDisplayScalar::Make, + { + { ParameterDescription::typeRate, NULL }, // rate ID + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeVector, NULL }, // size + { ParameterDescription::typeString, NULL }, // font name + { ParameterDescription::typeInteger, NULL }, // # of digits + { ParameterDescription::typeString, NULL }, // format + { ParameterDescription::typeColor, NULL }, // background + { ParameterDescription::typeColor, NULL }, // foreground + { ParameterDescription::typeAttribute, NULL }, // attribute + PARAMETER_DESCRIPTION_END + } + }; + +Logical + NumericDisplayScalar::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeRate); // rate ID + parameterList[1].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[2].CheckIt(ParameterDescription::typeVector); // size + parameterList[3].CheckIt(ParameterDescription::typeString); // font name + parameterList[4].CheckIt(ParameterDescription::typeInteger); // # of digs + parameterList[5].CheckIt(ParameterDescription::typeString); // format + parameterList[6].CheckIt(ParameterDescription::typeColor); // background + parameterList[7].CheckIt(ParameterDescription::typeColor); // foreground + parameterList[8].CheckIt(ParameterDescription::typeAttribute); // value name +# endif + + Test_Tell("NumericDisplayScalar::Make\n"); + Check(gauge_renderer); + + int + number_format = configureFormat[0].Search( + parameterList[5].data.string + ); + + if (number_format < 0) + { + Test_Tell("NumericDisplayScalar::Make format NOT FOUND\n"); + Check_Fpu(); + return False; + } + +# if DEBUG_LEVEL > 0 + NumericDisplayScalar + *numeric_display = +# endif + new NumericDisplayScalar( + parameterList[0].data.rate, + parameterList[1].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, //unsigned int owner_ID + display_port_index, //int graphics_port_number + position.x, position.y, + position.x + parameterList[2].data.vector.x, + position.y + parameterList[2].data.vector.y, + parameterList[3].data.string, //font name + parameterList[4].data.integer, //int number_of_chars + (NumericDisplay::NumericFormat) number_format, + parameterList[6].data.integer, //int background_color + parameterList[7].data.integer, //int foreground_color + (Scalar *) parameterList[8].data.attributePointer + + // HACK!!!! The (Scalar *) is VERY dangerous! + ); + Register_Object(numeric_display); + + //-------------------------------------------------------- + // Make sure the font was properly placed in the warehouse + //-------------------------------------------------------- + Check(gauge_renderer); + L4Warehouse + *warehouse = (L4Warehouse *) gauge_renderer->warehousePointer; + Check(warehouse); + + if (warehouse->bitMapBin.Get(parameterList[3].data.string) == NULL) + { + Test_Tell("NumericDisplayScalar::Missing font\n"); + Check_Fpu(); + return False; + } + else + { + warehouse->bitMapBin.Release(parameterList[3].data.string); + } + //-------------------------------------------------------- + // Everything's ok + //-------------------------------------------------------- + Test_Tell("NumericDisplayScalar::Make OK\n"); + Check_Fpu(); + return True; +} + +NumericDisplayScalar::NumericDisplayScalar( + GaugeRate rate, + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, int right, int top, + const char *font_name, //BitMap *font, + int number_of_digits, + NumericDisplay::NumericFormat requested_format, + int background_color, int foreground_color, + Scalar *value_pointer, + const char *identification_string +): + GraphicGauge( + rate, + mode_mask, + renderer, + owner_ID, + graphics_port_number, + identification_string + ) +{ + Check_Pointer(this); + // graphics_port may be NULL! + Check_Pointer(value_pointer); + //----------------------------------------------------------- + // Set internal values + //----------------------------------------------------------- + numericDisplay = new NumericDisplay( + (L4Warehouse *) renderer->warehousePointer, + 0,0, + font_name, + number_of_digits, + requested_format, + background_color, + foreground_color + ); + Register_Object(numericDisplay); + + localView.SetPositionWithinPort(left, bottom, right, top); + + // + //----------------------------------------------------------- + // Build connection to value + //----------------------------------------------------------- + // + GaugeConnection + *connection; + + connection = new + GaugeConnectionDirectOf(0, ¤tValue, value_pointer); + Register_Object(connection); + AddConnection(connection); + Check_Fpu(); +} + +NumericDisplayScalar::~NumericDisplayScalar() +{ + Check(this); + + //------------------------------------------------- + // Destroy the numeric display + //------------------------------------------------- + if (numericDisplay != NULL) + { + Unregister_Object(numericDisplay); + delete numericDisplay; + numericDisplay = NULL; + } + + // base class deletes all connections in Gauge::~Gauge + Check_Fpu(); +} + +Logical + NumericDisplayScalar::TestInstance() const +{ + return GraphicGauge::TestInstance(); +} + +void + NumericDisplayScalar::ShowInstance(char *indent) +{ + Check(this); + + cout << indent << "NumericDisplayScalar:\n"; + + char + temp[80]; + + Str_Copy(temp,indent, 80); + Str_Cat(temp,"...", 80); + + GraphicGauge::ShowInstance(temp); + Check(numericDisplay); + numericDisplay->ShowInstance(temp); + Check_Fpu(); +} + +void + NumericDisplayScalar::BecameActive() +{ + Check(this); + Check(numericDisplay); + numericDisplay->ForceUpdate(); + Check_Fpu(); +} + +void + NumericDisplayScalar::SetColors(int bg_color, int fg_color) +{ + Check(this); + numericDisplay->SetColors(bg_color, fg_color); + Check_Fpu(); +} + +void + NumericDisplayScalar::Execute() +{ + Check(this); + Check(numericDisplay); + numericDisplay->Draw(&localView, currentValue); + Check_Fpu(); +} + +//########################################################################### +// NumericDisplaySpeed +// +// - Converts input in meters per second to display as kilometers per hour +//########################################################################### +MethodDescription + NumericDisplaySpeed::methodDescription = + { + "numericSpeed", + NumericDisplaySpeed::Make, + { + { ParameterDescription::typeRate, NULL }, // rate ID + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeVector, NULL }, // size + { ParameterDescription::typeString, NULL }, // font name + { ParameterDescription::typeInteger, NULL }, // # of digits + { ParameterDescription::typeString, NULL }, // format + { ParameterDescription::typeColor, NULL }, // background + { ParameterDescription::typeColor, NULL }, // foreground + { ParameterDescription::typeAttribute, NULL }, // attribute + PARAMETER_DESCRIPTION_END + } + }; + +Logical + NumericDisplaySpeed::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeRate); // rate ID + parameterList[1].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[2].CheckIt(ParameterDescription::typeVector); // size + parameterList[3].CheckIt(ParameterDescription::typeString); // font name + parameterList[4].CheckIt(ParameterDescription::typeInteger); // # of digs + parameterList[5].CheckIt(ParameterDescription::typeString); // format + parameterList[6].CheckIt(ParameterDescription::typeColor); // background + parameterList[7].CheckIt(ParameterDescription::typeColor); // foreground + parameterList[8].CheckIt(ParameterDescription::typeAttribute); // value name +# endif + + Test_Tell("NumericDisplaySpeed::Make\n"); + + int + number_format = configureFormat[0].Search( + parameterList[5].data.string + ); + + if (number_format < 0) + { + Test_Tell("NumericDisplaySpeed::Make format NOT FOUND\n"); + Check_Fpu(); + return False; + } + +# if DEBUG_LEVEL > 0 + NumericDisplaySpeed + *numeric_display = +# endif + new NumericDisplaySpeed( + parameterList[0].data.rate, + parameterList[1].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, //unsigned int owner_ID + display_port_index, //int graphics_port_number + position.x, position.y, + position.x + parameterList[2].data.vector.x, + position.y + parameterList[2].data.vector.y, + parameterList[3].data.string, //font name + parameterList[4].data.integer, //int number_of_chars + (NumericDisplay::NumericFormat) number_format, + parameterList[6].data.integer, //int background_color + parameterList[7].data.integer, //int foreground_color + (Scalar *) parameterList[8].data.attributePointer + + // HACK!!!! The (Scalar *) is VERY dangerous! + ); + + Register_Object(numeric_display); + + //-------------------------------------------------------- + // Make sure the font was properly placed in the warehouse + //-------------------------------------------------------- + Check(gauge_renderer); + L4Warehouse + *warehouse = (L4Warehouse *) gauge_renderer->warehousePointer; + Check(warehouse); + + if (warehouse->bitMapBin.Get(parameterList[3].data.string) == NULL) + { + Test_Tell("NumericDisplaySpeed::Missing font\n"); + Check_Fpu(); + return False; + } + else + { + warehouse->bitMapBin.Release(parameterList[3].data.string); + } + //-------------------------------------------------------- + // Everything's ok + //-------------------------------------------------------- + Test_Tell("NumericDisplaySpeed::Make OK\n"); + Check_Fpu(); + return True; +} + +NumericDisplaySpeed::NumericDisplaySpeed( + GaugeRate rate, + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, int right, int top, + const char *font_name, + int number_of_digits, + NumericDisplay::NumericFormat requested_format, + int background_color, int foreground_color, + Scalar *value_pointer +): + NumericDisplayScalar( + rate, + mode_mask, + renderer, + owner_ID, + graphics_port_number, + left, bottom, right, top, + font_name, + number_of_digits, + requested_format, + background_color, foreground_color, + value_pointer + ) +{ + Check_Fpu(); +} + +void + NumericDisplaySpeed::Execute() +{ + Check(this); + + Scalar + value = currentValue*(Scalar)3.6; + + Check(numericDisplay); + numericDisplay->Draw(&localView, fabs(value)); + Check_Fpu(); +} + +//########################################################################### +// NumericDisplayInteger +//########################################################################### +MethodDescription + NumericDisplayInteger::methodDescription = + { + "numericInteger", + NumericDisplayInteger::Make, + { + { ParameterDescription::typeRate, NULL }, // rate ID + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeVector, NULL }, // size + { ParameterDescription::typeString, NULL }, // font name + { ParameterDescription::typeInteger, NULL }, // # of digits + { ParameterDescription::typeString, NULL }, // format + { ParameterDescription::typeColor, NULL }, // background + { ParameterDescription::typeColor, NULL }, // foreground + { ParameterDescription::typeAttribute, NULL }, // attribute + PARAMETER_DESCRIPTION_END + } + }; + +Logical + NumericDisplayInteger::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeRate); // rate ID + parameterList[1].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[2].CheckIt(ParameterDescription::typeVector); // size + parameterList[3].CheckIt(ParameterDescription::typeString); // font + parameterList[4].CheckIt(ParameterDescription::typeInteger); // # of digs + parameterList[5].CheckIt(ParameterDescription::typeString); // format + parameterList[6].CheckIt(ParameterDescription::typeColor); // background + parameterList[7].CheckIt(ParameterDescription::typeColor); // foreground + parameterList[8].CheckIt(ParameterDescription::typeAttribute); // value name +# endif + + Test_Tell("NumericDisplayInteger::Make\n"); + + int + number_format = configureFormat[0].Search( + parameterList[5].data.string + ); + + if (number_format < 0) + { + Test_Tell("NumericDisplayInteger::Make format NOT FOUND\n"); + Check_Fpu(); + return False; + } + +# if DEBUG_LEVEL > 0 + NumericDisplayInteger + *numeric_display = +# endif + new NumericDisplayInteger( + parameterList[0].data.rate, + parameterList[1].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, //unsigned int owner_ID + display_port_index, //int graphics_port_number + position.x, position.y, + position.x + parameterList[2].data.vector.x, + position.y + parameterList[2].data.vector.y, + parameterList[3].data.string, //font name + parameterList[4].data.integer, //int number_of_chars + (NumericDisplay::NumericFormat) number_format, + parameterList[6].data.integer, //int background_color + parameterList[7].data.integer, //int foreground_color + (int *) parameterList[8].data.attributePointer + + // HACK!!!! The (int *) is VERY dangerous! + ); + Register_Object(numeric_display); + + //-------------------------------------------------------- + // Make sure the font was properly placed in the warehouse + //-------------------------------------------------------- + Check(gauge_renderer); + L4Warehouse + *warehouse = (L4Warehouse *) gauge_renderer->warehousePointer; + Check(warehouse); + + if (warehouse->bitMapBin.Get(parameterList[3].data.string) == NULL) + { + Test_Tell("NumericDisplayInteger::Missing font\n"); + Check_Fpu(); + return False; + } + else + { + warehouse->bitMapBin.Release(parameterList[3].data.string); + } + //-------------------------------------------------------- + // Everything's ok + //-------------------------------------------------------- + Test_Tell("NumericDisplayInteger::Make OK\n"); + Check_Fpu(); + return True; +} + +NumericDisplayInteger::NumericDisplayInteger( + GaugeRate rate, + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, int right, int top, + const char *font_name, + int number_of_digits, + NumericDisplay::NumericFormat requested_format, + int background_color, int foreground_color, + int *value_pointer, + const char *identification_string +): + GraphicGauge( + rate, + mode_mask, + renderer, + owner_ID, + graphics_port_number, + identification_string + ) +{ + Check_Pointer(this); + // graphics_port may be NULL! + Check_Pointer(value_pointer); + Check(renderer); + //----------------------------------------------------------- + // Set internal values + //----------------------------------------------------------- + numericDisplay = new NumericDisplay( + (L4Warehouse *) renderer->warehousePointer, + 0,0, + font_name, + number_of_digits, + requested_format, + background_color, + foreground_color + ); + Register_Object(numericDisplay); + + localView.SetPositionWithinPort(left, bottom, right, top); + //----------------------------------------------------------- + // Build connection to value + //----------------------------------------------------------- + GaugeConnection + *connection; + + connection = new + GaugeConnectionDirectOf(0, ¤tValue, value_pointer); + Register_Object(connection); + AddConnection(connection); + Check_Fpu(); +} + +NumericDisplayInteger::~NumericDisplayInteger() +{ + Check(this); + + if (numericDisplay != NULL) + { + Unregister_Object(numericDisplay); + delete numericDisplay; + numericDisplay = NULL; + } + + // base class deletes all connections in Gauge::~Gauge + Check_Fpu(); +} + +Logical + NumericDisplayInteger::TestInstance() const +{ + return GraphicGauge::TestInstance(); +} + +void + NumericDisplayInteger::ShowInstance(char *indent) +{ + Check(this); + + cout << indent << "NumericDisplayInteger:\n"; + + char + temp[80]; + + Str_Copy(temp,indent, 80); + Str_Cat(temp,"...", 80); + + GraphicGauge::ShowInstance(temp); + Check(numericDisplay); + numericDisplay->ShowInstance(temp); + Check_Fpu(); +} + +void + NumericDisplayInteger::BecameActive() +{ + Check(this); + Check(numericDisplay); + numericDisplay->ForceUpdate(); + Check_Fpu(); +} + +void + NumericDisplayInteger::SetColors(int bg_color, int fg_color) +{ + Check(this); + numericDisplay->SetColors(bg_color, fg_color); + Check_Fpu(); +} + +void + NumericDisplayInteger::Execute() +{ + Check(this); + Check(numericDisplay); + numericDisplay->Draw(&localView, (Scalar) currentValue); + Check_Fpu(); +} + +//########################################################################### +// DigitalClock +//########################################################################### +MethodDescription + DigitalClock::methodDescription = + { + "digitalClock", + DigitalClock::Make, + { + { ParameterDescription::typeRate, NULL }, // rate ID + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeVector, NULL }, // size + { ParameterDescription::typeString, NULL }, // font name + { ParameterDescription::typeInteger, NULL }, // # of digits + { ParameterDescription::typeString, NULL }, // format + { ParameterDescription::typeColor, NULL }, // background + { ParameterDescription::typeColor, NULL }, // foreground + //{ ParameterDescription::typeEmpty, NULL }, + { ParameterDescription::typeEmpty, NULL } + } + }; + +Logical + DigitalClock::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeRate); // rate ID + parameterList[1].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[2].CheckIt(ParameterDescription::typeVector); // size + parameterList[3].CheckIt(ParameterDescription::typeString); // font name + parameterList[4].CheckIt(ParameterDescription::typeInteger); // # of digs + parameterList[5].CheckIt(ParameterDescription::typeString); // format + parameterList[6].CheckIt(ParameterDescription::typeColor); // background + parameterList[7].CheckIt(ParameterDescription::typeColor); // foreground +# endif + + Test_Tell("DigitalClock::Make\n"); + + int + number_format = configureFormat[0].Search( + parameterList[5].data.string + ); + + if (number_format < 0) + { + Test_Tell("DigitalClock::Make format NOT FOUND\n"); + Check_Fpu(); + return False; + } + +# if DEBUG_LEVEL > 0 + DigitalClock + *digital_clock = +# endif + new DigitalClock( + parameterList[0].data.rate, + parameterList[1].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, //unsigned int owner_ID + display_port_index, //int graphics_port_number + position.x, position.y, + position.x + parameterList[2].data.vector.x, + position.y + parameterList[2].data.vector.y, + parameterList[3].data.string, //font name + parameterList[4].data.integer, //int number_of_chars + (NumericDisplay::NumericFormat) number_format, + parameterList[6].data.integer, //int background_color + parameterList[7].data.integer //int foreground_color + ); + + Register_Object(digital_clock); + + //-------------------------------------------------------- + // Make sure the font was properly placed in the warehouse + //-------------------------------------------------------- + Check(gauge_renderer); + L4Warehouse + *warehouse = (L4Warehouse *) gauge_renderer->warehousePointer; + Check(warehouse); + + if (warehouse->bitMapBin.Get(parameterList[3].data.string) == NULL) + { + Test_Tell("DigitalClock::Missing font\n"); + Check_Fpu(); + return False; + } + else + { + warehouse->bitMapBin.Release(parameterList[3].data.string); + } + //-------------------------------------------------------- + // Everything's ok + //-------------------------------------------------------- + Test_Tell("DigitalClock::Make OK\n"); + Check_Fpu(); + return True; +} + +DigitalClock::DigitalClock( + GaugeRate rate, + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, int right, int top, + const char *font_name, + int number_of_digits, + NumericDisplay::NumericFormat requested_format, + int background_color, int foreground_color, + const char *identification_string +): + GraphicGauge( + rate, + mode_mask, + renderer, + owner_ID, + graphics_port_number, + identification_string + ) +{ + Check_Pointer(this); + // graphics_port may be NULL! + Check(renderer); + + Verify((right - left - 1) >= 0); + Verify((top - bottom - 1) >= 0); + // + //----------------------------------------------------------- + // Set internal values + //----------------------------------------------------------- + // + numericDisplay = new NumericDisplay( + (L4Warehouse *) renderer->warehousePointer, + 0,0, + font_name, + number_of_digits, + requested_format, + background_color, + foreground_color + ); + Register_Object(numericDisplay); + + localView.SetPositionWithinPort(left, bottom, right, top); + + Check_Fpu(); +} + +DigitalClock::~DigitalClock() +{ + Check(this); + + if (numericDisplay != NULL) + { + Unregister_Object(numericDisplay); + delete numericDisplay; + numericDisplay = NULL; + } + Check_Fpu(); +} + +Logical + DigitalClock::TestInstance() const +{ + return GraphicGauge::TestInstance(); +} + +void + DigitalClock::ShowInstance(char *indent) +{ + Check(this); + + cout << indent << "DigitalClock:\n"; + + char + temp[80]; + + Str_Copy(temp,indent, 80); + Str_Cat(temp,"...", 80); + + cout << temp << "numericDisplay=" << numericDisplay << "\n"; + Gauge::ShowInstance(temp); + Check(numericDisplay); + numericDisplay->ShowInstance(temp); + Check_Fpu(); +} + +void + DigitalClock::BecameActive() +{ + Check(this); + Check(numericDisplay); + numericDisplay->ForceUpdate(); + Check_Fpu(); +} + +void + DigitalClock::Execute() +{ + Check(this); + Check(numericDisplay); + Check(application); + + // HACK!!! + // Something subtle and mysterious is happening here... + //...and ONLY in the OPT version (which won't show source in the debugger!) + // + // If I try to fold the 'GetSecondsRemainingInGame()' call + // into the 'Draw' method, the clock will show an extra + // 60 seconds in the game! + // Perhaps some invisible type conversion is occurring. + + Scalar + seconds_remaining = application->GetSecondsRemainingInGame(); + numericDisplay->Draw(&localView, seconds_remaining); + Check_Fpu(); +} + + +//########################################################################### +// BackgroundConfig +//########################################################################### +Logical + MakeConfig( + int /*display_port_index*/, + Vector2DOf /*position*/, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = MakeConfigMethodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeInteger);// port + parameterList[1].CheckIt(ParameterDescription::typeString); // name + parameterList[2].CheckIt(ParameterDescription::typeInteger);// rotation + parameterList[3].CheckIt(ParameterDescription::typeInteger);// bits + parameterList[4].CheckIt(ParameterDescription::typeString); // palette ID + parameterList[5].CheckIt(ParameterDescription::typeString); // channel ID + parameterList[6].CheckIt(ParameterDescription::typeString); // palette name +# endif + + Test_Tell("BackgroundConfig::Make\n"); + + char + *palette_type = parameterList[4].data.string, + *enable_type = parameterList[5].data.string, + *palette_name = parameterList[6].data.string; + + //------------------------------------------------- + // Get palette ID type + //------------------------------------------------- + int + palette_ID = configurePalettes[0].Search(palette_type); + + if (palette_ID < 0) + { + DEBUG_STREAM << + "configure palette_ID '" << palette_type << "' NOT FOUND\n"; + return False; + } + + //------------------------------------------------- + // Get channel enable type + //------------------------------------------------- + int + enable_ID = configureChannels[0].Search(enable_type); + + if (enable_ID < 0) + { + DEBUG_STREAM << + "configure enable_ID '" << enable_type << "' NOT FOUND\n"; + return False; + } + + int + port_number = parameterList[0].data.integer; + const char + *port_name = parameterList[1].data.string; + int + rotation = parameterList[2].data.integer; + int + new_bits = parameterList[3].data.integer; + + Logical + ignore_palette_flag = (stricmp(palette_name, "NULL") == 0); + //------------------------------------------------------------ + // Get, lock pixelmap from warehouse + //------------------------------------------------------------ + //Check(renderer); + L4Warehouse + *warehouse = (L4Warehouse *) gauge_renderer->warehousePointer; + Check(warehouse); + + Palette8 + *palette; + + if (ignore_palette_flag) + { + palette = NULL; + } + else + { + palette = warehouse->palette8Bin.Get(palette_name); + if (palette == NULL) + { + DEBUG_STREAM << + "MakeConfig missing palette '" << palette_name << "'\n"; + Check_Fpu(); + return False; + } + Check(palette); + } + //------------------------------------------------- + // Build the port + //------------------------------------------------- + //Check(renderer); + ((L4GaugeRenderer *)gauge_renderer)->BuildGraphicsPort( + port_number, + port_name, + rotation, + new_bits, + (SVGA16::PaletteID) palette_ID, + (L4GraphicsPort::ChannelEnableID) enable_ID, + palette + ); + //------------------------------------------------- + // Release the palette (we're done with it) + //------------------------------------------------- + if (!ignore_palette_flag) + { + warehouse->palette8Bin.Release(palette_name); + } + + //-------------------------------------------------------- + // Everything's ok + //-------------------------------------------------------- + Test_Tell("MakeConfig OK\n"); + Check_Fpu(); + return True; +} + +MethodDescription + MakeConfigMethodDescription = + { + "configure", + MakeConfig, + { + { ParameterDescription::typeInteger, NULL }, // graphicsPort # + { ParameterDescription::typeString, NULL }, // name + { ParameterDescription::typeInteger, NULL }, // rotation + { ParameterDescription::typeInteger, NULL }, // bits + { ParameterDescription::typeString, NULL }, // palette ID + { ParameterDescription::typeString, NULL }, // channel ID + { ParameterDescription::typeString, NULL }, // palette name + PARAMETER_DESCRIPTION_END + } + }; + +//########################################################################### +// MakeExternConfig +//########################################################################### +Logical + MakeExternConfig( + int /*display_port_index*/, + Vector2DOf /*position*/, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = MakeExternConfigMethodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeInteger);// port # + parameterList[1].CheckIt(ParameterDescription::typeString); // name + parameterList[2].CheckIt(ParameterDescription::typeInteger);// bits +# endif + + Test_Tell("MakeExternConfig\n"); + + //------------------------------------------------- + // Build the port + //------------------------------------------------- + //Check(renderer); + ((L4GaugeRenderer *)gauge_renderer)->BuildExternalGraphicsPort( + parameterList[0].data.integer, // int port_number, + parameterList[1].data.string, // const char *name, + parameterList[2].data.integer // int bitAllocation + ); + + //-------------------------------------------------------- + // Everything's ok + //-------------------------------------------------------- + Test_Tell("MakeExternConfig OK\n"); + Check_Fpu(); + return True; +} + +MethodDescription + MakeExternConfigMethodDescription = + { + "externalConfigure", + MakeExternConfig, + { + { ParameterDescription::typeInteger, NULL }, // graphicsPort # + { ParameterDescription::typeString, NULL }, // name + { ParameterDescription::typeInteger, NULL }, // bits + PARAMETER_DESCRIPTION_END + } + }; + +//########################################################################### +// BackgroundReconfig +//########################################################################### +MethodDescription + BackgroundReconfig::methodDescription = + { + "reconfigure", + BackgroundReconfig::Make, + { + { ParameterDescription::typeModeMask, NULL },// mode mask + { ParameterDescription::typeInteger, NULL }, // graphicsPort # + { ParameterDescription::typeString, NULL }, // palette ID + { ParameterDescription::typeString, NULL }, // channel ID + { ParameterDescription::typeString, NULL }, // palette + PARAMETER_DESCRIPTION_END + } + }; + +Logical + BackgroundReconfig::Make( + int /*display_port_index*/, + Vector2DOf /*position*/, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeModeMask);// mode mask + parameterList[1].CheckIt(ParameterDescription::typeInteger);// port # + parameterList[2].CheckIt(ParameterDescription::typeString); // palette ID + parameterList[3].CheckIt(ParameterDescription::typeString); // channel ID + parameterList[4].CheckIt(ParameterDescription::typeString); // palette name +# endif + + Test_Tell("BackgroundReconfig::Make\n"); + + char + *palette_type = parameterList[2].data.string, + *enable_type = parameterList[3].data.string, + *palette_name = parameterList[4].data.string; + + //------------------------------------------------- + // Get palette ID type + //------------------------------------------------- + int + palette_ID = configurePalettes[0].Search(palette_type); + + if (palette_ID < 0) + { + DEBUG_STREAM << + "reconfigure palette_ID '" << palette_type << "' NOT FOUND\n"; + return False; + } + + //------------------------------------------------- + // Get channel enable type + //------------------------------------------------- + int + enable_ID = configureChannels[0].Search(enable_type); + + if (enable_ID < 0) + { + DEBUG_STREAM << + "reconfigure enable_ID '" << enable_type << "' NOT FOUND\n"; + return False; + } + + //------------------------------------------------- + // Create object + //------------------------------------------------- + BackgroundReconfig + *bg = + new BackgroundReconfig( + parameterList[0].data.modeMask, // mode mask + (L4GaugeRenderer *) gauge_renderer, + parameterList[1].data.integer, // port # + palette_ID, + enable_ID, + palette_name // palette name + ); + + Register_Object(bg); + + //----------------------------------------------------------- + // Make sure the palette was properly placed in the warehouse + //----------------------------------------------------------- + if (!bg->ignorePaletteFlag) + { + Check(gauge_renderer); + L4Warehouse + *warehouse = (L4Warehouse *) gauge_renderer->warehousePointer; + Check(warehouse); + + if (warehouse->bitMapBin.Get(palette_name) == NULL) + { + DEBUG_STREAM << + "BackgroundReconfig missing palette '" << palette_name << "'\n"; + Check_Fpu(); + return False; + } + else + { + warehouse->bitMapBin.Release(palette_name); + } + } + //-------------------------------------------------------- + // Everything's ok + //-------------------------------------------------------- + Test_Tell("BackgroundReconfig::Make OK\n"); + Check_Fpu(); + return True; +} + +BackgroundReconfig::BackgroundReconfig( + ModeMask mode_mask, + L4GaugeRenderer *renderer, + int port_number, + int palette_ID, + int enable_ID, + const char *palette_name, + const char *identification_string +): + GaugeBackground( + mode_mask, + renderer, + 0, + identification_string + ) +{ + portNumber = port_number; + paletteID = palette_ID; + enableID = enable_ID; + paletteName = nameCopy(palette_name); + ignorePaletteFlag = (stricmp(paletteName, "NULL") == 0); + + //---------------------------------------------------------- + // Preload the palette + //---------------------------------------------------------- +# if defined(PRELOAD_ART) + if (!ignorePaletteFlag) + { + Check(renderer); + L4Warehouse + *warehouse = (L4Warehouse *) renderer->warehousePointer; + Check(warehouse); + + warehouse->palette8Bin.Get(paletteName); + } +# endif + + Check_Fpu(); +} + +BackgroundReconfig::~BackgroundReconfig() +{ + Check(this); + //------------------------------------------------------------ + // Unlock preloaded art + //------------------------------------------------------------ +# if defined(PRELOAD_ART) + if (!ignorePaletteFlag) + { + Check(renderer); + L4Warehouse + *warehouse = (L4Warehouse *) renderer->warehousePointer; + Check(warehouse); + + warehouse->palette8Bin.Release(paletteName); + } +# endif + //------------------------------------------------------------ + // Delete the names + //------------------------------------------------------------ + Unregister_Pointer(paletteName); + delete[] paletteName; + paletteName = NULL; + + Check_Fpu(); +} + +void + BackgroundReconfig::BecameActive() +{ + Check(this); + //------------------------------------------------------------ + // Get, lock pixelmap from warehouse + //------------------------------------------------------------ + Check(renderer); + L4Warehouse + *warehouse = (L4Warehouse *) renderer->warehousePointer; + Check(warehouse); + + Palette8 + *palette; + + if (ignorePaletteFlag) + { + palette = NULL; + } + else + { + palette = warehouse->palette8Bin.Get(paletteName); + Check(palette); + } + //------------------------------------------------- + // Remap the port + //------------------------------------------------- + Check(renderer); + ((L4GaugeRenderer *)renderer)->RemapGraphicsPort( + portNumber, // int port_number, + (SVGA16::PaletteID) paletteID, + (L4GraphicsPort::ChannelEnableID) enableID, + palette + ); + //------------------------------------------------- + // Release the palette (we're done with it) + //------------------------------------------------- + if (!ignorePaletteFlag) + { + warehouse->palette8Bin.Release(paletteName); + } + Check_Fpu(); +} + +//########################################################################### +// BackgroundLine +//########################################################################### +MethodDescription + BackgroundLine::methodDescription = + { + "bgLine", + BackgroundLine::Make, + { + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeInteger, NULL }, // 1=thick + { ParameterDescription::typeVector, NULL }, // size + { ParameterDescription::typeColor, NULL }, // color + PARAMETER_DESCRIPTION_END + } + }; + +Logical + BackgroundLine::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[1].CheckIt(ParameterDescription::typeInteger); // thick + parameterList[2].CheckIt(ParameterDescription::typeVector); // size + parameterList[3].CheckIt(ParameterDescription::typeColor); // color +# endif + + Test_Tell("BackgroundLine::Make\n"); + +# if DEBUG_LEVEL > 0 + BackgroundLine + *bg = +# endif + new BackgroundLine( + parameterList[0].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, //unsigned int owner_ID + display_port_index, //int graphics_port_number + parameterList[1].data.integer, // thick + position.x, position.y, + position.x + parameterList[2].data.vector.x, + position.y + parameterList[2].data.vector.y, + parameterList[3].data.color + ); + + Register_Object(bg); + + //-------------------------------------------------------- + // Everything's ok + //-------------------------------------------------------- + Test_Tell("BackgroundLine::Make OK\n"); + Check_Fpu(); + return True; +} + +BackgroundLine::BackgroundLine( + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int thick_flag, + int left, int bottom, int right, int top, + int color, + const char *identification_string +): + GraphicGaugeBackground( + mode_mask, + renderer, + owner_ID, + graphics_port_number, + identification_string + ) +{ + + endpoints.bottomLeft.x = left; + endpoints.bottomLeft.y = bottom; + endpoints.topRight.x = right; + endpoints.topRight.y = top; + + thickFlag = thick_flag; + + localView.SetColor(color); + Check_Fpu(); +} + +void + BackgroundLine::BecameActive() +{ + Check(this); + //--------------------------------------------- + // Draw it + //--------------------------------------------- + localView.MoveToAbsolute(endpoints.bottomLeft.x, endpoints.bottomLeft.y); + + if (thickFlag) + { + localView.DrawThickLineToAbsolute( + endpoints.topRight.x, endpoints.topRight.y + ); + } + else + { + localView.DrawLineToAbsolute( + endpoints.topRight.x, endpoints.topRight.y + ); + } + Check_Fpu(); +} + +//########################################################################### +// BackgroundRect +//########################################################################### +MethodDescription + BackgroundRect::methodDescription = + { + "bgRect", + BackgroundRect::Make, + { + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeVector, NULL }, // size + { ParameterDescription::typeColor, NULL }, // color + PARAMETER_DESCRIPTION_END + } + }; + +Logical + BackgroundRect::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[1].CheckIt(ParameterDescription::typeVector); // size + parameterList[2].CheckIt(ParameterDescription::typeColor); // color +# endif + + Test_Tell("BackgroundRect::Make\n"); + +# if DEBUG_LEVEL > 0 + BackgroundRect + *bg = +# endif + new BackgroundRect( + parameterList[0].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, //unsigned int owner_ID + display_port_index, //int graphics_port_number + position.x, position.y, + position.x + parameterList[1].data.vector.x, + position.y + parameterList[1].data.vector.y, + parameterList[2].data.color + ); + + Register_Object(bg); + + //-------------------------------------------------------- + // Everything's ok + //-------------------------------------------------------- + Test_Tell("BackgroundRect::Make OK\n"); + Check_Fpu(); + return True; +} + +BackgroundRect::BackgroundRect( + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, int top, int right, + int color, + const char *identification_string +): + GraphicGaugeBackground( + mode_mask, + renderer, + owner_ID, + graphics_port_number, + identification_string + ) +{ + + endpoints.bottomLeft.x = left; + endpoints.bottomLeft.y = bottom; + endpoints.topRight.x = right; + endpoints.topRight.y = top; + + localView.SetColor(color); + Check_Fpu(); +} + +void + BackgroundRect::BecameActive() +{ + Check(this); + //--------------------------------------------- + // Draw it + //--------------------------------------------- + localView.MoveToAbsolute( + endpoints.bottomLeft.x, endpoints.bottomLeft.y + ); + localView.DrawRectangleToAbsolute( + endpoints.topRight.x, endpoints.topRight.y + ); + Check_Fpu(); +} + +//########################################################################### +// BackgroundFilledRect +//########################################################################### +MethodDescription + BackgroundFilledRect::methodDescription = + { + "bgFilledRect", + BackgroundFilledRect::Make, + { + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeVector, NULL }, // size + { ParameterDescription::typeColor, NULL }, // color + PARAMETER_DESCRIPTION_END + } + }; + +Logical + BackgroundFilledRect::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[1].CheckIt(ParameterDescription::typeVector); // size + parameterList[2].CheckIt(ParameterDescription::typeColor); // color +# endif + + Test_Tell("BackgroundFilledRect::Make\n"); + + BackgroundFilledRect + *bg = + new BackgroundFilledRect( + parameterList[0].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, //unsigned int owner_ID + display_port_index, //int graphics_port_number + position.x, position.y, + position.x + parameterList[1].data.vector.x, + position.y + parameterList[1].data.vector.y, + parameterList[2].data.color + ); + + Register_Object(bg); + + //--------------------------------------------------------------- + // Everything's ok: if 'always active', run once and then kill it + //--------------------------------------------------------------- + if ( + parameterList[0].data.modeMask == + (ModeMask) ModeManager::ModeAlwaysActive + ) + { + bg->BecameActive(); + + Unregister_Object(bg); + delete bg; + } + Test_Tell("BackgroundFilledRect::Make OK\n"); + Check_Fpu(); + return True; +} + +BackgroundFilledRect::BackgroundFilledRect( + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, int top, int right, + int color, + const char *identification_string +): + GraphicGaugeBackground( + mode_mask, + renderer, + owner_ID, + graphics_port_number, + identification_string + ) +{ + + endpoints.bottomLeft.x = left; + endpoints.bottomLeft.y = bottom; + endpoints.topRight.x = right; + endpoints.topRight.y = top; + + localView.SetColor(color); + Check_Fpu(); +} + +void + BackgroundFilledRect::BecameActive() +{ + Check(this); + //--------------------------------------------- + // Draw it + //--------------------------------------------- + localView.MoveToAbsolute( + endpoints.bottomLeft.x, endpoints.bottomLeft.y + ); + localView.DrawFilledRectangleToAbsolute( + endpoints.topRight.x, endpoints.topRight.y + ); + Check_Fpu(); +} + +//########################################################################### +// BackgroundPixelMap +//########################################################################### +MethodDescription + BackgroundPixelmap::methodDescription = + { + "bgPixelMap", + BackgroundPixelmap::Make, + { + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeString, NULL }, // pixelmap name + { ParameterDescription::typeInteger, NULL }, // 1=opaque + PARAMETER_DESCRIPTION_END + } + }; + +Logical + BackgroundPixelmap::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[1].CheckIt(ParameterDescription::typeString); // map name + parameterList[2].CheckIt(ParameterDescription::typeInteger); // opaque +# endif + + Test_Tell("BackgroundPixelmap::Make\n"); + + const char + *name = parameterList[1].data.string; + + BackgroundPixelmap + *bg = + new BackgroundPixelmap( + parameterList[0].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, //unsigned int owner_ID + display_port_index, //int graphics_port_number + position.x, position.y, + name, //font name + parameterList[2].data.integer + ); + + Register_Object(bg); + + //-------------------------------------------------------- + // Make sure the map was properly placed in the warehouse + //-------------------------------------------------------- + Check(gauge_renderer); + L4Warehouse + *warehouse = (L4Warehouse *) gauge_renderer->warehousePointer; + Check(warehouse); + + if (warehouse->pixelMap8Bin.Get(name) == NULL) + { + DEBUG_STREAM << + "BackgroundPixelmap::Missing image '" << name << "\n"; + Check_Fpu(); + return False; + } + else + { + warehouse->pixelMap8Bin.Release(name); + } + + //--------------------------------------------------------------- + // Everything's ok: if 'always active', run once and then kill it + //--------------------------------------------------------------- + if ( + parameterList[0].data.modeMask == + (ModeMask) ModeManager::ModeAlwaysActive + ) + { + bg->BecameActive(); + + Unregister_Object(bg); + delete bg; + } + Test_Tell("BackgroundPixelmap::Make OK\n"); + Check_Fpu(); + return True; +} + +BackgroundPixelmap::BackgroundPixelmap( + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, + const char *pixelmap_name, + int opaque_flag, + const char *identification_string +): + GraphicGaugeBackground( + mode_mask, + renderer, + owner_ID, + graphics_port_number, + identification_string + ) +{ + //------------------------------------------------------------ + // Save the map name + //------------------------------------------------------------ + pixelMapName = nameCopy(pixelmap_name); + opaqueFlag = opaque_flag; + //------------------------------------------------------------ + // Set origin + //------------------------------------------------------------ + localView.SetOrigin(left, bottom); + //------------------------------------------------------------ + // Order the font from the warehouse (pre-load for future use) + //------------------------------------------------------------ +# if defined(PRELOAD_ART) + Check(renderer); + L4Warehouse + *warehouse = (L4Warehouse *) renderer->warehousePointer; + Check(warehouse); + + Check_Pointer(pixelMapName); + warehouse->pixelMap8Bin.Get(pixelMapName); +# endif + + Check_Fpu(); +} + +BackgroundPixelmap::~BackgroundPixelmap() +{ + Check(this); + //------------------------------------------------------------ + // Unlock preloaded art + //------------------------------------------------------------ +# if defined(PRELOAD_ART) + Check(renderer); + L4Warehouse + *warehouse = (L4Warehouse *) renderer->warehousePointer; + Check(warehouse); + + Check_Pointer(pixelMapName); + warehouse->pixelMap8Bin.Release(pixelMapName); +# endif + //------------------------------------------------------------ + // Delete the map name + //------------------------------------------------------------ + Unregister_Pointer(pixelMapName); + delete[] pixelMapName; + pixelMapName = NULL; + + Check_Fpu(); +} + +Logical + BackgroundPixelmap::TestInstance() const +{ + Check_Pointer(pixelMapName); + return GraphicGaugeBackground::TestInstance(); +} + +void + BackgroundPixelmap::BecameActive() +{ + Check(this); + //--------------------------------------------- + // Get the image + //--------------------------------------------- + Check(renderer); + L4Warehouse + *warehouse = (L4Warehouse *) renderer->warehousePointer; + Check(warehouse); + + PixelMap8 + *map = warehouse->pixelMap8Bin.Get(pixelMapName); + + //--------------------------------------------- + // Draw it + //--------------------------------------------- + if (map != NULL) + { + Check(map); + localView.MoveToAbsolute(0,0); + localView.DrawPixelMap8(opaqueFlag, 0, map); + } + //--------------------------------------------- + // Release the image + //--------------------------------------------- + Check(warehouse); + warehouse->pixelMap8Bin.Release(pixelMapName); + Check_Fpu(); +} + +//########################################################################### +// BackgroundBitMap +//########################################################################### +MethodDescription + BackgroundBitmap::methodDescription = + { + "bgBitMap", + BackgroundBitmap::Make, + { + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeString, NULL }, // bitmap name + { ParameterDescription::typeInteger, NULL }, // 1=opaque + { ParameterDescription::typeColor, NULL }, // fg color + { ParameterDescription::typeColor, NULL }, // bg color(opaque) + PARAMETER_DESCRIPTION_END + } + }; + +Logical + BackgroundBitmap::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[1].CheckIt(ParameterDescription::typeString); // map name + parameterList[2].CheckIt(ParameterDescription::typeInteger); // opaque + parameterList[3].CheckIt(ParameterDescription::typeColor); // fg color + parameterList[4].CheckIt(ParameterDescription::typeColor); // bg color +# endif + + Test_Tell("BackgroundBitMap::Make\n"); + + const char + *name = parameterList[1].data.string; + + BackgroundBitmap + *bg = + new BackgroundBitmap( + parameterList[0].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, //unsigned int owner_ID + display_port_index, //int graphics_port_number + position.x, position.y, + name, //font name + parameterList[2].data.integer, + parameterList[3].data.color, + parameterList[4].data.color + ); + + Register_Object(bg); + + //-------------------------------------------------------- + // Make sure the map was properly placed in the warehouse + //-------------------------------------------------------- + Check(gauge_renderer); + L4Warehouse + *warehouse = (L4Warehouse *) gauge_renderer->warehousePointer; + Check(warehouse); + + if (warehouse->bitMapBin.Get(name) == NULL) + { + DEBUG_STREAM << + "BackgroundBitmap::Missing image '" << name << "\n"; + Check_Fpu(); + return False; + } + else + { + warehouse->bitMapBin.Release(name); + } + + //--------------------------------------------------------------- + // Everything's ok: if 'always active', run once and then kill it + //--------------------------------------------------------------- + if ( + parameterList[0].data.modeMask == + (ModeMask) ModeManager::ModeAlwaysActive + ) + { + bg->BecameActive(); + + Unregister_Object(bg); + delete bg; + } + Test_Tell("BackgroundBitmap::Make OK\n"); + Check_Fpu(); + return True; +} + +BackgroundBitmap::BackgroundBitmap( + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, + const char *bitmap_name, + int opaque_flag, + int fg_color, + int bg_color, + const char *identification_string +): + GraphicGaugeBackground( + mode_mask, + renderer, + owner_ID, + graphics_port_number, + identification_string + ) +{ + //------------------------------------------------------------ + // Save the map name + //------------------------------------------------------------ + bitMapName = nameCopy(bitmap_name); + opaqueFlag = opaque_flag; + foregroundColor = fg_color; + backgroundColor = bg_color; + //------------------------------------------------------------ + // Set origin + //------------------------------------------------------------ + localView.SetOrigin(left, bottom); + //------------------------------------------------------------ + // Order the map from the warehouse (pre-load for future use) + //------------------------------------------------------------ +# if defined(PRELOAD_ART) + Check(renderer); + L4Warehouse + *warehouse = (L4Warehouse *) renderer->warehousePointer; + Check(warehouse); + + Check_Pointer(bitMapName); + warehouse->bitMapBin.Get(bitMapName); +# endif + + Check_Fpu(); +} + +BackgroundBitmap::~BackgroundBitmap() +{ + Check(this); + //------------------------------------------------------------ + // Unlock preloaded art + //------------------------------------------------------------ +# if defined(PRELOAD_ART) + Check(renderer); + L4Warehouse + *warehouse = (L4Warehouse *) renderer->warehousePointer; + Check(warehouse); + + Check_Pointer(bitMapName); + warehouse->bitMapBin.Release(bitMapName); +# endif + //------------------------------------------------------------ + // Delete the map name + //------------------------------------------------------------ + Unregister_Pointer(bitMapName); + delete[] bitMapName; + bitMapName = NULL; + + Check_Fpu(); +} + +Logical + BackgroundBitmap::TestInstance() const +{ + Check_Pointer(bitMapName); + return GraphicGaugeBackground::TestInstance(); +} + +void + BackgroundBitmap::BecameActive() +{ + Check(this); + //--------------------------------------------- + // Get the image + //--------------------------------------------- + Check(renderer); + L4Warehouse + *warehouse = (L4Warehouse *) renderer->warehousePointer; + Check(warehouse); + + BitMap + *map = warehouse->bitMapBin.Get(bitMapName); + + //--------------------------------------------- + // Draw it + //--------------------------------------------- + if (map != NULL) + { + Check(map); + localView.MoveToAbsolute(0,0); + localView.SetColor(foregroundColor); + + if (opaqueFlag) + { + localView.DrawBitMapOpaque(backgroundColor, 0, map); + } + else + { + localView.DrawBitMap(0, map); + } + } + //--------------------------------------------- + // Release the image + //--------------------------------------------- + Check(warehouse); + warehouse->pixelMap8Bin.Release(bitMapName); + Check_Fpu(); +} + +//########################################################################### +// RankAndScore +//########################################################################### + +#define RNSCHARWIDTH 6 +#define RNSCHARHEIGHT 8 +#define RNSSCOREDIGITS 8 +#define RNSRANK_X 2 +#define RNSLINE_X (RNSRANK_X+RNSCHARWIDTH+2) +#define RNSSCORE_X (RNSLINE_X+2) +#define RNS_Y 2 +#define RNSWIDTH (2+RNSCHARWIDTH+5+(RNSCHARWIDTH*RNSSCOREDIGITS)+2) +#define RNSHEIGHT (2+RNSCHARHEIGHT+2) + +MethodDescription + RankAndScore::methodDescription = + { + "rankAndScore", + RankAndScore::Make, + { + { ParameterDescription::typeRate, NULL }, // rate ID + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeString, NULL }, // font name + { ParameterDescription::typeColor, NULL }, // background + { ParameterDescription::typeColor, NULL }, // foreground + PARAMETER_DESCRIPTION_END + } + }; + +Logical + RankAndScore::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeRate); // rate ID + parameterList[1].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[2].CheckIt(ParameterDescription::typeString); // font + parameterList[3].CheckIt(ParameterDescription::typeColor); // background + parameterList[4].CheckIt(ParameterDescription::typeColor); // foreground +# endif + + Test_Tell("RankAndScore::Make\n"); + +# if DEBUG_LEVEL > 0 + RankAndScore + *rank_and_score = +# endif + new RankAndScore( + parameterList[0].data.rate, + parameterList[1].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, //unsigned int owner_ID + display_port_index, //int graphics_port_number + position.x, position.y, + parameterList[2].data.string, //font name + parameterList[3].data.integer, //int background_color + parameterList[4].data.integer //int foreground_color + ); + + Register_Object(rank_and_score); + + //-------------------------------------------------------- + // Make sure the font was properly placed in the warehouse + //-------------------------------------------------------- + Check(gauge_renderer); + L4Warehouse + *warehouse = (L4Warehouse *) gauge_renderer->warehousePointer; + Check(warehouse); + + if (warehouse->bitMapBin.Get(parameterList[2].data.string) == NULL) + { + Test_Tell("RankAndScore::Missing font\n"); + Check_Fpu(); + return False; + } + else + { + warehouse->bitMapBin.Release(parameterList[2].data.string); + } + //-------------------------------------------------------- + // Everything's ok + //-------------------------------------------------------- + Test_Tell("RankAndScore::Make OK\n"); + Check_Fpu(); + return True; +} + +RankAndScore::RankAndScore( + GaugeRate rate, + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, + const char *font_name, + int foreground_color, int background_color, + const char *identification_string +): + GraphicGauge( + rate, + mode_mask, + renderer, + owner_ID, + graphics_port_number, + identification_string + ) +{ + Check_Pointer(this); + Check(renderer); + // + //----------------------------------------------------------- + // Set internal values + //----------------------------------------------------------- + // + numericDisplayRank = new NumericDisplay( + (L4Warehouse *) renderer->warehousePointer, + RNSRANK_X,RNS_Y, + font_name, + 1, + NumericDisplay::unsignedFormat, + background_color, + foreground_color + ); + Register_Object(numericDisplayRank); + + numericDisplayScore = new NumericDisplay( + (L4Warehouse *) renderer->warehousePointer, + RNSSCORE_X,RNS_Y, + font_name, + RNSSCOREDIGITS, + NumericDisplay::signedBlankedZerosFormat, + background_color, + foreground_color + ); + Register_Object(numericDisplayScore); + + localView.SetPositionWithinPort( + left,bottom, + left+RNSWIDTH+1,bottom+RNSHEIGHT+1 + ); + + linkedEntity = NULL; + foregroundColor = foreground_color; + backgroundColor = background_color; + + Check_Fpu(); +} + +RankAndScore::~RankAndScore() +{ + Check(this); + + if (linkedEntity != NULL) + { + Player + *player; + + Check(linkedEntity); + player = linkedEntity->GetPlayerLink(); + Check(player); + //--------------------------------------- + // Truncate the score (no rounding) + //--------------------------------------- + DEBUG_STREAM << + "~RankAndScore: I think my score is " << + (int)(player->currentScore) << "\n"; + } + + if (numericDisplayRank != NULL) + { + Unregister_Object(numericDisplayRank); + delete numericDisplayRank; + numericDisplayRank = NULL; + } + if (numericDisplayScore != NULL) + { + Unregister_Object(numericDisplayScore); + delete numericDisplayScore; + numericDisplayScore = NULL; + } + + Check_Fpu(); +} + +Logical + RankAndScore::TestInstance() const +{ + return GraphicGauge::TestInstance(); +} + +void + RankAndScore::ShowInstance(char */*indent*/) +{ +} + +void + RankAndScore::BecameActive() +{ + Check(this); + + previousState = False; + + Check(numericDisplayRank); + Check(numericDisplayScore); + + numericDisplayRank->ForceUpdate(); + numericDisplayScore->ForceUpdate(); + + Check_Fpu(); +} + +void + RankAndScore::LinkToEntity(Entity *entity) +{ + Test_Tell("RankAndScore::LinkToEntity\n" << flush); + Check(this); + + linkedEntity = entity; + Check_Fpu(); +} + +void + RankAndScore::Execute() +{ + Check(this); + Check(numericDisplayRank); + Check(numericDisplayScore); + + Check(application); + Logical + currentState = + (application->GetApplicationState() == Application::RunningMission); + + if (previousState != currentState) + { + previousState = currentState; + + if (currentState == True) + { + //------------------------------------------- + // Draw background + //------------------------------------------- + localView.SetColor(backgroundColor); + localView.MoveToAbsolute(1,1); + localView.DrawFilledRectangleToAbsolute(RNSWIDTH-1,RNSHEIGHT-1); + + localView.SetColor(foregroundColor); + localView.MoveToAbsolute(0,0); + localView.DrawRectangleToAbsolute(RNSWIDTH,RNSHEIGHT); + localView.MoveToAbsolute(RNSLINE_X,0); + localView.DrawLineToAbsolute(RNSLINE_X,RNSHEIGHT); + } + } + + if (currentState == True) + { + //------------------------------------------- + // Get 'our' placement + //------------------------------------------- + if (linkedEntity != NULL) + { + Player + *player; + + Check(linkedEntity); + player = linkedEntity->GetPlayerLink(); + Check(player); + //--------------------------------------- + // Truncate the score (no rounding) + //--------------------------------------- + int + integer_score = (int)(player->currentScore); + //--------------------------------------- + // Update displays + //--------------------------------------- + numericDisplayRank->Draw( + &localView, + player->playerRanking+1 + ); + numericDisplayScore->Draw( + &localView, + (Scalar) integer_score + ); + } + } + Check_Fpu(); +} + +//########################################################################### +// WipeGaugeScalar +//########################################################################### +WipeGaugeScalar::WipeGaugeScalar( + GaugeRate rate, + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, int right, int top, + Direction direction, + Scalar min, + Scalar max, + const char *identification_string +): + GraphicGauge( + rate, + mode_mask, + renderer, + owner_ID, + graphics_port_number, + identification_string + ) +{ + Check_Pointer(this); + // graphics_port may be NULL! + // + //----------------------------------------------------------- + // Initialize internal values + //----------------------------------------------------------- + // + width = right - left - 1; + height = top - bottom - 1; + Verify(width >= 0); + Verify(height >= 0); + + previousValue = -1234; + previousSize.MakeEmpty(); + + wipeDirection = direction; + minimumValue = min; + maximumValue = max - min; + Verify(maximumValue != 0); + + localView.SetPositionWithinPort(left, bottom, right, top); + + Check_Fpu(); +} + + +WipeGaugeScalar::~WipeGaugeScalar() +{ + Check(this); + + // base class deletes all connections in Gauge::~Gauge + Check_Fpu(); +} + +Logical + WipeGaugeScalar::TestInstance() const +{ + return GraphicGauge::TestInstance(); +} + +void + WipeGaugeScalar::ShowInstance(char *indent) +{ + Check(this); + + cout << indent << "WipeGaugeScalar:\n"; + + char + temp[80]; + + Str_Copy(temp,indent, 80); + Str_Cat(temp,"...", 80); + + cout << temp << "previousSize =" << previousSize << "\n"; + GraphicGauge::ShowInstance(temp); + Check_Fpu(); +} + +void + WipeGaugeScalar::BecameActive() +{ + Check(this); + forceUpdateFlag = True; + Check_Fpu(); +} + +void + WipeGaugeScalar::Execute() +{ + Check(this); + + int + new_value; + + Scalar + q; + + Rectangle2D + rectangle; + + // + //----------------------------------------------------------- + // Calculate new_value + //----------------------------------------------------------- + // + if (currentValue < minimumValue) + { + currentValue = minimumValue; + } + + currentValue -= minimumValue; + + if (currentValue > maximumValue) + { + currentValue = maximumValue; + } + + Verify(maximumValue != 0); + q = currentValue / maximumValue; + + if (q > 1.0) + { + q = 1.0; + } + else if (q < -1.0) + { + q = -1.0; + } + // + //----------------------------------------------------------- + // Update display + //----------------------------------------------------------- + // + switch(wipeDirection) + { + case wipeLeft: + new_value = width - (int) (width*q + .5); + + if (forceUpdateFlag) + { + forceUpdateFlag = False; + + rectangle.topRight.x = width; + rectangle.topRight.y = height; + rectangle.bottomLeft.x = new_value; + rectangle.bottomLeft.y = 0; + + if (!rectangle.IsEmpty()) + { + DrawActive(&rectangle); + } + + rectangle.topRight.x = new_value-1; + rectangle.bottomLeft.x = 0; + + if (!rectangle.IsEmpty()) + { + DrawInactive(&rectangle); + } + previousValue = new_value; + } + else if (new_value > previousValue) + { + rectangle.topRight.x = new_value-1; + rectangle.topRight.y = height; + rectangle.bottomLeft.x = previousValue; + rectangle.bottomLeft.y = 0; + if (!rectangle.IsEmpty()) + { + DrawInactive(&rectangle); + } + previousValue = new_value; + } + else if (previousValue > new_value) + { + rectangle.topRight.x = previousValue-1; + rectangle.topRight.y = height; + rectangle.bottomLeft.x = new_value; + rectangle.bottomLeft.y = 0; + if (!rectangle.IsEmpty()) + { + DrawActive(&rectangle); + } + previousValue = new_value; + } + break; + + case wipeDown: + new_value = height - (int) (height*q + .5); + + if (forceUpdateFlag) + { + forceUpdateFlag = False; + + rectangle.topRight.x = width; + rectangle.topRight.y = height; + rectangle.bottomLeft.x = 0; + rectangle.bottomLeft.y = new_value; + + if (!rectangle.IsEmpty()) + { + DrawActive(&rectangle); + } + + rectangle.topRight.y = new_value-1; + rectangle.bottomLeft.y = 0; + + if (!rectangle.IsEmpty()) + { + DrawInactive(&rectangle); + } + previousValue = new_value; + } + else if (new_value > previousValue) + { + rectangle.topRight.x = width; + rectangle.topRight.y = new_value+1; + rectangle.bottomLeft.x = 0; + rectangle.bottomLeft.y = previousValue; + if (!rectangle.IsEmpty()) + { + DrawInactive(&rectangle); + } + previousValue = new_value; + } + else if (previousValue > new_value) + { + rectangle.topRight.x = width; + rectangle.topRight.y = previousValue+1; + rectangle.bottomLeft.x = 0; + rectangle.bottomLeft.y = new_value; + if (!rectangle.IsEmpty()) + { + DrawActive(&rectangle); + } + previousValue = new_value; + } + break; + + case wipeRight: + new_value = (int) (width*q + .5); + + if (forceUpdateFlag) + { + forceUpdateFlag = False; + + rectangle.topRight.x = new_value; + rectangle.topRight.y = height; + rectangle.bottomLeft.x = 0; + rectangle.bottomLeft.y = 0; + + if (!rectangle.IsEmpty()) + { + DrawActive(&rectangle); + } + + rectangle.topRight.x = width; + rectangle.bottomLeft.x = new_value+1; + + if (!rectangle.IsEmpty()) + { + DrawInactive(&rectangle); + } + previousValue = new_value; + } + else if (new_value > previousValue) + { + rectangle.topRight.x = new_value; + rectangle.topRight.y = height; + rectangle.bottomLeft.x = previousValue+1; + rectangle.bottomLeft.y = 0; + if (!rectangle.IsEmpty()) + { + DrawActive(&rectangle); + } + previousValue = new_value; + } + else if (previousValue > new_value) + { + rectangle.topRight.x = previousValue; + rectangle.topRight.y = height; + rectangle.bottomLeft.x = new_value+1; + rectangle.bottomLeft.y = 0; + if (!rectangle.IsEmpty()) + { + DrawInactive(&rectangle); + } + previousValue = new_value; + } + break; + + case wipeUp: + new_value = (int) (height*q + .5); + + if (forceUpdateFlag) + { + forceUpdateFlag = False; + + rectangle.topRight.x = width; + rectangle.topRight.y = new_value; + rectangle.bottomLeft.x = 0; + rectangle.bottomLeft.y = 0; + + if (!rectangle.IsEmpty()) + { + DrawActive(&rectangle); + } + + rectangle.topRight.y = height; + rectangle.bottomLeft.y = new_value+1; + + if (!rectangle.IsEmpty()) + { + DrawInactive(&rectangle); + } + previousValue = new_value; + } + else if (previousValue < new_value) + { + rectangle.topRight.x = width; + rectangle.topRight.y = new_value; + rectangle.bottomLeft.x = 0; + rectangle.bottomLeft.y = previousValue; + if (!rectangle.IsEmpty()) + { + DrawActive(&rectangle); + } + previousValue = new_value; + } + else if (previousValue > new_value) + { + rectangle.topRight.x = width; + rectangle.topRight.y = previousValue; + rectangle.bottomLeft.x = 0; + rectangle.bottomLeft.y = new_value; + if (!rectangle.IsEmpty()) + { + DrawInactive(&rectangle); + } + previousValue = new_value; + } + break; + } + Check_Fpu(); +} + +void + WipeGaugeScalar::DrawActive( + Rectangle2D */*rectangle*/ + ) +{ + Fail("WipeGaugeScalar::DrawActive is not overridden"); +} + +void + WipeGaugeScalar::DrawInactive( + Rectangle2D */*rectangle*/ + ) +{ + Fail("WipeGaugeScalar::DrawInactive is not overridden"); +} + +//########################################################################### +// BarGraphSolidScalar +//########################################################################### +MethodDescription + BarGraphSolidScalar::methodDescription = + { + "solidbar", + BarGraphSolidScalar::Make, + { + { ParameterDescription::typeRate, NULL }, // rate ID + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeVector, NULL }, // size + { ParameterDescription::typeColor, NULL }, // foreground + { ParameterDescription::typeColor, NULL }, // background + { ParameterDescription::typeString, NULL }, // direction + { ParameterDescription::typeScalar, NULL }, // min + { ParameterDescription::typeScalar, NULL }, // max + { ParameterDescription::typeAttribute, NULL }, // attribute + PARAMETER_DESCRIPTION_END + } + }; + +Logical + BarGraphSolidScalar::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeRate); // rate ID + parameterList[1].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[2].CheckIt(ParameterDescription::typeVector); // size + parameterList[3].CheckIt(ParameterDescription::typeColor); // foreground + parameterList[4].CheckIt(ParameterDescription::typeColor); // background + parameterList[5].CheckIt(ParameterDescription::typeString); // direction + parameterList[6].CheckIt(ParameterDescription::typeScalar); // min + parameterList[7].CheckIt(ParameterDescription::typeScalar); // max + parameterList[8].CheckIt(ParameterDescription::typeAttribute); // attribute +# endif + + Test_Tell("BarGraphSolidScalar::Make\n"); + + int + direction = configureDirection[0].Search( + parameterList[5].data.string + ); + + if (direction < 0) + { + Test_Tell("BarGraphSolidScalar::Make direction NOT FOUND\n"); + Check_Fpu(); + return False; + } + +# if DEBUG_LEVEL > 0 + BarGraphSolidScalar + *bar_graph = +# endif + new BarGraphSolidScalar( + parameterList[0].data.rate, + parameterList[1].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, // unsigned int owner_ID + display_port_index, // int graphics_port_number + position.x, position.y, + position.x + parameterList[2].data.vector.x, + position.y + parameterList[2].data.vector.y, + parameterList[3].data.color, // int foreground_color + parameterList[4].data.color, // int background_color + (WipeGaugeScalar::Direction) direction, + parameterList[6].data.scalar, // Scalar min, + parameterList[7].data.scalar, // Scalar max, + (Scalar *) parameterList[8].data.attributePointer // Scalar *valptr + // HACK!!!! The (Scalar *) is VERY dangerous! + ); + + Register_Object(bar_graph); + + Test_Tell("BarGraphSolidScalar::Make OK\n"); + Check_Fpu(); + return True; +} + +BarGraphSolidScalar::BarGraphSolidScalar( + GaugeRate rate, + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, int right, int top, + int foreground_color, int background_color, + WipeGaugeScalar::Direction direction, + Scalar min, + Scalar max, + Scalar *value_pointer, + const char *identification_string +): + WipeGaugeScalar( + rate, + mode_mask, + renderer, + owner_ID, + graphics_port_number, + left, bottom, right, top, + direction, + min, + max, + identification_string + ) +{ + backgroundColor = background_color; + foregroundColor = foreground_color; + + // + //----------------------------------------------------------- + // Build connection to value + // (if NULL, it's assumed that a derived object built the + // connection for us) + //----------------------------------------------------------- + // + if (value_pointer != NULL) + { + GaugeConnection + *connection = new + GaugeConnectionDirectOf(0, ¤tValue, value_pointer); + Register_Object(connection); + AddConnection(connection); + } + Check_Fpu(); +} + +BarGraphSolidScalar::~BarGraphSolidScalar() +{ + Check(this); + Check_Fpu(); +} + +Logical + BarGraphSolidScalar::TestInstance() const +{ + return WipeGaugeScalar::TestInstance(); +} + +void + BarGraphSolidScalar::ShowInstance(char *indent) +{ + Check(this); + + cout << indent << "BarGraphSolidScalar:\n"; + + char + temp[80]; + + Str_Copy(temp,indent, 80); + Str_Cat(temp,"...", 80); + + cout << temp << "foregroundColor=" << foregroundColor << "\n"; + cout << temp << "backgroundColor=" << backgroundColor << "\n"; + WipeGaugeScalar::ShowInstance(temp); + Check_Fpu(); +} + +void + BarGraphSolidScalar::DrawActive( + Rectangle2D *rectangle + ) +{ + localView.SetColor(foregroundColor); + localView.MoveToAbsolute( + rectangle->bottomLeft.x, + rectangle->bottomLeft.y + ); + localView.DrawFilledRectangleToAbsolute( + rectangle->topRight.x, + rectangle->topRight.y + ); + Check_Fpu(); +} + +void + BarGraphSolidScalar::DrawInactive( + Rectangle2D *rectangle + ) +{ + localView.SetColor(backgroundColor); + localView.MoveToAbsolute( + rectangle->bottomLeft.x, + rectangle->bottomLeft.y + ); + localView.DrawFilledRectangleToAbsolute( + rectangle->topRight.x, + rectangle->topRight.y + ); + Check_Fpu(); +} + + +//########################################################################### +// BarGraphBitMapScalar +//########################################################################### +MethodDescription + BarGraphBitMapScalar::methodDescription = + { + "bitmapbar", + BarGraphBitMapScalar::Make, + { + { ParameterDescription::typeRate, NULL }, // rate ID + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeVector, NULL }, // size + { ParameterDescription::typeString, NULL }, // bit map name + { ParameterDescription::typeColor, NULL }, // foreground + { ParameterDescription::typeColor, NULL }, // background + { ParameterDescription::typeString, NULL }, // direction + { ParameterDescription::typeScalar, NULL }, // min + { ParameterDescription::typeScalar, NULL }, // max + { ParameterDescription::typeAttribute, NULL }, // attribute + PARAMETER_DESCRIPTION_END + } + }; + +Logical + BarGraphBitMapScalar::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeRate); // rate ID + parameterList[1].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[2].CheckIt(ParameterDescription::typeVector); // size + parameterList[3].CheckIt(ParameterDescription::typeString); // image name + parameterList[4].CheckIt(ParameterDescription::typeColor); // foreground + parameterList[5].CheckIt(ParameterDescription::typeColor); // background + parameterList[6].CheckIt(ParameterDescription::typeString); // direction + parameterList[7].CheckIt(ParameterDescription::typeScalar); // min + parameterList[8].CheckIt(ParameterDescription::typeScalar); // max + parameterList[9].CheckIt(ParameterDescription::typeAttribute); +# endif + + Test_Tell("BarGraphBitMapScalar::Make\n"); + + int + direction = configureDirection[0].Search( + parameterList[6].data.string + ); + + if (direction < 0) + { + Test_Tell("BarGraphBitMapScalar::Make direction NOT FOUND\n"); + Check_Fpu(); + return False; + } + +# if DEBUG_LEVEL > 0 + BarGraphBitMapScalar + *bar_graph = +# endif + new BarGraphBitMapScalar( + parameterList[0].data.rate, + parameterList[1].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, // owner_ID*/ + display_port_index, // graphics_port_number + position.x, position.y, + position.x + parameterList[2].data.vector.x, + position.y + parameterList[2].data.vector.y, + parameterList[3].data.string, // BitMap name + parameterList[4].data.color, // int fg_color + parameterList[5].data.color, // int bg_color + (WipeGaugeScalar::Direction) direction, + parameterList[7].data.scalar, // Scalar min, + parameterList[8].data.scalar, // Scalar max, + (Scalar *) parameterList[9].data.attributePointer// Scalar *val_ptr + // HACK!!!! The (Scalar *) is VERY dangerous! + ); + + Register_Object(bar_graph); + //--------------------------------------------------------- + // Make sure the image was properly placed in the warehouse + //--------------------------------------------------------- + Check(gauge_renderer); + L4Warehouse + *warehouse = (L4Warehouse *) gauge_renderer->warehousePointer; + Check(warehouse); + + if (warehouse->bitMapBin.Get(parameterList[3].data.string) == NULL) + { + Test_Tell("BarGraphBitMapScalar::Missing bitmap\n"); + Check_Fpu(); + return False; + } + else + { + warehouse->bitMapBin.Release(parameterList[3].data.string); + } + //-------------------------------------------------------- + // Everything's ok + //-------------------------------------------------------- + Test_Tell("BarGraphBitMapScalar::Make OK\n"); + Check_Fpu(); + return True; +} + +BarGraphBitMapScalar::BarGraphBitMapScalar( + GaugeRate rate, + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, int right, int top, + const char *bitmap_name, //BitMap *bit_map, + int foreground_color, int background_color, + WipeGaugeScalar::Direction direction, + Scalar min, + Scalar max, + Scalar *value_pointer, + const char *identification_string +): + WipeGaugeScalar( + rate, + mode_mask, + renderer, + owner_ID, + graphics_port_number, + left, bottom, right, top, + direction, + min, + max, + identification_string + ) +{ + //------------------------------------------------------------ + // Save the bitmap name + //------------------------------------------------------------ + bitMapName = nameCopy(bitmap_name); + //------------------------------------------------------------- + // Save colors + //------------------------------------------------------------- + backgroundColor = background_color; + foregroundColor = foreground_color; + //------------------------------------------------------------- + // Order the image from the warehouse (pre-load for future use) + //------------------------------------------------------------- +# if defined(PRELOAD_ART) + Check(renderer); + Check(renderer->warehousePointer); + Check_Pointer(bitMapName); + + ((L4Warehouse *)renderer->warehousePointer)->bitMapBin.Get(bitMapName); +# endif + //----------------------------------------------------------- + // Build connection to value + // (if NULL, it's assumed that a derived object built the + // connection for us) + //----------------------------------------------------------- + if (value_pointer != NULL) + { + GaugeConnection + *connection = new + GaugeConnectionDirectOf(0, ¤tValue, value_pointer); + Register_Object(connection); + AddConnection(connection); + } + Check_Fpu(); +} + +BarGraphBitMapScalar::~BarGraphBitMapScalar() +{ + Check(this); + //------------------------------------------------------------ + // Unlock preloaded art + //------------------------------------------------------------ +# if defined(PRELOAD_ART) + Check(renderer); + Check(renderer->warehousePointer); + Check_Pointer(bitMapName); + ((L4Warehouse *)renderer->warehousePointer)-> + bitMapBin.Release(bitMapName); +# endif + //------------------------------------------------------------ + // Delete the bitmap name + //------------------------------------------------------------ + Unregister_Pointer(bitMapName); + delete[] bitMapName; + bitMapName = NULL; + + Check_Fpu(); +} + +Logical + BarGraphBitMapScalar::TestInstance() const +{ + return WipeGaugeScalar::TestInstance(); +} + +void + BarGraphBitMapScalar::ShowInstance(char *indent) +{ + Check(this); + + cout << indent << "BarGraphBitMapScalar:\n"; + + char + temp[80]; + + Str_Copy(temp,indent, 80); + Str_Cat(temp,"...", 80); + + cout << temp << "bitMapName= " << bitMapName << "\n"; + cout << temp << "backgroundColor=" << backgroundColor << "\n"; + WipeGaugeScalar::ShowInstance(temp); + Check_Fpu(); +} + +void + BarGraphBitMapScalar::DrawActive( + Rectangle2D *rectangle + ) +{ + //----------------------------------------------------------- + // Get and lock the image so that we may use it + //----------------------------------------------------------- + Check(renderer); + L4Warehouse + *warehouse = (L4Warehouse *) renderer->warehousePointer; + + Check_Pointer(bitMapName); + BitMap + *bit_map = renderer->warehousePointer->bitMapBin.Get(bitMapName); + //----------------------------------------------------------- + // Draw the image + //----------------------------------------------------------- + if (bit_map != NULL) + { + Check(bit_map); + localView.SetColor(foregroundColor); + + localView.MoveToAbsolute( + rectangle->bottomLeft.x, + rectangle->bottomLeft.y + ); + + localView.DrawBitMapOpaque( + backgroundColor, + 0, // rotation + bit_map, + rectangle->bottomLeft.x, + rectangle->bottomLeft.y, + rectangle->topRight.x, + rectangle->topRight.y + ); + } + //----------------------------------------------------------- + // Unlock the image: we're done + //----------------------------------------------------------- + Check(warehouse); + warehouse->bitMapBin.Release(bitMapName); + + Check_Fpu(); +} + +void + BarGraphBitMapScalar::DrawInactive( + Rectangle2D *rectangle + ) +{ + Check(this); + + localView.SetColor(backgroundColor); + + localView.MoveToAbsolute( + rectangle->bottomLeft.x, + rectangle->bottomLeft.y + ); + + localView.DrawFilledRectangleToAbsolute( + rectangle->topRight.x, + rectangle->topRight.y + ); + + Check_Fpu(); +} + +//########################################################################### +// BarGraphPixelMapScalar +//########################################################################### +MethodDescription + BarGraphPixelMapScalar::methodDescription = + { + "pixelbar", + BarGraphPixelMapScalar::Make, + { + { ParameterDescription::typeRate, NULL }, // rate ID + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeVector, NULL }, // size + { ParameterDescription::typeString, NULL }, // pixel map name + { ParameterDescription::typeColor, NULL }, // background + { ParameterDescription::typeString, NULL }, // direction + { ParameterDescription::typeScalar, NULL }, // min + { ParameterDescription::typeScalar, NULL }, // max + { ParameterDescription::typeAttribute, NULL }, // attribute + PARAMETER_DESCRIPTION_END + } + }; + +Logical + BarGraphPixelMapScalar::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeRate); // rate ID + parameterList[1].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[2].CheckIt(ParameterDescription::typeVector); // size + parameterList[3].CheckIt(ParameterDescription::typeString); // foreground + parameterList[4].CheckIt(ParameterDescription::typeColor); // background + parameterList[5].CheckIt(ParameterDescription::typeString); // direction + parameterList[6].CheckIt(ParameterDescription::typeScalar); // min + parameterList[7].CheckIt(ParameterDescription::typeScalar); // max + parameterList[8].CheckIt(ParameterDescription::typeAttribute); +# endif + + Test_Tell("BarGraphPixelMapScalar::Make\n"); + + int + direction = configureDirection[0].Search( + parameterList[5].data.string + ); + + if (direction < 0) + { + Test_Tell("BarGraphPixelMapScalar::Make direction NOT FOUND\n"); + Check_Fpu(); + return False; + } + +# if DEBUG_LEVEL > 0 + BarGraphPixelMapScalar + *bar_graph = +# endif + new BarGraphPixelMapScalar( + parameterList[0].data.rate, + parameterList[1].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, // owner_ID*/ + display_port_index, // graphics_port_number + position.x, position.y, + position.x + parameterList[2].data.vector.x, + position.y + parameterList[2].data.vector.y, + parameterList[3].data.string, // PixelMap name + parameterList[4].data.color, // int bg_color + (WipeGaugeScalar::Direction) direction, + parameterList[6].data.scalar, // Scalar min, + parameterList[7].data.scalar, // Scalar max, + (Scalar *) parameterList[8].data.attributePointer //Scalar *valptr + // HACK!!!! The (Scalar *) is VERY dangerous! + ); + + Register_Object(bar_graph); + //--------------------------------------------------------- + // Make sure the image was properly placed in the warehouse + //--------------------------------------------------------- + Check(gauge_renderer); + L4Warehouse + *warehouse = (L4Warehouse *) gauge_renderer->warehousePointer; + Check(warehouse); + + if (warehouse->bitMapBin.Get(parameterList[3].data.string) == NULL) + { + Test_Tell("BarGraphPixelMapScalar::Missing pixelmap\n"); + Check_Fpu(); + return False; + } + else + { + warehouse->bitMapBin.Release(parameterList[3].data.string); + } + //-------------------------------------------------------- + // Everything's ok + //-------------------------------------------------------- + Test_Tell("BarGraphPixelMapScalar::Make OK\n"); + Check_Fpu(); + return True; +} + +BarGraphPixelMapScalar::BarGraphPixelMapScalar( + GaugeRate rate, + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, int right, int top, + const char *pixelmap_name, //PixelMap8 *pixel_map, + int background_color, + WipeGaugeScalar::Direction direction, + Scalar min, + Scalar max, + Scalar *value_pointer, + const char *identification_string +): + WipeGaugeScalar( + rate, + mode_mask, + renderer, + owner_ID, + graphics_port_number, + left, bottom, right, top, + direction, + min, + max, + identification_string + ) +{ + //------------------------------------------------------------- + // Make local copy of map name + //------------------------------------------------------------- + Check_Pointer(pixelmap_name); + pixelMapName = nameCopy(pixelmap_name); + Check_Pointer(pixelMapName); + //------------------------------------------------------------- + // Save background color + //------------------------------------------------------------- + backgroundColor = background_color; + //------------------------------------------------------------- + // Order the image from the warehouse (pre-load for future use) + //------------------------------------------------------------- +# if defined(PRELOAD_ART) + Check(renderer); + Check(renderer->warehousePointer); + + ((L4Warehouse *) renderer->warehousePointer)-> + pixelMap8Bin.Get(pixelMapName); +# endif + //----------------------------------------------------------- + // Build connection to value + // (if NULL, it's assumed that a derived object built the + // connection for us) + //----------------------------------------------------------- + // + if (value_pointer != NULL) + { + GaugeConnection + *connection = new + GaugeConnectionDirectOf(0, ¤tValue, value_pointer); + Register_Object(connection); + AddConnection(connection); + } + Check_Fpu(); +} + +BarGraphPixelMapScalar::~BarGraphPixelMapScalar() +{ + Check(this); + //------------------------------------------------------------ + // Unlock preloaded image + //------------------------------------------------------------ +# if defined(PRELOAD_ART) + Check(renderer); + Check(renderer->warehousePointer); + Check_Pointer(pixelMapName); + + ((L4Warehouse *) renderer->warehousePointer)-> + pixelMap8Bin.Get(pixelMapName); +# endif + //------------------------------------------------------------ + // Delete the map name + //------------------------------------------------------------ + Unregister_Pointer(pixelMapName); + delete[] pixelMapName; + pixelMapName = NULL; + + Check_Fpu(); +} + +Logical + BarGraphPixelMapScalar::TestInstance() const +{ + return WipeGaugeScalar::TestInstance(); +} + +void + BarGraphPixelMapScalar::ShowInstance(char *indent) +{ + Check(this); + + cout << indent << "BarGraphPixelMapScalar:\n"; + + char + temp[80]; + + Str_Copy(temp,indent, 80); + Str_Cat(temp,"...", 80); + + cout << temp << "pixelMapName= " << pixelMapName << "\n"; + cout << temp << "backgroundColor=" << backgroundColor << "\n"; + WipeGaugeScalar::ShowInstance(temp); + Check_Fpu(); +} + +void + BarGraphPixelMapScalar::DrawActive( + Rectangle2D *rectangle + ) +{ + //----------------------------------------------------------- + // Get and lock the image so that we may use it + //----------------------------------------------------------- + Check(renderer); + L4Warehouse + *warehouse = (L4Warehouse *) renderer->warehousePointer; + + Check_Pointer(pixelMapName); + PixelMap8 + *pixel_map = renderer->warehousePointer->pixelMap8Bin.Get(pixelMapName); + //----------------------------------------------------------- + // Draw the image + //----------------------------------------------------------- + if (pixel_map != NULL) + { + Check(pixel_map); + + localView.MoveToAbsolute( + rectangle->bottomLeft.x, + rectangle->bottomLeft.y + ); + + localView.DrawPixelMap8( + False, // opaque, + 0, // rotation + pixel_map, + rectangle->bottomLeft.x, + rectangle->bottomLeft.y, + rectangle->topRight.x, + rectangle->topRight.y + ); + } + //----------------------------------------------------------- + // Unlock the image: we're done + //----------------------------------------------------------- + Check(warehouse); + warehouse->pixelMap8Bin.Release(pixelMapName); + + Check_Fpu(); +} + +void + BarGraphPixelMapScalar::DrawInactive( + Rectangle2D *rectangle + ) +{ + //----------------------------------------------------------- + // Get and lock the image so that we may use it + //----------------------------------------------------------- + Check(renderer); + L4Warehouse + *warehouse = (L4Warehouse *) renderer->warehousePointer; + + Check_Pointer(pixelMapName); + PixelMap8 + *pixel_map = renderer->warehousePointer->pixelMap8Bin.Get(pixelMapName); + //----------------------------------------------------------- + // Draw the image + //----------------------------------------------------------- + if (pixel_map != NULL) + { + Check(pixel_map); + + localView.SetColor(backgroundColor); + + localView.MoveToAbsolute( + rectangle->bottomLeft.x, + rectangle->bottomLeft.y + ); + + localView.DrawPixelMap8SingleColor( + 0, // rotation + pixel_map, + rectangle->bottomLeft.x, + rectangle->bottomLeft.y, + rectangle->topRight.x, + rectangle->topRight.y + ); + } + //----------------------------------------------------------- + // Unlock the image: we're done + //----------------------------------------------------------- + Check(warehouse); + warehouse->pixelMap8Bin.Release(pixelMapName); + + Check_Fpu(); +} + +//####################################################################### +// ColorState +//####################################################################### +MethodDescription + ColorState::methodDescription= + { + "colorState", + ColorState::Make, + { + { ParameterDescription::typeRate, NULL }, // rate ID + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeString, NULL }, // bitmap name + { ParameterDescription::typeColor, NULL }, // color 0 + { ParameterDescription::typeScalar, NULL }, // 0...a + { ParameterDescription::typeColor, NULL }, // color 1 + { ParameterDescription::typeScalar, NULL }, // a...b + { ParameterDescription::typeColor, NULL }, // color 2 + { ParameterDescription::typeScalar, NULL }, // b...c + { ParameterDescription::typeColor, NULL }, // color 3 + { ParameterDescription::typeScalar, NULL }, // c...d + { ParameterDescription::typeColor, NULL }, // color 4 (+) + { ParameterDescription::typeInteger, NULL }, // zone # + { ParameterDescription::typeAttribute, NULL }, // attribute + PARAMETER_DESCRIPTION_END + } + }; + +Logical + ColorState::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeRate); // rate ID + parameterList[1].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[2].CheckIt(ParameterDescription::typeString); // bitmap name + parameterList[3].CheckIt(ParameterDescription::typeColor); // first color + parameterList[4].CheckIt(ParameterDescription::typeScalar); // first range + parameterList[5].CheckIt(ParameterDescription::typeColor); // second color + parameterList[6].CheckIt(ParameterDescription::typeScalar); // second range + parameterList[7].CheckIt(ParameterDescription::typeColor); // third color + parameterList[8].CheckIt(ParameterDescription::typeScalar); // third range + parameterList[9].CheckIt(ParameterDescription::typeColor); // fourth color + parameterList[10].CheckIt(ParameterDescription::typeScalar);// fourth range + parameterList[11].CheckIt(ParameterDescription::typeColor); // fifth color + parameterList[12].CheckIt(ParameterDescription::typeInteger); // zone # + parameterList[13].CheckIt(ParameterDescription::typeAttribute); +# endif + + Test_Tell("ColorState::Make\n"); + +# if DEBUG_LEVEL > 0 + ColorState + *color_state = +# endif + new ColorState( + parameterList[0].data.rate, + parameterList[1].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, // unsigned int owner_ID + display_port_index, // int graphics_port_number + position.x, position.y, + parameterList[2].data.string, + parameterList[3].data.color, + parameterList[4].data.scalar, + parameterList[5].data.color, + parameterList[6].data.scalar, + parameterList[7].data.color, + parameterList[8].data.scalar, + parameterList[9].data.color, + parameterList[10].data.scalar, + parameterList[11].data.color, + parameterList[12].data.integer, + (DamageZone ***) parameterList[13].data.attributePointer + // HACK!!!! The cast above is VERY dangerous! + ); + + Register_Object(color_state); + //--------------------------------------------------------- + // Make sure the image was properly placed in the warehouse + //--------------------------------------------------------- + Check(gauge_renderer); + L4Warehouse + *warehouse = (L4Warehouse *) gauge_renderer->warehousePointer; + Check(warehouse); + + if (warehouse->bitMapBin.Get(parameterList[2].data.string) == NULL) + { + Test_Tell("ColorState::Missing pixelmap\n"); + Check_Fpu(); + return False; + } + else + { + warehouse->bitMapBin.Release(parameterList[2].data.string); + } + //-------------------------------------------------------- + // Everything's ok + //-------------------------------------------------------- + Test_Tell("ColorState::Make OK\n"); + Check_Fpu(); + return True; +} + +ColorState::ColorState( + GaugeRate rate, + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, + const char *bitmap_name, + int first_color, + Scalar first_bin, + int second_color, + Scalar second_bin, + int third_color, + Scalar third_bin, + int fourth_color, + Scalar fourth_bin, + int fifth_color, + int zone_number, + DamageZone ***value_pointer, + const char *identification_string +): + GraphicGauge( + rate, + mode_mask, + renderer, + owner_ID, + graphics_port_number, + identification_string + ) +{ + Test_Tell("ColorState creator\n" << flush); + Check(renderer); + //------------------------------------------------------------ + // Save the map name + //------------------------------------------------------------ + bitMapName = nameCopy(bitmap_name); + //------------------------------------------------------------- + // Order the image from the warehouse (pre-load for future use) + //------------------------------------------------------------- +# if defined(PRELOAD_ART) + Check(renderer); + Check(renderer->warehousePointer); + Check_Pointer(bitMapName); + + ((L4Warehouse *)renderer->warehousePointer)-> + bitMapBin.Get(bitMapName); +# endif + //------------------------------------------------------------- + // Initialize values + //------------------------------------------------------------- + localView.SetOrigin(left, bottom); + + color[0] = first_color; + color[1] = second_color; + color[2] = third_color; + color[3] = fourth_color; + color[4] = fifth_color; + + bin[0] = first_bin; + bin[1] = second_bin; + bin[2] = third_bin; + bin[3] = fourth_bin; + + Test_Tell("value_pointer=" << value_pointer << "\n" << flush); + Check_Pointer(value_pointer); + DamageZone + **array_pointer = *value_pointer; + Test_Tell("array_pointer=" << array_pointer << "\n" << flush); + Check_Pointer(array_pointer); + + Test_Tell("zone_number=" << zone_number << "\n" << flush); + damagePointer = array_pointer[zone_number]; + Test_Tell("damagePointer=" << damagePointer << "\n" << flush); + Check(damagePointer); + + Check_Fpu(); +} + +ColorState::~ColorState() +{ + Check(this); + //------------------------------------------------------------ + // Unlock preloaded art + //------------------------------------------------------------ +# if defined(PRELOAD_ART) + Check(renderer); + Check(renderer->warehousePointer); + Check_Pointer(bitMapName); + ((L4Warehouse *)renderer->warehousePointer)-> + bitMapBin.Release(bitMapName); +# endif + //------------------------------------------------------------ + // Delete the map name + //------------------------------------------------------------ + Unregister_Pointer(bitMapName); + delete[] bitMapName; + bitMapName = NULL; + + Check_Fpu(); +} + +Logical + ColorState::TestInstance() const +{ + return True; +} + +void + ColorState::ShowInstance(char */*indent*/) +{ + Check_Fpu(); +} + +void + ColorState::BecameActive() +{ + Check(this); + + previousState = -1; +} + +void + ColorState::Execute() +{ + Check(this); + + //----------------------------------------------------------- + // Get and lock the image so that we may use it + //----------------------------------------------------------- + Check(renderer); + L4Warehouse + *warehouse = (L4Warehouse *) renderer->warehousePointer; + + Check_Pointer(bitMapName); + BitMap + *bit_map = renderer->warehousePointer->bitMapBin.Get(bitMapName); + //----------------------------------------------------------- + // Draw the image + //----------------------------------------------------------- + if (bit_map != NULL) + { + Check(bit_map); + Check(damagePointer); + Scalar + value(damagePointer->damageLevel); + int + i; + //---------------------------------------- + // Find current bin + //---------------------------------------- + for(i=0; i<4; ++i) + { + if (value < bin[i]) + { + break; + } + } + //---------------------------------------- + // If different, draw it + //---------------------------------------- + if (i != previousState) + { + previousState = i; + + localView.SetColor(color[i]); + localView.DrawBitMap(0, bit_map); + } + } + //----------------------------------------------------------- + // Unlock the image: we're done + //----------------------------------------------------------- + Check(warehouse); + warehouse->bitMapBin.Release(bitMapName); + + Check_Fpu(); +} + +//####################################################################### +// TwoState +//####################################################################### +MethodDescription + TwoState::methodDescription= + { + "twoState", + TwoState::Make, + { + { ParameterDescription::typeRate, NULL }, // rate ID + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeString, NULL }, // bitmap name + { ParameterDescription::typeColor, NULL }, // color 0 + { ParameterDescription::typeColor, NULL }, // color 1 + { ParameterDescription::typeAttribute, NULL }, // attribute + PARAMETER_DESCRIPTION_END + } + }; + +Logical + TwoState::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeRate); // rate ID + parameterList[1].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[2].CheckIt(ParameterDescription::typeString); // bitmap name + parameterList[3].CheckIt(ParameterDescription::typeColor); // first color + parameterList[4].CheckIt(ParameterDescription::typeColor); // second color + parameterList[5].CheckIt(ParameterDescription::typeAttribute); +# endif + + Test_Tell("TwoState::Make\n"); + +# if DEBUG_LEVEL > 0 + TwoState + *two_state = +# endif + new TwoState( + parameterList[0].data.rate, + parameterList[1].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, //unsigned int owner_ID + display_port_index, //int graphics_port_number + position.x, position.y, + parameterList[2].data.string, //bitmap name + parameterList[3].data.color, + parameterList[4].data.color, + (int *) parameterList[5].data.attributePointer + // HACK!!!! The cast above is VERY dangerous! + ); + + Register_Object(two_state); + //--------------------------------------------------------- + // Make sure the image was properly placed in the warehouse + //--------------------------------------------------------- + Check(gauge_renderer); + L4Warehouse + *warehouse = (L4Warehouse *) gauge_renderer->warehousePointer; + Check(warehouse); + + if (warehouse->bitMapBin.Get(parameterList[2].data.string) == NULL) + { + Test_Tell("TwoState::Missing bitmap\n"); + Check_Fpu(); + return False; + } + else + { + warehouse->bitMapBin.Release(parameterList[2].data.string); + } + //-------------------------------------------------------- + // Everything's ok + //-------------------------------------------------------- + Test_Tell("TwoState::Make OK\n"); + Check_Fpu(); + return True; +} + +TwoState::TwoState( + GaugeRate rate, + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, + const char *bitmap_name, + int first_color, + int second_color, + int *value_pointer, + const char *identification_string +): + GraphicGauge( + rate, + mode_mask, + renderer, + owner_ID, + graphics_port_number, + identification_string + ) +{ + Test_Tell("TwoState creator\n" << flush); + Check_Pointer(this); + + //------------------------------------------------------------ + // Save the bitmap name + //------------------------------------------------------------ + bitMapName = nameCopy(bitmap_name); + //------------------------------------------------------------- + // Order the image from the warehouse (pre-load for future use) + //------------------------------------------------------------- +# if defined(PRELOAD_ART) + Check(renderer); + Check(renderer->warehousePointer); + Check_Pointer(bitMapName); + + ((L4Warehouse *)renderer->warehousePointer)-> + bitMapBin.Get(bitMapName); +# endif + //----------------------------------------------------------- + // Initialize values + //----------------------------------------------------------- + localView.SetOrigin(left, bottom); + + color[0] = first_color; + color[1] = second_color; + //----------------------------------------------------------- + // Build connection to value + //----------------------------------------------------------- + GaugeConnection + *connection; + + connection = new + GaugeConnectionDirectOf(0, ¤tValue, value_pointer); + Register_Object(connection); + AddConnection(connection); + + Check_Fpu(); +} + +TwoState::~TwoState() +{ + Check(this); + //------------------------------------------------------------ + // Unlock preloaded art + //------------------------------------------------------------ +# if defined(PRELOAD_ART) + Check(renderer); + Check(renderer->warehousePointer); + Check_Pointer(bitMapName); + ((L4Warehouse *)renderer->warehousePointer)-> + bitMapBin.Release(bitMapName); +# endif + //------------------------------------------------------------ + // Delete the bitmap name + //------------------------------------------------------------ + Unregister_Pointer(bitMapName); + delete[] bitMapName; + bitMapName = NULL; + + Check_Fpu(); +} + +Logical + TwoState::TestInstance() const +{ + return True; +} + +void + TwoState::ShowInstance(char */*indent*/) +{ + Check_Fpu(); +} + +void + TwoState::BecameActive() +{ + Check(this); + previousState = -1; + Check_Fpu(); +} + +void + TwoState::Execute() +{ + Check(this); + //----------------------------------------------------------- + // Get and lock the image so that we may use it + //----------------------------------------------------------- + Check(renderer); + L4Warehouse + *warehouse = (L4Warehouse *) renderer->warehousePointer; + + Check_Pointer(bitMapName); + BitMap + *bit_map = renderer->warehousePointer->bitMapBin.Get(bitMapName); + //----------------------------------------------------------- + // Draw the image + //----------------------------------------------------------- + if (bit_map != NULL) + { + Check(bit_map); + + int + new_value; + + if (currentValue > 0) + { + new_value = 1; + } + else + { + new_value = 0; + } + + if (new_value != previousState) + { + previousState = new_value; + + localView.SetColor(color[new_value]); + localView.DrawBitMap(0, bit_map); + } + } + //----------------------------------------------------------- + // Unlock the image: we're done + //----------------------------------------------------------- + Check(warehouse); + warehouse->bitMapBin.Release(bitMapName); + + Check_Fpu(); +} + +//########################################################################### +// NumericDisplayScalarTwoState +//########################################################################### +MethodDescription + NumericDisplayScalarTwoState ::methodDescription = + { + "numericIntegerTwoState", + NumericDisplayScalarTwoState::Make, + { + { ParameterDescription::typeRate, NULL }, // rate ID + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeVector, NULL }, // size + { ParameterDescription::typeString, NULL }, // font name + { ParameterDescription::typeInteger, NULL }, // # of digits + { ParameterDescription::typeString, NULL }, // format + { ParameterDescription::typeColor, NULL }, // background + { ParameterDescription::typeColor, NULL }, // foreground + { ParameterDescription::typeAttribute, NULL }, // attribute for number + { ParameterDescription::typeAttribute, NULL }, // attribute for logical + PARAMETER_DESCRIPTION_END + } + }; + +Logical + NumericDisplayScalarTwoState::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeRate); // rate ID + parameterList[1].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[2].CheckIt(ParameterDescription::typeVector); // size + parameterList[3].CheckIt(ParameterDescription::typeString); // font + parameterList[4].CheckIt(ParameterDescription::typeInteger); // # of digs + parameterList[5].CheckIt(ParameterDescription::typeString); // format + parameterList[6].CheckIt(ParameterDescription::typeColor); // background + parameterList[7].CheckIt(ParameterDescription::typeColor); // foreground + parameterList[8].CheckIt(ParameterDescription::typeAttribute); // value name + parameterList[9].CheckIt(ParameterDescription::typeAttribute); // second value name +# endif + + Test_Tell("NumericDisplayScalarTwoState::Make\n"); + + int + number_format = configureFormat[0].Search( + parameterList[5].data.string + ); + + if (number_format < 0) + { + Test_Tell("NumericDisplayScalarTwoState::Make format NOT FOUND\n"); + Check_Fpu(); + return False; + } + +# if DEBUG_LEVEL > 0 + NumericDisplayScalarTwoState + *numeric_display = +# endif + new NumericDisplayScalarTwoState( + parameterList[0].data.rate, + parameterList[1].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, //unsigned int owner_ID + display_port_index, //int graphics_port_number + position.x, position.y, + position.x + parameterList[2].data.vector.x, + position.y + parameterList[2].data.vector.y, + parameterList[3].data.string, //font name + parameterList[4].data.integer, //int number_of_chars + (NumericDisplay::NumericFormat) number_format, + parameterList[6].data.integer, //int background_color + parameterList[7].data.integer, //int foreground_color + (Scalar *) parameterList[8].data.attributePointer, + (int *) parameterList[9].data.attributePointer // second (logical) value + // HACK!!!! The (Scalar *) is VERY dangerous! + // HACK!!!! The (int *) is VERY dangerous! + ); + Register_Object(numeric_display); + + //-------------------------------------------------------- + // Make sure the font was properly placed in the warehouse + //-------------------------------------------------------- + Check(gauge_renderer); + L4Warehouse + *warehouse = (L4Warehouse *) gauge_renderer->warehousePointer; + Check(warehouse); + + if (warehouse->bitMapBin.Get(parameterList[3].data.string) == NULL) + { + Test_Tell("NumericDisplayScalarTwoState::Missing font\n"); + Check_Fpu(); + return False; + } + else + { + warehouse->bitMapBin.Release(parameterList[3].data.string); + } + //-------------------------------------------------------- + // Everything's ok + //-------------------------------------------------------- + Test_Tell("NumericDisplayScalarTwoState::Make OK\n"); + Check_Fpu(); + return True; +} + +NumericDisplayScalarTwoState::NumericDisplayScalarTwoState( + GaugeRate rate, + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int left, int bottom, int right, int top, + const char *font_name, + int number_of_digits, + NumericDisplay::NumericFormat requested_format, + int background_color, int foreground_color, + Scalar *value_pointer, + int *logical_pointer, + const char *identification_string +): + GraphicGauge( + rate, + mode_mask, + renderer, + owner_ID, + graphics_port_number, + identification_string + ) +{ + Check_Pointer(this); + // graphics_port may be NULL! + Check_Pointer(value_pointer); + Check(renderer); + //----------------------------------------------------------- + // Set internal values + //----------------------------------------------------------- + numericDisplay = new NumericDisplay( + (L4Warehouse *) renderer->warehousePointer, + 0,0, + font_name, + number_of_digits, + requested_format, + background_color, + foreground_color + ); + Register_Object(numericDisplay); + + localView.SetPositionWithinPort(left, bottom, right, top); + + color[0] = background_color; + color[1] = foreground_color; + //----------------------------------------------------------- + // Build connection to value + //----------------------------------------------------------- + GaugeConnection + *value_connection; + + GaugeConnection + *logical_connection; + + value_connection = new + GaugeConnectionDirectOf(0, ¤tValue, value_pointer); + Register_Object(value_connection); + AddConnection(value_connection); + + + logical_connection = new + GaugeConnectionDirectOf(0, ¤tLogical, logical_pointer); + Register_Object(logical_connection); + AddConnection(logical_connection); + + previousValue = currentValue; + Check_Fpu(); +} + +NumericDisplayScalarTwoState::~NumericDisplayScalarTwoState() +{ + Check(this); + + if (numericDisplay != NULL) + { + Unregister_Object(numericDisplay); + delete numericDisplay; + numericDisplay = NULL; + } + + // base class deletes all connections in Gauge::~Gauge + Check_Fpu(); +} + +Logical + NumericDisplayScalarTwoState::TestInstance() const +{ + return GraphicGauge::TestInstance(); +} + +void + NumericDisplayScalarTwoState::ShowInstance(char *indent) +{ + Check(this); + + cout << indent << "NumericDisplayScalarTwoState:\n"; + + char + temp[80]; + + Str_Copy(temp,indent, 80); + Str_Cat(temp,"...", 80); + + GraphicGauge::ShowInstance(temp); + Check(numericDisplay); + numericDisplay->ShowInstance(temp); + Check_Fpu(); +} + +void + NumericDisplayScalarTwoState::BecameActive() +{ + Check(this); + Check(numericDisplay); + previousState = -1; + numericDisplay->ForceUpdate(); + Check_Fpu(); +} + +#if 0 +void + NumericDisplayScalarTwoState::SetColors(int bg_color, int fg_color) +{ + Check(this); + numericDisplay->SetColors(bg_color, fg_color); + Check_Fpu(); +} +#endif + +void + NumericDisplayScalarTwoState::Execute() +{ + Check(this); + Check(numericDisplay); + + int new_logical; + if (currentLogical > 0) + { + new_logical = 1; + } + else + { + new_logical = 0; + } + + // Draw if state has changed. NumericDisplay only redraws if value has changed + if (new_logical != previousState || currentValue != previousValue) + { + previousState = new_logical; + previousValue = currentValue; + if (currentLogical > 0) + { + numericDisplay->Draw(&localView,currentValue); + } + else + { + numericDisplay->Erase(&localView); + } + } + Check_Fpu(); +} + + + +//####################################################################### +// SegmentArc +//####################################################################### +SegmentArc::SegmentArc( + GaugeRate rate, + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int center_x, int center_y, + Scalar inner0, Scalar outer0, + Scalar inner1, Scalar outer1, + Scalar deg0, Scalar deg1, + int number_of_segs_and_direction, + int background_color, + int foreground_color, + Logical use_thick_lines, + const char *identification_string +) : + GraphicGauge( + rate, + mode_mask, + renderer, + owner_ID, + graphics_port_number, + identification_string + ) +{ + Test_Tell("SegmentArc creator\n" << flush); + Check_Pointer(this); + + + backgroundColor = background_color; + foregroundColor = foreground_color; + numberOfSegments = number_of_segs_and_direction; + startAngle = deg0*(2.0*M_PI)/360; + innerRadius = inner0; + outerRadius = outer0; + useThickLines = use_thick_lines; + + if (numberOfSegments < 0) + { + numberOfSegments = - numberOfSegments; + } + Verify(numberOfSegments > 0); + + Scalar + total_angle = (deg1*(2.0*M_PI)/360) - startAngle; + + if (number_of_segs_and_direction > 0) + { + if (total_angle < 0.0) + { + total_angle += (2.0*M_PI); + } + } + else + { + if (total_angle > 0.0) + { + total_angle -= (2.0*M_PI); + } + } + deltaAngle = (total_angle)/numberOfSegments; + deltaInnerRadius = (inner1 - inner0)/numberOfSegments; + deltaOuterRadius = (outer1 - outer0)/numberOfSegments; + + localView.SetOrigin(center_x, center_y); + + Check_Fpu(); +} + +SegmentArc::~SegmentArc() +{ + + // base class deletes all connections in Gauge::~Gauge + Check_Fpu(); +} + +Logical + SegmentArc::TestInstance() const +{ + return True; +} + +void + SegmentArc::ShowInstance(char */*indent*/) +{ + + cout << "SegmentArc\n"; + cout << " backgroundColor = " << backgroundColor << "\n"; + cout << " foregroundColor = " << foregroundColor << "\n"; + cout << " numberOfSegments = " << numberOfSegments << "\n"; + cout << " startAngle = " << startAngle << "\n"; + cout << " deltaAngle = " << deltaAngle << "\n"; + cout << " deltaInnerRadius = " << deltaInnerRadius << "\n"; + cout << " deltaOuterRadius = " << deltaOuterRadius << "\n"; + cout << " previousSegment = " << previousSegment << "\n"; + Check_Fpu(); +} + +void + SegmentArc::BecameActive() +{ + Check(this); + + previousSegment = 0; +} + +void + SegmentArc::Execute() +{ + Check(this); + + if (currentValue < (Scalar) 0) + { + currentValue = (Scalar) 0; + } + else if (currentValue > (Scalar) 1) + { + currentValue = (Scalar) 1; + } + + Verify(numberOfSegments > 0); + + int + i, + new_segment = (int) (currentValue * numberOfSegments + .5); + Scalar + inner_radius, + delta_inner, + outer_radius, + delta_outer, + segment_angle, + delta_angle, + segment_sin, + segment_cos; + + if (new_segment != previousSegment) + { + if (new_segment > previousSegment) + { + localView.SetColor(foregroundColor); + + i = new_segment - previousSegment; // how many segments + + inner_radius = innerRadius + (previousSegment * deltaInnerRadius); + outer_radius = outerRadius + (previousSegment * deltaOuterRadius); + segment_angle = startAngle + (previousSegment * deltaAngle); + } + else + { + localView.SetColor(backgroundColor); + + i = previousSegment - new_segment; // how many segments + + inner_radius = innerRadius + (new_segment * deltaInnerRadius); + outer_radius = outerRadius + (new_segment * deltaOuterRadius); + segment_angle = startAngle + (new_segment * deltaAngle); + } + + delta_outer = deltaOuterRadius; + delta_inner = deltaInnerRadius; + delta_angle = deltaAngle; + + for(; i>=0; --i) + { + segment_sin = sin(segment_angle); + segment_cos = cos(segment_angle); + + localView.MoveToAbsolute( + (int)(segment_sin*inner_radius + .5), + (int)(segment_cos*inner_radius + .5) + ); + + if (useThickLines) + { + localView.DrawThickLineToAbsolute( + (int)(segment_sin*outer_radius + .5), + (int)(segment_cos*outer_radius + .5) + ); + } + else + { + localView.DrawLineToAbsolute( + (int)(segment_sin*outer_radius + .5), + (int)(segment_cos*outer_radius + .5) + ); + } + + inner_radius += delta_inner; + outer_radius += delta_outer; + segment_angle += delta_angle; + } + + previousSegment = new_segment; + } + Check_Fpu(); +} + +//####################################################################### +// SegmentArcNormalized +//####################################################################### +MethodDescription + SegmentArcNormalized::methodDescription = + { + "segmentArc", + SegmentArcNormalized::Make, + { + { ParameterDescription::typeRate, NULL }, // rate ID + { ParameterDescription::typeModeMask, NULL }, // mode mask + { ParameterDescription::typeScalar, NULL }, // inner 0 + { ParameterDescription::typeScalar, NULL }, // outer 0 + { ParameterDescription::typeScalar, NULL }, // inner 1 + { ParameterDescription::typeScalar, NULL }, // outer 1 + { ParameterDescription::typeScalar, NULL }, // deg 0 + { ParameterDescription::typeScalar, NULL }, // deg 1 + { ParameterDescription::typeInteger, NULL }, // segs + { ParameterDescription::typeColor, NULL }, // fg + { ParameterDescription::typeColor, NULL }, // bg + { ParameterDescription::typeAttribute, NULL }, // attribute + PARAMETER_DESCRIPTION_END + } + }; + +Logical + SegmentArcNormalized::Make( + int display_port_index, + Vector2DOf position, + Entity */*entity*/, + GaugeRenderer * gauge_renderer + ) +{ + ParameterDescription + *parameterList = methodDescription.parameterList; + +# if DEBUG_LEVEL > 0 + parameterList[0].CheckIt(ParameterDescription::typeRate); // rate ID + parameterList[1].CheckIt(ParameterDescription::typeModeMask); // mode mask + parameterList[2].CheckIt(ParameterDescription::typeScalar); // inner0 + parameterList[3].CheckIt(ParameterDescription::typeScalar); // outer0 + parameterList[4].CheckIt(ParameterDescription::typeScalar); // inner1 + parameterList[5].CheckIt(ParameterDescription::typeScalar); // outer1 + parameterList[6].CheckIt(ParameterDescription::typeScalar); // deg0 + parameterList[7].CheckIt(ParameterDescription::typeScalar); // deg1 + parameterList[8].CheckIt(ParameterDescription::typeInteger); // segs&dir + parameterList[9].CheckIt(ParameterDescription::typeColor); // bg color + parameterList[10].CheckIt(ParameterDescription::typeColor); // fg color + parameterList[11].CheckIt(ParameterDescription::typeAttribute); +# endif + + Test_Tell("SegmentArcNormalized::Make\n"); + +# if DEBUG_LEVEL > 0 + SegmentArcNormalized + *arc = +# endif + new SegmentArcNormalized( + parameterList[0].data.rate, + parameterList[1].data.modeMask, + (L4GaugeRenderer *) gauge_renderer, + 0, // unsigned int owner_ID + display_port_index, // int graphics_port_number + position.x, position.y, + parameterList[2].data.scalar, // inner0 + parameterList[3].data.scalar, // outer0 + parameterList[4].data.scalar, // inner1 + parameterList[5].data.scalar, // outer1 + parameterList[6].data.scalar, // deg0 + parameterList[7].data.scalar, // deg1 + parameterList[8].data.integer, // segs & dir + parameterList[9].data.color, // bg + parameterList[10].data.color, // fg + (Scalar *) parameterList[11].data.attributePointer, + True // use thick lines + + // HACK - cast is VERY DANGEROUS! + ); + + Register_Object(arc); + + Test_Tell("SegmentArcNormalized::Make OK\n"); + Check_Fpu(); + return True; +} + +SegmentArcNormalized::SegmentArcNormalized( + GaugeRate rate, + ModeMask mode_mask, + L4GaugeRenderer *renderer, + unsigned int owner_ID, + int graphics_port_number, + int center_x, int center_y, + Scalar inner0, Scalar outer0, + Scalar inner1, Scalar outer1, + Scalar deg0, Scalar deg1, + int number_of_segs_and_direction, + int background_color, + int foreground_color, + Scalar *value_pointer, + Logical use_thick_lines, + const char *identification_string +) : + SegmentArc( + rate, + mode_mask, + renderer, + owner_ID, + graphics_port_number, + center_x, center_y, + inner0, outer0, + inner1, outer1, + deg0, deg1, + number_of_segs_and_direction, + background_color, + foreground_color, + use_thick_lines, + identification_string + ) +{ + Test_Tell("SegmentArcNormalized creator\n" << flush); + Check_Pointer(this); + + //----------------------------------------------------------- + // Build connection to value + //----------------------------------------------------------- + GaugeConnection + *connection; + + connection = new + GaugeConnectionDirectOf(0, ¤tValue, value_pointer); + Check(connection); + Register_Object(connection); + + AddConnection(connection); + + Check_Fpu(); +} diff --git a/restoration/source410/UNRESOLVED-LEDGER.txt b/restoration/source410/UNRESOLVED-LEDGER.txt index 6db4840d..a5dc0d25 100644 --- a/restoration/source410/UNRESOLVED-LEDGER.txt +++ b/restoration/source410/UNRESOLVED-LEDGER.txt @@ -1,52 +1,219 @@ -BTCameraDirector::DefaultData -BTPlayer::DefaultData -BackgroundBitmap::methodDescription -BackgroundFilledRect::methodDescription -BackgroundLine::methodDescription -BackgroundPixelmap::methodDescription -BackgroundReconfig::methodDescription -BackgroundRect::methodDescription -BarGraphPixelMapScalar::methodDescription -BarGraphSolidScalar::methodDescription -ColorState::methodDescription -CulturalIcon::DefaultData -DigitalClock::methodDescription -DropZone::DefaultData -EulerAngles::Identity -Explosion::DefaultData -L4Application::ClassDerivations -L4Application::MessageHandlers -L4Application::missionReviewMode -L4Application::rioPlaybackFileName -L4Application::rioRecordingFileName -Landmark::DefaultData -Mech::DefaultData -MechRIOMapper::DefaultData -MechThrustmasterMapper::DefaultData -Missile::DefaultData -NetworkClient::ClassDerivations -NumericDisplayInteger::methodDescription -NumericDisplayScalar::methodDescription -NumericDisplaySpeed::methodDescription -Player::AttributeIndex -Player::ClassDerivations -Player::DefaultData -Player::MessageHandlers -Projectile::DefaultData -Quaternion::Identity -RandomGenerator::Index -RankAndScore::methodDescription -Receiver::ClassDerivations -Receiver::DefaultData -Receiver::MessageHandlers -SegmentArcNormalized::methodDescription -Subsystem::ClassDerivations -Team::AttributeIndex -Team::ClassDerivations -Team::DefaultData -Team::MessageHandlers -Terrain::DefaultData -TwoState::methodDescription -UnscalableTerrain::ClassDerivations -UnscalableTerrain::DefaultData -YawPitchRoll::Identity +AudioControlMixer::AudioControlMixer(PlugStream*,Entity*) +AudioControlMixer::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long) +AudioControlMultiplier::AudioControlMultiplier(PlugStream*,Entity*) +AudioControlMultiplier::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long) +AudioControlSend::AudioControlSend(PlugStream*,Entity*) +AudioControlSend::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long) +AudioControlSmoother::AudioControlSmoother(PlugStream*,Entity*) +AudioControlSmoother::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long) +AudioControlSplitter::AudioControlSplitter(PlugStream*,Entity*) +AudioControlSplitter::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long) +AudioControlsButtonMessageWatcher::AudioControlsButtonMessageWatcher(PlugStream*,Entity*) +AudioLFO::AudioLFO(PlugStream*,Entity*) +AudioLFO::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long) +AudioMessageWatcher::AudioMessageWatcher(PlugStream*,Entity*) +AudioMessageWatcher::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long) +AudioRenderer::AudioRenderer(float) +AudioRenderer::ExecuteImplementation(float,RendererOrigin__InterestingEntityIterator*) +AudioRenderer::FlushAudioMessages(AudioSource*) +AudioRenderer::Initialize() +AudioRenderer::LinkToEntity(Entity*) +AudioRenderer::MakeAudioHead() +AudioRenderer::PostAudioRequestMessage(AudioSource*,AudioSource__RequestMessage*) +AudioRenderer::ProcessAudioRequestMessage() +AudioRenderer::StartEntityEffectImplementation(Entity*,DamageZone*,int) +AudioRenderer::TestInstance() const +AudioRenderer::~AudioRenderer() +AudioResourceSelector::AudioResourceSelector(PlugStream*,Entity*) +AudioResourceSelector::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long) +AudioSampleAndHold::AudioSampleAndHold(PlugStream*,Entity*) +AudioSampleAndHold::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long) +BTCameraDirector::BTCameraDirector(Player__MakeMessage*,Entity__SharedData&) +BTCameraDirector::Make(Player__MakeMessage*) +BTL4GaugeRenderer::BTL4GaugeRenderer() +BTL4Mission::BTL4Mission(NotationFile*,ResourceFile*) +BTL4VideoRenderer::BTL4VideoRenderer(float,float,RendererPriority,InterestType,int) +BTPlayer::BTPlayer(BTPlayer__MakeMessage*,Entity__SharedData&) +BTPlayer::Make(BTPlayer__MakeMessage*) +BitMap::Make(const char*) +BitMap::Make(int) +BoundingBoxTreeNode::GetAllocatedMemory() +CString::operator =(const CString&) +CString::operator =(const char*) +CStringRepresentation::CStringRepresentation() +CStringRepresentation::CStringRepresentation(const char*) +CStringRepresentation::Compare(const CStringRepresentation&) const +CStringRepresentation::GetNthToken(unsigned int,char*) const +CStringRepresentation::~CStringRepresentation() +Convert_From_Ascii(const char*,CString*) +Exit(int) +ExplosionTable::CreateStreamedExplosionTable(ResourceFile*,CString,NotationFile*,CString,MemoryStream*) +ExplosionTable::ExplosionTable(MemoryStream*) +Fail_To_Debugger(char*,char*,int) +Gauge::AddConnection(GaugeConnection*) +Gauge::DiscernTier() +Gauge::RemoveAllConnections() +Gauge::RemoveConnection(int) +Gauge::ReportProfile() +Gauge::ShowInstance(char*) +Gauge::Update(unsigned int) +Gauge::UpdateProfile(float) +GaugeBackground::GaugeBackground(unsigned long,GaugeRenderer*,unsigned int,const char*) +GaugeBase::BecameInactive() +GaugeBase::DiscernTier() +GaugeBase::Inactivate() +GaugeBase::LinkToEntity(Entity*) +GaugeBase::NotifyOfBecomingUninterestingEntity(Entity*) +GaugeBase::NotifyOfNewInterestingEntity(Entity*) +GaugeBase::ReportProfile() +GaugeBase::TestInstance() const +GaugeBase::Update(unsigned int) +GaugeBase::UpdateProfile(float) +GaugeBase::~GaugeBase() +GaugeConnection::GaugeConnection(int) +GaugeConnection::ShowInstance(char*) +GaugeConnection::~GaugeConnection() +GaugeRenderer::Configure(const char*,Entity*) +GaugeRenderer::ExecuteBackground() +GaugeRenderer::ExecuteForeground() +GaugeRenderer::ExecuteImplementation(float,RendererOrigin__InterestingEntityIterator*) +GaugeRenderer::GaugeRenderer() +GaugeRenderer::GetGraphicsPort(int) +GaugeRenderer::LinkToEntity(Entity*) +GaugeRenderer::LoadMissionImplementation(Mission*) +GaugeRenderer::LocalEmergencyShutdown() +GaugeRenderer::NotifyOfBecomingUninterestingEntity(Entity*) +GaugeRenderer::NotifyOfNewInterestingEntity(Entity*) +GaugeRenderer::Remove(unsigned int) +GaugeRenderer::ResumeImplementation() +GaugeRenderer::ShutdownImplementation() +GaugeRenderer::StartEntityAlarmImplementation(Entity*,Subsystem*,int,int) +GaugeRenderer::StopEntityAlarmImplementation(Entity*,Subsystem*,int) +GaugeRenderer::SuspendImplementation() +GaugeRenderer::TestInstance() const +GaugeRenderer::~GaugeRenderer() +GraphicGauge::GraphicGauge(unsigned int,unsigned long,GaugeRenderer*,unsigned int,int,const char*) +GraphicGauge::ShowInstance(char*) +GraphicGauge::TestInstance() const +GraphicGauge::~GraphicGauge() +GraphicGaugeBackground::GraphicGaugeBackground(unsigned long,GaugeRenderer*,unsigned int,int,const char*) +GraphicsDisplay::GraphicsDisplay(int,int) +GraphicsDisplay::ShowInstance(char*) +GraphicsDisplay::TextBounds(int,int,GraphicsDisplay::Justification,char) +GraphicsDisplay::Update(int) +GraphicsDisplay::WaitForUpdate() +GraphicsDisplay::~GraphicsDisplay() +GraphicsPort::GraphicsPort(GraphicsDisplay*,const char*) +GraphicsPort::SetColor(PaletteTriplet*,int) +GraphicsPort::ShowInstance(char*) +GraphicsPort::TextBounds(int,int,GraphicsDisplay::Justification,char) +GraphicsPort::~GraphicsPort() +GraphicsView::GraphicsView(GraphicsPort*) +GraphicsView::~GraphicsView() +L4Application::Initialize() +L4Application::KeyCommandMessageHandler(ReceiverDataMessageOf*) +L4Application::L4Application(ResourceFile*,ApplicationID,RegisteredClass::ClassID,Receiver__SharedData) +L4Application::LightsOutMessageHandler(Receiver__Message*) +L4Application::MakeAndLinkViewpointEntity(Entity__MakeMessage*) +L4Application::MakeIntercomManager() +L4Application::MakeNetworkManager() +L4Application::RunMissionMessageHandler(Application__RunMissionMessage*) +L4Application::StopMissionMessageHandler(Application__StopMissionMessage*) +L4Application::Terminate() +L4Application::~L4Application() +LookupTable::Search(const char*) +MakePathedFilename(const char*,const char*) +Mech::Make(Mech__MakeMessage*) +Mech::SetMappingSubsystem(Subsystem*) +MechRIOMapper::MechRIOMapper(Mech*,int,CString,RegisteredClass::ClassID,Simulation__SharedData) +MechThrustmasterMapper::MechThrustmasterMapper(Mech*,int,CString,RegisteredClass::ClassID,Simulation__SharedData) +MemoryStream_Read(MemoryStream*,CString*) +MemoryStream_Write(MemoryStream*,const CStringRepresentation&) +Missile::Make(Mover__MakeMessage*) +NetNub::SendCommand() +NetworkClient::NetworkClient(RegisteredClass::ClassID,Receiver__SharedData,NetworkClient::ClientID) +NetworkClient::ReceiveNetworkPacket(NetworkPacket*,Receiver__Message*) +NetworkClient::~NetworkClient() +NetworkManager::Broadcast(Receiver__Message*,NetworkClient::ClientID) +NetworkManager::NetworkManager(Receiver__SharedData&) +NetworkManager::RoutePacket() +ObjectStream::BuildFromPageImplementation(NameList*,int,unsigned long) +ObjectStream::MakeObjectImplementation(int) +Palette8::BuildColorRange(int,int,PaletteTriplet,PaletteTriplet) +Palette8::Make(const char*) +Palette8::Make(int) +Palette8::Palette8() +Palette8::~Palette8() +ParameterDescription::~ParameterDescription() +PixelMap16::PixelMap16(int,int) +PixelMap16::ShowInstance(char*) +PixelMap16::~PixelMap16() +PixelMap8::Make(const char*) +PixelMap8::Make(int) +PixelMap8::PixelMap8(int,int) +PixelMap8::ShowInstance(char*) +PixelMap8::~PixelMap8() +PlugStream::AddGlobalObjectID(unsigned long,const CString&) +PlugStream::AddGlobalPlug(Plug*,unsigned long) +PlugStream::AddLocalObjectID(unsigned long,const CString&) +PlugStream::AddLocalPlug(Plug*,unsigned long) +PlugStream::BuildFromNotationFile(NotationFile*,ResourceFile*) +PlugStream::CreateObjects() +PlugStream::FindObjectID(const CString&) +PlugStream::FindPlug(unsigned long) +PlugStream::PlugStream() +PlugStream::PlugStream(ResourceDescription*) +PlugStream::TestInstance() const +PlugStream::~PlugStream() +PlugStreamManager::FindPlug(unsigned long) +PlugStreamManager::FindPlugName(const CString&) +PlugStream_FindEntryAndWriteObjectID(PlugStream*,NameList*,const CString&) +Projectile::Make(Mover__MakeMessage*) +Ray::LengthToClosestPointTo(const Point3D&) +Ray::Project(float,Point3D*) +ResourceDescription::LoadResource() +ResourceFile::AddResource(const char*,int,int,unsigned long,const void*,unsigned int,int) +ResourceFile::AddResourceList(const char*,int,int,unsigned long,const int*,int,int) +ResourceFile::AddResourceMemoryStream(const char*,int,int,unsigned long,MemoryStream*,int) +ResourceFile::FindResourceDescription(const char*,int,int) +ResourceFile::FindResourceDescription(int) +ResourceFile::ReleaseUnlockedResources() +ResourceFile::SearchList(int,const char*) +ResourceFile::SearchList(int,int) +ScenarioRole::ScenarioRole(const CString&,const CString&) +_Net_Common_Ptr +_PCSPAKActive +_PCSPAKErrors +_PCSPAKIRQState +_PCSPAKInit +_PCSPAKReceive +_PCSPAKSend +_PCSPAKSetDTR +_PCSPAKTerm +_PCSPAKTransmitCount +_PCSerialActive +_PCSerialFlowControl +_PCSerialInit +_PCSerialSend +_PCSerialTerm +_PCSerialTransmitCount +_PC_Joystick1_Raw_X +_PC_Joystick1_Raw_Y +_PC_Joystick2_Raw_Y +_PC_Joystick_Buttons +_PC_Joystick_Mask +_PC_Joystick_Update +_SVGAFunkyVideo +_SVGASetMode +_SVGASetPage +_SVGASetSplitterClock +_SVGATransfer32 +_SVGATransfer32x +_SVGAWriteFullPalette +_SVGAWritePaletteMask +_SVGAZeroPalette +_iThinkIRQIsOn +_pcspakCharactersSent +_sosMIDIAWE32ReleaseSBKFiles +_sosMIDIAWE32SetSBKFile +operator +(const CStringRepresentation&,const CStringRepresentation&) diff --git a/restoration/source410/backdate.py b/restoration/source410/backdate.py index c47265a2..d7daa60e 100644 --- a/restoration/source410/backdate.py +++ b/restoration/source410/backdate.py @@ -19,7 +19,30 @@ def main(): donor, out = sys.argv[1], sys.argv[2] name = os.path.splitext(os.path.basename(out))[0].upper() guard = "%s_HPP" % name - body = open(donor, "r", errors="replace").read().splitlines() + text = open(donor, "r", errors="replace").read() + # WinTesla wrapped the 1995 static objects in accessor functions (its + # static-init-order fix); unwrap them back to plain 1995 definitions. + text = re.sub( + r"Derivation\s*\*\s*(\w+)::GetClassDerivations\(\)\s*" + r"\{\s*static\s+Derivation\s+\w+\s*\(([^;]*?)\);\s*return\s*&\w+;\s*\}", + r"Derivation\n\t\1::ClassDerivations(\2);", + text, flags=re.S) + text = re.sub( + r"(?:Receiver::)?MessageHandlerSet\s*&?\s*(\w+)::GetMessageHandlers\(\)\s*" + r"\{\s*static\s+(?:\w+::)?MessageHandlerSet\s+\w+\s*\(([^;]*?)\);\s*return\s*\w+;\s*\}", + r"\1::MessageHandlerSet\n\t\1::MessageHandlers(\2);", + text, flags=re.S) + text = re.sub( + r"(?:\w+::)?AttributeIndexSet\s*&?\s*(\w+)::GetAttributeIndex\(\)\s*" + r"\{\s*static\s+(?:\w+::)?AttributeIndexSet\s+\w+\s*\(([^;]*?)\);\s*return\s*\w+;\s*\}", + r"\1::AttributeIndexSet\n\t\1::AttributeIndex(\2);", + text, flags=re.S) + text = re.sub( + r"MemoryBlock\s*\*\s*(\w+)::GetAllocatedMemory\(\)\s*" + r"\{\s*static\s+MemoryBlock\s+\w+\s*\(([^;]*?)\);\s*return\s*&\w+;\s*\}", + r"MemoryBlock\n\t\1::AllocatedMemory(\2);", + text, flags=re.S) + body = text.splitlines() res = [] warned = set() for line in body: @@ -36,6 +59,26 @@ def main(): res.append("#\tendif") continue # post-1994 C++ the 4.52 compiler rejects: de-modernize + line = re.sub(r"\b(\w+)::GetClassDerivations\(\)", r"\1::ClassDerivations", line) + line = re.sub(r"\b(\w+)::GetMessageHandlers\(\)", r"\1::MessageHandlers", line) + line = re.sub(r"\b(\w+)::GetAttributeIndex\(\)", r"\1::AttributeIndex", line) + line = re.sub(r"\b(\w+)::GetAllocatedMemory\(\)", r"\1::AllocatedMemory", line) + # header-side: 2007 accessor DECLARATIONS -> 1995 static objects + line = re.sub(r"static\s+Derivation\s*\*\s*GetClassDerivations\(\);", + "static Derivation ClassDerivations;", line) + line = re.sub(r"static\s+(?:\w+::)?MessageHandlerSet\s*&?\s*GetMessageHandlers\(\);", + "static MessageHandlerSet MessageHandlers;", line) + line = re.sub(r"static\s+(?:\w+::)?AttributeIndexSet\s*&?\s*GetAttributeIndex\(\);", + "static AttributeIndexSet AttributeIndex;", line) + line = line.replace("Shutdown(int remainingApps);", "Shutdown(int remainingApps = 0);") + line = re.sub(r"\*?\s*(? [S410dir] case "$1" in filestrm.cpp) echo "$3/FILESTRM.CPP"; return;; # BT pair = post-4.10 drift l4vidper.cpp|l4tsdpl.cpp) return;; # not in mungal4.lib + filestub.cpp) return;; # stub.lib member (prebuilt obj) esac for d in "$2" "$4" "$3"; do # BT first, then source410, then RP [ -z "$d" ] && continue diff --git a/restoration/source410/override/FILESTRM.HPP b/restoration/source410/override/FILESTRM.HPP index 279341f9..9d321792 100644 --- a/restoration/source410/override/FILESTRM.HPP +++ b/restoration/source410/override/FILESTRM.HPP @@ -34,7 +34,7 @@ public: Logical TestInstance() const; -protected: +public: int fileHandle; Logical readOnly;