Files
RP412/MUNGA_L4/L4VIDEO.h
T
CydandClaude Opus 4.8 4abbf8879f Initial import of Red Planet v4.10 Win32 source
Imports the current Win32 source for the pod-racing game 'Red Planet',
built on the MUNGA engine and its L4 (Win32/DirectX) platform layer:

- MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend
- RP / RP_L4: Red Planet game logic and Win32 application
- DivLoader, Setup1: asset loader and installer project
- lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies

Removed stale Subversion metadata and added .gitignore/.gitattributes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 07:59:51 -05:00

578 lines
18 KiB
C++

#pragma once
#include "..\munga\vidrend.h"
#include "..\munga\rotation.h"
#include "..\munga\reticle.h"
#include "..\munga\graph2d.h"
#include "..\munga\simulate.h"
#include "l4vidrnd.h"
#include "..\munga\tree.h"
#include "..\munga\table.h"
#include "l4d3d.h"
#include <string>
#include <hash_map>
#include <vector>
using namespace std;
using namespace stdext;
//STUBBED: DPL RB 1/14/07
//once the stubs are removed, the following can be removed
#define char8 unsigned char
// RB 1/14/07
//#include <dpl\dpl.h>
//#include <dpl\dpl_2d.h>
#include <D3DX9.h>
#include <D3DX9math.h>
class NotationFile;
#define INTERSECT_ALL (0xFFFFFFFF)
//##########################################################################
// Declaration of dpl callback function that performs in-place text
// substitution on all material names before they are looked up.
// There must be at least MATERIAL_NAME_LENGTH bytes available at source!
//
#define MATERIAL_NAME_BUFFER_LENGTH 256
char*
substituteMaterial(char *source);
void loadTables();
const char* opMaterialName(const char *fileName, int opId);
struct ReplacementMaterialData
{
float r, g, b;
string texName;
};
hash_map<string, hash_map<int, string>> *gOpNames;
hash_map<string, ReplacementMaterialData> *gReplacementData;
//##########################################################################
// This structure is attached to DPL nodes so we can put information in them
// on what entity the node is part of and what damage zone it belongs to.
//
#define MAX_DZ_NAME_LENGTH 25
struct dpl_tracker
{
Entity
*This_Entity; // The entity this is part of
char
dz_name[MAX_DZ_NAME_LENGTH]; // this is temporary, to make testing easier
int
Damage_Zone_Number; // number of this damage zone
};
//-----------------------------------------------------------------------------
//--------------------------DPL video resource object--------------------------
//-----------------------------------------------------------------------------
//##########################################################################
//########################## L4VideoObject ###########################
//##########################################################################
#define MAX_OBJECT_FILENAME_LENGTH 15
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This class gets stored in a resource so it is derived from nothing.
//
class L4VideoObject
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction, Destruction and testing
//
public:
enum ResourceType
{
Unknown,
Skeleton,
Object,
Rubble,
VidFile
};
enum RendererModes // bit flags
{
Normal = 0x000,
BillboardXAxis = 0x001,
BillboardYAxis = 0x002,
BillboardZAxis = 0x004,
BillboardObject = (BillboardXAxis | BillboardYAxis | BillboardZAxis),
BlinkObject = 0x008,
IntersectImmune = 0x010
};
// L4VideoObject();
L4VideoObject(
const char *filename,
ResourceType resource_type,
Enumeration renderer_modes, // RendererModes
float blink_period = 0.0f,
float percent_time_on = 0.0f
);
~L4VideoObject();
const char*
GetObjectFilename() const
{ return objectFilename; }
char*
GetObjectFilename()
{ return objectFilename; }
ResourceType
GetResourceType() const
{ return resourceType; }
Enumeration // RendererModes
GetRendererModes() const
{ return rendererModes; }
Logical
TestInstance() const;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Implementations
//
// private:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Private data
//
private:
char
objectFilename[MAX_OBJECT_FILENAME_LENGTH];
ResourceType
resourceType;
Enumeration // RendererModes
rendererModes; // bit flags (see RendererModes)
float
blinkPeriod, // cycle length in seconds
percentTimeOn; // percent of cycle on
};
//##########################################################################
//####################### L4VideoObjectWrapper #######################
//##########################################################################
class L4VideoObjectWrapper:
public Plug
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction, Destruction and testing
//
public:
// L4VideoObjectWrapper();
L4VideoObjectWrapper(
L4VideoObject *video_object,
Logical delete_object = False
);
~L4VideoObjectWrapper();
L4VideoObject*
GetVideoObject() const
{ Check(this); return videoObject; }
Logical
TestInstance() const;
static int
BuildVideoObjectChainFromResource(
ChainOf<L4VideoObjectWrapper*> *video_chain,
ResourceDescription *video_resource
);
static void
DeleteVideoObjectChain(
ChainOf<L4VideoObjectWrapper*> *video_chain
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Implementations
//
// public:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Private data
//
private:
L4VideoObject
*videoObject;
Logical
deleteObject;
};
//
//-----------------------------------------------------------------------------
//--------------Actual DPL video renderer class starts below-------------------
//-----------------------------------------------------------------------------
//
class DPLObjectCacheLine:
public Plug
{
public:
DPLObjectCacheLine(
const CString &object_name,
dpl_OBJECT *object_ptr)
{
objectName = object_name;
objectPointer = object_ptr;
};
~DPLObjectCacheLine(){};
Logical
TestInstance() const
{
Check(&objectName);
Check_Pointer(objectPointer);
return True;
};
CString
objectName;
dpl_OBJECT
*objectPointer;
};
class DPLJointToDCSTranslator:
public Plug
{
public:
DPLJointToDCSTranslator(
Entity *entity, // The entity to translate
dpl_DCS *dcs_array[]); // Array of DCS's to translate
~DPLJointToDCSTranslator();
Logical
TestInstance() const;
int
DCSCount;
dpl_DCS
**translation_array; // array to translate from joint # to DCS*
};
//##########################################################################
//########################### DPLRenderer ############################
//##########################################################################
#define DELAY_DCS_FLUSH_ARRAY_SIZE 100
#define MAX_PSFX_COUNT 40
#define MAX_INDIE_EMITTERS 32
class DPLRenderer :
public VideoRenderer
{
public:
//
// Construction, Destruction and test instance declarations
//
DPLRenderer(HWND hWnd, unsigned int screenWidth, unsigned int screenHeight, bool fullscreen, InterestType interest_type, InterestDepth depth_calibration);
~DPLRenderer();
virtual vector<MONITORINFO> MonitorsCreateAll(int &monitorCount);
Logical TestInstance() const;
//
// These routines are the renderer side of the culling system, they are
// used to setup the stored data on the eyepoint's transformation matrices
//
inline Scalar GetCurrentFrameTime() { return(currentFrameTime); } // Returns the time at the start of the frame
inline LinearMatrix* GetWorldToEyeMatrix() { return(&worldToEyeMatrix); } // Returns the world to eye matrix (for culling)
inline Scalar GetViewRatio() { return(viewRatio); } // Returns tan(viewAngle/2.0)
void SetupCull(); // Sets up the WorldToEyeMatrix each frame
//
// These routines manage the renderer's list of renderables that need to be
// executed each frame. For the moment these routines just blindly add and
// remove the items from the dplRenderableSocket
//
void AddDynamicRenderable(Component *my_renderable);
void RemoveDynamicRenderable(Component *my_renderable);
//
// These routines are used for tracking target frame time
//
void ResetStatistics();
void ReportStatistics();
//
// Other renderer stuff
//
dpl_ZONE* MakeNewZone();
void MarkDCSHiearchy(dpl_DCS *root_DCS, Entity *entity);
void FlushBitSliceTexture(unsigned int *local_storage);
void LoadBitSliceTexture(BitMap *bitmap_to_load, LPDIRECT3DTEXTURE9 local_storage);
void SetViewAngle(Degree new_angle);
unsigned int* MakeBitSliceStorage();
void SortAndReloadNameBitmaps();
void LoadNameBitmaps();
void LoadOrdinalBitmaps();
void DPLIndependantEffect(Point3D location, // Location of the effect in world space
int effect_number, // DPL effect number to trigger at this location
dpl_DCS *my_dcs = NULL,
int subid = 0); // inserted into third byte of effect id.
void DPLIndependantPFX(Point3D location, // Location in space to trigger the effect
dpl_PARTICLESTART_EFFECT_INFO *psfx_definition, // Description of the pfx
dpl_DCS *my_dcs = NULL, // optional DCS to issue from
int subid = 0); // inserted into third byte of effect id.
void DPLDelayDCSFlush(dpl_DCS *my_dcs); // The DCS we want to remember for later
void DPLDoDCSBatchFlush(); // Flush the dcs's remembered by DPLDelayDCSFlush
void DPLReportFreeMemory(std::ostream &output); // Report current free memory in card
void DPLReportPerfStats(std::ostream &output); // Report performance statistics
void DPLToggleWireframe(); // Toggle state of dpl wireframe
void DPLTogglePVision(); // Toggle state of dpl pvision
void DPLFrameDump(Logical antialias); // Write framedump to targa file
InnerProjectileRenderable* GetProjectile(
d3d_OBJECT *graphical_object, // object to hang on the DCS, may be a list later <NULL>
bool isDeathZone); // DPL Zone this stuff will live in (for culling)
void ReleaseProjectile(InnerProjectileRenderable *inner_projectile);
int GetUniqueID();
dpl_PARTICLESTART_EFFECT_INFO* ReadPSFX(const char *file_name); // Name of the file containing the PSFX description
dpl_OBJECT* GetCachedObject(const CString &object_name); // Name of the object we want to get
void PutCachedObject(
const CString &object_name, // Name of the object we will cache
dpl_OBJECT *object_pointer); // pointer to the object being cached
static ResourceDescription::ResourceID CreateModelVideoStreamResource(ResourceFile *resource_file, const char *model_name, NotationFile *model_file, const ResourceDirectories *directories);
void CacheExplosionScripts(int script_select); // The script to be cached
enum FogStyle
{
updateFogSetting,
noUpdateFogSetting,
searchLightOnFogStyle,
searchLightOffFogStyle,
winnersCircleFogStyle
};
void SetFogStyle(FogStyle my_fog);
void GetCurrentFogSettings(float *fogRed, float *fogGreen, float *fogBlue, float *fogNear, float *fogFar);
void SetCurrentFogLimits(float fogNear, float fogFar);
LPDIRECT3DTEXTURE9 GetNameTexture(int playerIndex) { return mNameTextures[playerIndex]; }
inline LPDIRECT3DDEVICE9 GetDevice() { return mDevice; }
inline LPD3DXMATRIXSTACK GetMatrixStack() { return m_MatrixStack; }
inline void AddRenderable(HierarchicalDrawComponent *component) { mRenderables.Add(component); }
void AddToPassList(d3d_OBJECT *object, int pass);
void AddStaticObject(d3d_OBJECT *object);
void RecurseStaticObject(HierarchicalDrawComponent *obj);
virtual void ConsolidateStaticObjects();
inline unsigned int GetWidth() { return x_size; }
inline unsigned int GetHeight() { return y_size; }
inline int *GetSecondaryIndex() { return mSecondaryIndex; }
inline int *GetAux1Index() { return mAux1Index; }
inline int *GetAux2Index() { return mAux2Index; }
private:
d3d_OBJECT *ConsolidateSingleObject(LPD3DXMESH *meshes, D3DXMATRIX *transforms, UINT startMesh, UINT meshCount, hash_map<DWORD, hyper> subsetHash, hash_map<hyper, DWORD> hashToOp, vector<L4DRAWOP*> finalOps);
void ExplosionScripts(Entity *entity, // The entity we are dealing with
ResourceDescription *model_resource, // Pointer to the video resource
ViewFrom view_type, // Type of reference (inside/outside...etc.)
int script_select);
void DPLRenderer::DPLReadINIPage(NotationFile *master_notation_file, const char *starting_page_name, Mission *mission, Logical debug_print);
void DPLRenderer::DPLReadEnvironment(Mission *mission);
void ShutdownImplementation();
void SuspendImplementation();
void ResumeImplementation();
void ExecuteImplementation(RendererComplexity complexity_update, RendererOrigin::InterestingEntityIterator *iterator);
void ExecuteIdle();
hyper HashAdd(hyper input, char data);
hyper HashDrawOp(L4DRAWOP *op);
//Damn eye renderable is our camera and I hate it
public:
DPLEyeRenderable *mCamera;
float GetCloudRed() { return mCloudRed;}
float GetCloudGreen() { return mCloudGreen;}
float GetCloudBlue() { return mCloudBlue;}
float GetCloudEmitRed() { return mCloudEmitRed; }
float GetCloudEmitGreen() { return mCloudEmitGreen; }
float GetCloudEmitBlue() { return mCloudEmitBlue; }
void SetCoreRenderStates();
private:
//
// Direct3D Required Variables
//
LPDIRECT3DDEVICE9 mDevice;
D3DPRESENT_PARAMETERS mPresentParams;
unsigned int x_size;
unsigned int y_size;
SChainOf<HierarchicalDrawComponent *> mRenderables;
d3d_OBJECT *mRenderLists[PASS_TOTAL_COUNT];
LPD3DXMATRIXSTACK m_MatrixStack;
D3DXMATRIX mProjectionMatrix;
D3DXMATRIX mDecalProjectionMatrix;
float mDecalEpsilon;
void FindBestAdapterIndices(bool isWindowed);
float mCloudRed, mCloudGreen, mCloudBlue;
float mCloudEmitRed, mCloudEmitGreen, mCloudEmitBlue;
int *mPrimaryIndex, *mSecondaryIndex, *mAux1Index, *mAux2Index;
// these are used for the map rendering
d3d_OBJECT *mStaticObjectsHead;
int mStaticObjectsCount;
std::list<d3d_OBJECT *> mConsolidatedStaticObjects;
// name and ordinal texture maps
LPDIRECT3DTEXTURE9 mNameTextures[MAX_PLAYER_NAMES];
LPDIRECT3DTEXTURE9 mOrdinalTextures[MAX_PLAYER_NAMES];
protected:
ReticleRenderable *mReticle;
CameraShipHUDRenderable *mCamShipHUD;
void LoadMissionImplementation(Mission *mission);
//
// These variables hold some culling related information
//
LinearMatrix worldToEyeMatrix; // the current world to eye transform for our linked entity
Scalar currentFrameTime; // the time at the start of renderable execution
//
// These variables are used for tracking target frame time
//
unsigned long total_cull,
total_draw,
total_pixelplanes,
total_frame_time,
target_frame_time,
frame_count,
target_frame_count;
Logical statistics_started;
Scalar report_time;
//
// The rest of the renderer's variables.
//
Time StartSample; // For generating a framerate printout
Logical fogUpdating,
eyeRelative, // True if the eye will be relative to the linked entity origin
completeCycleNeeded; // True when we are waiting for DPL to be ready for the next frame
int myUniqueID, // Generates a unique 16 bit id value for PSFX use
lastAppState; // For keeping track of what the application is doing
float aspectRatio, // aspect ratio of the screen
FrameCount, // For keeping track of framerate
// Fog is setup as standard fog used for vehicles without simulated lights
// and used when a vehicle with lights has them switched on. This setting
// is replicated into the "noSearchLight" setting so vehicles with lights
// will always get this setting if the environment doesn't specifically say
// that headlight simulation will work.
fogRed, // Fog setting to use when vehicle lights are on
fogBlue, // This is the default for vehicles with no lights
fogGreen,
fogNear,
fogFar,
currentFogNear,
currentFogFar,
searchLightFogRed, // Fog setting to use when vehicle lights are on
searchLightFogBlue,
searchLightFogGreen,
searchLightFogNear,
searchLightFogFar,
noSearchLightFogRed, // Fog setting to use when vehicle lights are off
noSearchLightFogBlue,
noSearchLightFogGreen,
noSearchLightFogNear,
noSearchLightFogFar,
clipNear, // Near clipping plane (from INI file)
clipFar, // Far clipping plane (from INI file)
backgroundRed, // Background color (from INI file)
backgroundGreen,
backgroundBlue,
viewAngle, // Viewing angle (from INI file)
viewRatio; // This is tan(viewAngle/2.0f) (handy for culling)
dpl_DCS *dplTestEyeDCS; // A DCS we temporarily hook our eye on (for testing)
void MakeEntityRenderables(Entity *this_entity, // The entity we are dealing with
ResourceDescription *model_resource, // Pointer to the video resource
ViewFrom type); // Type of reference (inside/outside...etc.)
dpl_VIEW *dplMainView; // The DPL view we create at the beginning and use for our eye
dpl_ZONE *dplDeathZone, // The DPL zone that holds our vehicle (for death effect)
*dplMainZone; // The DPL zone that holds the rest of the world
Reticle *vehicleReticle; // Pointer to our vehicle's reticle if one exists.
dpl_DCS *delayDCSFlushArray[DELAY_DCS_FLUSH_ARRAY_SIZE+1];
int delayedDCSCount;
INDIE_EFFECT myPSFXDescriptons[MAX_PSFX_COUNT];
ParticleEmitter myPSFXEmitters[MAX_INDIE_EMITTERS];
//
// This information is captured from the pickpoint when it is enabled
//
dpl_INSTANCE *dplHitInstance;
dpl_DCS *dplHitDCS;
dpl_GEOGROUP *dplHitGeoGroup;
dpl_GEOMETRY *dplHitGeometry;
//
// This information holds the list of projectile renderables
//
SChainOf<InnerProjectileRenderable*> projectile_list;
//
// This holds the list of cached objects
//
TreeOf<DPLObjectCacheLine*, CString> dplObjectCacheSocket;
//
// This holds the list of jointed mover DCS tables
//
TableOf<DPLJointToDCSTranslator*, RegisteredClassMemoryAddress> dplJointToDCSTranslatorSocket;
//
// This chain contains the list of active renderables
//
SChainOf<Component*> dplRenderableSocket;
public:
//
// Store Lights for Later Revision
//
// dpl_LIGHT *ambientLight;
D3DLIGHT9 *sceneLight; // Array of all the lights
dpl_DCS **sceneLightDCS; // Array of DCS's for Lights
int sceneLightCount;
//static UserHeap *DPLHeap;
};
extern LPDIRECT3D9 gD3D;