TINSEL: Parsing of cameras & lights

This commit is contained in:
Peter Kohaut
2022-05-07 12:30:52 +02:00
parent eccf066b4b
commit 91e2436650
3 changed files with 139 additions and 37 deletions
+136 -36
View File
@@ -84,7 +84,11 @@ struct SCENE_STRUC {
int32 numProcess; // number of processes in this scene
SCNHANDLE hProcess; // handle to table of processes
SCNHANDLE hMusicScript; // handle to music script data - Tinsel 2 only
SCNHANDLE hMusicSegment;// handle to music segments - Tinsel 2 only
SCNHANDLE hMusicSegment; // handle to music segments - Tinsel 2 only
int32 numCameras;
SCNHANDLE hCamera;
int32 numLights;
SCNHANDLE hLight;
} PACKED_STRUCT;
/** entrance structure - one per entrance */
@@ -96,6 +100,25 @@ struct ENTRANCE_STRUC {
uint32 flags;
} PACKED_STRUCT;
/** camera strucutre, Noir only */
struct CAMERA_STRUC {
int32 sceneId;
int32 rotX;
int32 rotY;
int32 rotZ;
int32 posX;
int32 posY;
int32 posZ;
int32 aperture;
} PACKED_STRUCT;
struct LIGHT_STRUC {
int32 sceneId;
int32 posX;
int32 posY;
int32 posZ;
} PACKED_STRUCT;
#include "common/pack-end.h" // END STRUCT PACKING
@@ -114,6 +137,8 @@ static SCNHANDLE g_SceneHandle = 0; // Current scene handle - stored in case of
SCENE_STRUC g_tempStruc;
static bool g_isViewSet = false;
struct TP_INIT {
SCNHANDLE hTinselCode; // Code
TINSEL_EVENT event; // Triggering event
@@ -124,45 +149,12 @@ void ResetVarsScene() {
g_initialMyEscape = 0;
g_SceneHandle = 0;
g_isViewSet = false;
memset(&g_tempStruc, 0, sizeof(SCENE_STRUC));
}
SCENE_STRUC* parseV3Scene(const byte *pStruc) {
memset(&g_tempStruc, 0, sizeof(SCENE_STRUC));
Common::MemoryReadStream stream(pStruc, 84);
g_tempStruc.defRefer = stream.readUint32LE();
g_tempStruc.hSceneScript = stream.readUint32LE();
g_tempStruc.hSceneDesc = stream.readUint32LE();
g_tempStruc.numEntrance = stream.readUint32LE();
g_tempStruc.hEntrance = stream.readUint32LE();
stream.readUint32LE();
stream.readUint32LE();
stream.readUint32LE();
stream.readUint32LE();
g_tempStruc.numPoly = stream.readUint32LE();
g_tempStruc.hPoly = stream.readUint32LE();
g_tempStruc.numTaggedActor = stream.readUint32LE();
g_tempStruc.hTaggedActor = stream.readUint32LE();
g_tempStruc.numProcess = stream.readUint32LE();
g_tempStruc.hProcess = stream.readUint32LE();
g_tempStruc.hMusicScript = stream.readUint32LE();
g_tempStruc.hMusicSegment = stream.readUint32LE();
warning("TODO: Complete scene loading logic for Noir");
return &g_tempStruc;
}
const SCENE_STRUC *GetSceneStruc(const byte *pStruc) {
if (TinselVersion == 2)
return (const SCENE_STRUC *)pStruc;
else if (TinselVersion == 3)
return parseV3Scene(pStruc);
// Copy appropriate fields into tempStruc, and return a pointer to it
const byte *p = pStruc;
memset(&g_tempStruc, 0, sizeof(SCENE_STRUC));
SCENE_STRUC* parseSceneV1(const byte *p) {
g_tempStruc.numEntrance = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.numPoly = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.numTaggedActor = READ_UINT32(p); p += sizeof(uint32);
@@ -175,6 +167,59 @@ const SCENE_STRUC *GetSceneStruc(const byte *pStruc) {
return &g_tempStruc;
}
SCENE_STRUC* parseSceneV2(const byte *p) {
g_tempStruc.defRefer = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hSceneScript = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hSceneDesc = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.numEntrance = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hEntrance = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.numPoly = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hPoly = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.numTaggedActor = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hTaggedActor = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.numProcess = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hProcess = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hMusicScript = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hMusicSegment = READ_UINT32(p); p += sizeof(uint32);
return &g_tempStruc;
}
SCENE_STRUC* parseSceneV3(const byte *p) {
g_tempStruc.defRefer = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hSceneScript = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hSceneDesc = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.numEntrance = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hEntrance = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.numCameras = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hCamera = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.numLights = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hLight = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.numPoly = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hPoly = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.numTaggedActor = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hTaggedActor = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.numProcess = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hProcess = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hMusicScript = READ_UINT32(p); p += sizeof(uint32);
g_tempStruc.hMusicSegment = READ_UINT32(p); p += sizeof(uint32);
// scollfields scaling/speed - 4 ints
warning("TODO: Complete scene loading logic for Noir");
return &g_tempStruc;
}
const SCENE_STRUC *GetSceneStruc(const byte *pStruc) {
memset(&g_tempStruc, 0, sizeof(SCENE_STRUC));
if (TinselVersion == 3) {
return parseSceneV3(pStruc);
} else if (TinselVersion == 2) {
return parseSceneV2(pStruc);
} else {
return parseSceneV1(pStruc);
}
}
/**
* Started up for scene script and entrance script.
@@ -423,6 +468,8 @@ void StartNewScene(SCNHANDLE scene, int entry) {
PrimeScene(); // Start up the standard stuff for the next scene.
LoadScene(scene, entry);
g_isViewSet = false;
}
#ifdef DEBUG
@@ -469,4 +516,57 @@ void WrapScene() {
SendSceneTinselProcess(CLOSEDOWN);
}
/**
* Set parameters for 3D rendering for Noir.
*/
void SetView(int sceneId, int scale) {
if (sceneId == SysVar(SV_SPRITER_SCENE_ID)) {
if (scale == SysVar(SV_SPRITER_SCALE)) {
debug("Ignoring SetView()");
return;
}
}
debug("SetView(%d, %d)", sceneId, scale);
SetSysVar(SV_SPRITER_SCALE, scale);
SetSysVar(SV_USER3 ,0x28);
if (g_isViewSet) {
//EndActors();
} else {
g_isViewSet = true;
}
int i = 0;
CAMERA_STRUC *pCamera = (CAMERA_STRUC *)_vm->_handle->LockMem(g_tempStruc.hCamera);
for (i = 0; i < g_tempStruc.numCameras; ++i, ++pCamera) {
if (sceneId == FROM_32(pCamera->sceneId)) {
// set camera
SetSysVar(SV_SPRITER_SCENE_ID, sceneId);
break;
}
}
if (i == g_tempStruc.numCameras) {
// no suitable camera found
return;
}
LIGHT_STRUC *pLight = (LIGHT_STRUC *)_vm->_handle->LockMem(g_tempStruc.hLight);
for (i = 0; i < g_tempStruc.numLights; ++i, ++pLight) {
if (sceneId == FROM_32(pLight->sceneId)) {
// set light
break;
}
}
if (i == g_tempStruc.numLights) {
// use default light
}
//update ground plane
}
} // End of namespace Tinsel
+2
View File
@@ -88,6 +88,8 @@ void EndScene();
void SendSceneTinselProcess(TINSEL_EVENT event);
void SetView(int id, int scale);
} // End of namespace Tinsel
#endif // TINSEL_SCENE_H
+1 -1
View File
@@ -6418,7 +6418,7 @@ int CallLibraryRoutine(CORO_PARAM, int operand, int32 *pp, const INT_CONTEXT *pi
case SETVIEW:
// Noir only
pp -= 1;
warning("TODO: Implement SETVIEW(0x%08X, %i)", pp[0], pp[1]);
SetView(pp[0], pp[1]);
return -2;
case SHELL: