Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
338 lines
8.8 KiB
C++
338 lines
8.8 KiB
C++
//===========================================================================//
|
|
// File: simulate.cc //
|
|
// Project: MUNGA Brick: Model Manager //
|
|
// Contents: Implementation details of model class //
|
|
//---------------------------------------------------------------------------//
|
|
// Date Who Modification //
|
|
// -------- --- ---------------------------------------------------------- //
|
|
// 01/25/95 JMA Initial coding. //
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1995, Virtual World Entertainment, Inc. All Rights reserved //
|
|
// PROPRIETARY AND CONFIDENTIAL //
|
|
//===========================================================================//
|
|
|
|
#include "AdeptHeaders.hpp"
|
|
#include "State.hpp"
|
|
|
|
//#############################################################################
|
|
//########################### StateEngine ###############################
|
|
//#############################################################################
|
|
|
|
//#############################################################################
|
|
// Virtual Data support
|
|
//
|
|
const StateEngine::StateEntry
|
|
StateEngine::StateEntries[]=
|
|
{
|
|
STATE_ENTRY(StateEngine, Uninitialized)
|
|
};
|
|
|
|
StateEngine::ClassData*
|
|
StateEngine::DefaultData = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
StateEngine::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
StateEngineClassID,
|
|
"Adept::StateEngine",
|
|
Plug::DefaultData,
|
|
ELEMENTS(StateEntries), StateEntries,
|
|
Make,
|
|
&StateEngine::FactoryRequest::ConstructFactoryRequest
|
|
);
|
|
Register_Object(DefaultData);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
StateEngine::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
StateEngine*
|
|
StateEngine::Make(const FactoryRequest *request)
|
|
{
|
|
Check_Object(request);
|
|
gos_PushCurrentHeap(g_LibraryHeap);
|
|
StateEngine *engine = new StateEngine(DefaultData, request);
|
|
gos_PopCurrentHeap();
|
|
return engine;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
StateEngine::Save(FactoryRequest *request)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(request);
|
|
|
|
request->currentState = currentState;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
StateEngine::Reuse(const FactoryRequest *request)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(request);
|
|
|
|
RequestState(request->currentState);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
StateEngine::~StateEngine()
|
|
{
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
StateEngine::StateEngine(
|
|
ClassData *class_data,
|
|
int state_number
|
|
):
|
|
Plug(class_data)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(class_data);
|
|
|
|
oldState = state_number;
|
|
Verify(static_cast<unsigned>(oldState) < class_data->stateCount);
|
|
currentState = state_number;
|
|
Verify(static_cast<unsigned>(currentState) < class_data->stateCount);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
StateEngine::StateEngine(
|
|
ClassData *class_data,
|
|
const FactoryRequest *request
|
|
):
|
|
Plug(class_data)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(class_data);
|
|
Check_Object(request);
|
|
|
|
currentState = request->currentState;
|
|
Verify(static_cast<unsigned>(currentState) < class_data->stateCount);
|
|
oldState = UninitializedState;
|
|
Verify(static_cast<unsigned>(oldState) < class_data->stateCount);
|
|
}
|
|
|
|
//#############################################################################
|
|
// State stuff
|
|
//
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
StateEngine::RequestState(
|
|
int new_state,
|
|
void*
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(GetClassData());
|
|
Verify(new_state < GetClassData()->stateCount);
|
|
|
|
oldState = currentState;
|
|
return currentState = new_state;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
#if !defined(Spew)
|
|
void
|
|
Spew(
|
|
const char* group,
|
|
StateEngine &state_indicator
|
|
)
|
|
{
|
|
Check_Object(&state_indicator);
|
|
const StateEngine::StateEntry *state =
|
|
state_indicator.GetStateEntry(state_indicator.GetState());
|
|
Check_Pointer(state);
|
|
SPEW((group, "%s+", state->stateName));
|
|
}
|
|
#endif
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
StateEngine::TestInstance()
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|
|
//#############################################################################
|
|
//################### StateEngine::ClassData #####################
|
|
//#############################################################################
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
StateEngine__ClassData::StateEngine__ClassData(
|
|
RegisteredClass::ClassID class_id,
|
|
const char* name,
|
|
Plug::ClassData *parent,
|
|
int count,
|
|
const StateEngine::StateEntry index_table[],
|
|
StateEngine::Factory engine_factory,
|
|
StateEngine::FactoryRequest::Factory request_factory
|
|
):
|
|
Plug__ClassData(class_id, name, parent),
|
|
engineFactory(engine_factory),
|
|
requestFactory(request_factory)
|
|
{
|
|
Check_Pointer(this);
|
|
//
|
|
//------------------------------
|
|
// Only the root can be empty...
|
|
//------------------------------
|
|
//
|
|
stateCount = 0;
|
|
stateEntries = NULL;
|
|
StateEngine__ClassData *inheritance = NULL;
|
|
int i;
|
|
if (parent != Plug::DefaultData)
|
|
{
|
|
Check_Object(parent);
|
|
inheritance = Cast_Pointer(StateEngine__ClassData *, parent);
|
|
Check_Object(inheritance);
|
|
if (!count)
|
|
{
|
|
stateCount = inheritance->stateCount;
|
|
goto Skip_Mix;
|
|
}
|
|
}
|
|
|
|
//
|
|
//-------------------------------------------------------
|
|
// Find out the highest message type we have to deal with
|
|
//-------------------------------------------------------
|
|
//
|
|
for (i=0; i<count; ++i)
|
|
{
|
|
if (index_table[i].stateNumber > stateCount)
|
|
{
|
|
stateCount = index_table[i].stateNumber;
|
|
}
|
|
}
|
|
++stateCount;
|
|
if (inheritance)
|
|
{
|
|
Check_Object(inheritance);
|
|
Verify(inheritance->stateCount + count == stateCount);
|
|
#if defined(_ARMOR)
|
|
i = inheritance->stateCount;
|
|
goto Check_Table;
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
Verify(stateCount == count);
|
|
#if defined(_ARMOR)
|
|
i = 0;
|
|
Check_Table:
|
|
while (i < stateCount)
|
|
{
|
|
int j;
|
|
for (j=0; j<count; ++j)
|
|
{
|
|
if (index_table[j].stateNumber == i)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (j == count)
|
|
{
|
|
break;
|
|
}
|
|
++i;
|
|
}
|
|
Verify(i == stateCount);
|
|
#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
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
Skip_Mix:
|
|
stateEntries = new StateEngine::StateEntry[stateCount];
|
|
Register_Pointer(stateEntries);
|
|
i = 0;
|
|
if (inheritance)
|
|
{
|
|
for (; i<inheritance->stateCount; ++i)
|
|
{
|
|
stateEntries[i] = inheritance->stateEntries[i];
|
|
}
|
|
}
|
|
|
|
//
|
|
//----------------------------------------------------------------------
|
|
// Step through the new table supplied, placing each handler in the slot
|
|
// determined by the message type
|
|
//----------------------------------------------------------------------
|
|
//
|
|
for (i=0; i<count; ++i)
|
|
{
|
|
Verify(!inheritance || index_table[i].stateNumber >= inheritance->stateCount);
|
|
stateEntries[index_table[i].stateNumber] = index_table[i];
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
StateEngine__ClassData::~StateEngine__ClassData()
|
|
{
|
|
if (stateEntries)
|
|
{
|
|
Unregister_Pointer(stateEntries);
|
|
delete[] stateEntries;
|
|
}
|
|
};
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
const StateEngine::StateEntry*
|
|
StateEngine__ClassData::FindStateEntry(const char* state_name)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(state_name);
|
|
|
|
for (int state=0; state<stateCount; ++state)
|
|
{
|
|
if (!_stricmp(state_name, stateEntries[state].stateName))
|
|
{
|
|
return &stateEntries[state];
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
StateEngine__ClassData::TestInstance()
|
|
{
|
|
Verify(IsDerivedFrom(StateEngine::DefaultData));
|
|
}
|