Skip to content

Commit 32a11af

Browse files
committed
Merge commit
Conflicts: TheForceEngine/TFE_DarkForces/Scripting/scriptObject.cpp
2 parents 233b231 + 0d889df commit 32a11af

File tree

14 files changed

+204
-12
lines changed

14 files changed

+204
-12
lines changed

TheForceEngine/TFE_DarkForces/Scripting/gs_game.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ namespace TFE_DarkForces
3131
{
3232
ScriptClassBegin("Game", "game", api);
3333
{
34+
// Enums
35+
ScriptEnumRegister("MessageType");
36+
ScriptEnum("M_TRIGGER", MSG_TRIGGER);
37+
ScriptEnum("NEXT_STOP", MSG_NEXT_STOP);
38+
ScriptEnum("PREV_STOP", MSG_PREV_STOP);
39+
// ScriptEnum("GOTO_STOP", MSG_GOTO_STOP); // GOTO_STOP requires a parameter, not yet implemented
40+
ScriptEnum("DONE", MSG_DONE);
41+
ScriptEnum("WAKEUP", MSG_WAKEUP);
42+
ScriptEnum("MASTER_ON", MSG_MASTER_ON);
43+
ScriptEnum("MASTER_OFF", MSG_MASTER_OFF);
44+
ScriptEnum("CRUSH", MSG_CRUSH);
45+
3446
// Functions
3547
ScriptObjMethod("float getGameTime()", getGameTime);
3648
ScriptObjMethod("int random(int)", scriptRandom);

TheForceEngine/TFE_DarkForces/Scripting/scriptObject.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,14 @@ namespace TFE_DarkForces
288288
}
289289

290290

291+
void sendMessageToObject(MessageType messageType, ScriptObject* sObject)
292+
{
293+
if (!doesObjectExist(sObject)) { return; }
294+
295+
SecObject* obj = TFE_Jedi::s_objectRefList[sObject->m_id].object;
296+
message_sendToObj(obj, messageType, actor_messageFunc);
297+
}
298+
291299
//////////////////////////////////////////////////////
292300
// Logic related functionality
293301
//////////////////////////////////////////////////////
@@ -629,6 +637,7 @@ namespace TFE_DarkForces
629637
ScriptObjFunc("void delete()", deleteObject);
630638
ScriptObjFunc("void addLogic(string)", addLogicToObject);
631639
ScriptObjFunc("void setCamera()", setCamera);
640+
ScriptObjFunc("void sendMessage(int)", sendMessageToObject);
632641

633642
// Logic getters & setters
634643
ScriptPropertyGetFunc("int get_hitPoints()", getHitPoints);

TheForceEngine/TFE_DarkForces/Scripting/scriptSector.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <TFE_Jedi/Level/levelData.h>
66
#include <TFE_Jedi/Level/rwall.h>
77
#include <TFE_Jedi/Level/rsector.h>
8+
#include <TFE_Jedi/InfSystem/message.h>
89
#include <angelscript.h>
910

1011
using namespace TFE_Jedi;
@@ -169,6 +170,33 @@ namespace TFE_DarkForces
169170
}
170171
}
171172

173+
// Message with event and arg, eg. GOTO_STOP 131072 2
174+
void sendMessageToSector(MessageType messageType, u32 evt, u32 msgArg1, ScriptSector* sSector)
175+
{
176+
if (!isScriptSectorValid(sSector))
177+
{
178+
return;
179+
}
180+
181+
// TODO: investigate how to do this safely
182+
// s_msgArg1 = msgArg1;
183+
184+
RSector* sector = &s_levelState.sectors[sSector->m_id];
185+
message_sendToSector(sector, nullptr, evt, messageType);
186+
}
187+
188+
// Message with no event and no arg, eg. NEXT_STOP
189+
void sendMessageToSector1(MessageType messageType, ScriptSector* sSector)
190+
{
191+
sendMessageToSector(messageType, 0, 0, sSector);
192+
}
193+
194+
// Message with event, eg. NEXT_STOP 131072
195+
void sendMessageToSector2(MessageType messageType, u32 evt, ScriptSector* sSector)
196+
{
197+
sendMessageToSector(messageType, evt, 0, sSector);
198+
}
199+
172200
void ScriptSector::registerType()
173201
{
174202
s32 res = 0;
@@ -185,6 +213,11 @@ namespace TFE_DarkForces
185213
ScriptObjFunc("void setFlag(int, uint)", setSectorFlag);
186214
ScriptObjFunc("float2 getCenterXZ()", getCenterXZ);
187215
ScriptObjFunc("Wall getWall(int)", getWall);
216+
217+
ScriptObjFunc("void sendMessage(int)", sendMessageToSector1);
218+
ScriptObjFunc("void sendMessage(int, uint)", sendMessageToSector2);
219+
//ScriptObjFunc("void sendMessage(int, uint, uint)", sendMessageToSector); // For now do not expose the ability to pass an arg
220+
188221
// Properties
189222
ScriptPropertyGetFunc("float get_floorHeight()", getFloorHeight);
190223
ScriptPropertyGetFunc("float get_ceilHeight()", getCeilHeight);

TheForceEngine/TFE_DarkForces/darkForcesMain.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,6 +1617,12 @@ namespace TFE_DarkForces
16171617
// TFE - Scripting.
16181618
serialization_setVersion(curVersion);
16191619
TFE_ForceScript::serialize(stream);
1620+
if (!writeState)
1621+
{
1622+
// Setup the level script after script serialization and fixup INF function pointers.
1623+
loadLevelScript();
1624+
inf_fixupScriptCalls();
1625+
}
16201626

16211627
TFE_System::messages_serialize(stream);
16221628

TheForceEngine/TFE_ForceScript/forceScript.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -919,7 +919,8 @@ namespace TFE_ForceScript
919919
} break;
920920
case ARG_STRING:
921921
{
922-
context->SetArgObject(i, (void*)&arg[i].stdStr);
922+
std::string stdStr(arg[i].strValue);
923+
context->SetArgObject(i, (void*)&stdStr);
923924
} break;
924925
case ARG_FLOAT2:
925926
{

TheForceEngine/TFE_ForceScript/forceScript.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <TFE_System/types.h>
77
#include <TFE_System/system.h>
88
#include <TFE_FileSystem/stream.h>
9+
#include <cstring>
910
#include <string>
1011

1112
namespace TFE_ForceScript
@@ -54,8 +55,8 @@ namespace TFE_ForceScript
5455
Vec2f float2Value;
5556
Vec3f float3Value;
5657
Vec4f float4Value;
58+
char strValue[32];
5759
};
58-
std::string stdStr;
5960
};
6061

6162
// Opaque Handles.
@@ -109,8 +110,8 @@ namespace TFE_ForceScript
109110
inline ScriptArg scriptArg(u32 value) { ScriptArg arg; arg.type = ARG_U32; arg.uValue = value; return arg; }
110111
inline ScriptArg scriptArg(f32 value) { ScriptArg arg; arg.type = ARG_F32; arg.fValue = value; return arg; }
111112
inline ScriptArg scriptArg(bool value) { ScriptArg arg; arg.type = ARG_BOOL; arg.bValue = value; return arg; }
112-
inline ScriptArg scriptArg(const std::string& value) { ScriptArg arg; arg.type = ARG_STRING; arg.stdStr = value; return arg; }
113-
inline ScriptArg scriptArg(const char* value) { ScriptArg arg; arg.type = ARG_STRING; arg.stdStr = value; return arg; }
113+
inline ScriptArg scriptArg(const std::string& value) { ScriptArg arg; arg.type = ARG_STRING; strcpy(arg.strValue, value.c_str()); return arg; }
114+
inline ScriptArg scriptArg(const char* value) { ScriptArg arg; arg.type = ARG_STRING; strcpy(arg.strValue, value); return arg; }
114115
inline ScriptArg scriptArg(Vec2f value) { ScriptArg arg; arg.type = ARG_FLOAT2; arg.float2Value = value; return arg; }
115116
inline ScriptArg scriptArg(Vec3f value) { ScriptArg arg; arg.type = ARG_FLOAT3; arg.float3Value = value; return arg; }
116117
inline ScriptArg scriptArg(Vec4f value) { ScriptArg arg; arg.type = ARG_FLOAT4; arg.float4Value = value; return arg; }

TheForceEngine/TFE_Jedi/InfSystem/infState.cpp

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@ namespace TFE_Jedi
1515
enum InfStateVersion : u32
1616
{
1717
InfState_InitVersion = 1,
18-
InfState_CurVersion = InfState_InitVersion,
18+
InfState_ScriptCall,
19+
InfState_CurVersion = InfState_ScriptCall,
1920
};
2021

2122
// INF State
2223
InfSerializableState s_infSerState = { };
2324
InfState s_infState = { };
2425

26+
static std::vector<InfScriptCall*> s_infScriptCallsToFixup;
27+
2528
/////////////////////////////////////////////
2629
// Forward Declarations
2730
/////////////////////////////////////////////
@@ -493,6 +496,8 @@ namespace TFE_Jedi
493496

494497
void inf_serialize(Stream* stream)
495498
{
499+
s_infScriptCallsToFixup.clear();
500+
496501
SERIALIZE_VERSION(InfState_CurVersion);
497502

498503
s32 elevCount, teleCount, trigCount;
@@ -627,6 +632,32 @@ namespace TFE_Jedi
627632
SERIALIZE(InfState_InitVersion, msg->arg2, 0);
628633
}
629634

635+
void inf_serializeSciptCall(Stream* stream, Stop* stop, InfScriptCall* call)
636+
{
637+
SERIALIZE(InfState_ScriptCall, call->argCount, 0);
638+
for (s32 i = 0; i < call->argCount; i++)
639+
{
640+
serialization_serializeScriptArg(stream, InfState_ScriptCall, &call->args[i]);
641+
}
642+
SERIALIZE_CSTRING(InfState_ScriptCall, call->funcName);
643+
if (serialization_getMode() == SMODE_READ)
644+
{
645+
call->funcPtr = nullptr;
646+
s_infScriptCallsToFixup.push_back(call);
647+
}
648+
}
649+
650+
void inf_fixupScriptCalls()
651+
{
652+
const s32 count = (s32)s_infScriptCallsToFixup.size();
653+
for (s32 i = 0; i < count; i++)
654+
{
655+
InfScriptCall* call = s_infScriptCallsToFixup[i];
656+
call->funcPtr = getLevelScriptFunc(call->funcName);
657+
}
658+
s_infScriptCallsToFixup.clear();
659+
}
660+
630661
void inf_serializeAdjoin(Stream* stream, Stop* stop, AdjoinCmd* adjCmd)
631662
{
632663
serialization_serializeSectorPtr(stream, InfState_InitVersion, adjCmd->sector0);
@@ -684,6 +715,35 @@ namespace TFE_Jedi
684715
}
685716
}
686717

718+
// Script Calls
719+
s32 scriptCallCount = 0;
720+
if (serialization_getMode() == SMODE_WRITE)
721+
{
722+
scriptCallCount = allocator_getCount(stop->scriptCalls);
723+
}
724+
SERIALIZE(InfState_ScriptCall, scriptCallCount, 0);
725+
if (serialization_getMode() == SMODE_WRITE)
726+
{
727+
allocator_saveIter(stop->scriptCalls);
728+
InfScriptCall* call = (InfScriptCall*)allocator_getHead(stop->scriptCalls);
729+
while (call)
730+
{
731+
inf_serializeSciptCall(stream, stop, call);
732+
call = (InfScriptCall*)allocator_getNext(stop->scriptCalls);
733+
}
734+
allocator_restoreIter(stop->scriptCalls);
735+
}
736+
else if (scriptCallCount > 0) // SMODE_READ
737+
{
738+
stop->scriptCalls = allocator_create(sizeof(InfScriptCall));
739+
for (s32 c = 0; c < scriptCallCount; c++)
740+
{
741+
InfScriptCall* call = (InfScriptCall*)allocator_newItem(stop->scriptCalls);
742+
if (!call) { return; }
743+
inf_serializeSciptCall(stream, stop, call);
744+
}
745+
}
746+
687747
// Adjoin Commands
688748
s32 adjCount;
689749
if (serialization_getMode() == SMODE_WRITE)
@@ -708,8 +768,7 @@ namespace TFE_Jedi
708768
for (s32 a = 0; a < adjCount; a++)
709769
{
710770
AdjoinCmd* adjCmd = (AdjoinCmd*)allocator_newItem(stop->adjoinCmds);
711-
if (!adjCmd)
712-
return;
771+
if (!adjCmd) { return; }
713772
inf_serializeAdjoin(stream, stop, adjCmd);
714773
}
715774
}

TheForceEngine/TFE_Jedi/InfSystem/infSystem.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2034,7 +2034,9 @@ namespace TFE_Jedi
20342034
memcpy(unquotedStr, &value[1], newLen);
20352035
unquotedStr[newLen] = 0;
20362036

2037-
arg[argCount].stdStr = std::string(unquotedStr);
2037+
// Force string to fixed-size.
2038+
unquotedStr[31] = 0;
2039+
strcpy(arg[argCount].strValue, unquotedStr);
20382040
arg[argCount].type = TFE_ForceScript::ARG_STRING;
20392041
argCount++;
20402042
}
@@ -2375,7 +2377,8 @@ namespace TFE_Jedi
23752377
Stop* stop = inf_getStopByIndex(elev, index);
23762378
if (stop)
23772379
{
2378-
TFE_ForceScript::FunctionHandle func = getLevelScriptFunc(s_infArg1);
2380+
std::string funcName = s_infArg1;
2381+
TFE_ForceScript::FunctionHandle func = getLevelScriptFunc(funcName.c_str());
23792382
if (func)
23802383
{
23812384
if (!stop->scriptCalls)
@@ -2388,6 +2391,16 @@ namespace TFE_Jedi
23882391
// Up to 4 arguments.
23892392
scriptCall->argCount = inf_parseScriptCallArg(elev, stop, scriptCall->args, argCount - 3, s_infArg2, s_infArg3, s_infArg4, s_infArgExtra);
23902393
scriptCall->funcPtr = func;
2394+
// Copy the name, zero out any unused space to avoid saving to disk.
2395+
memset(scriptCall->funcName, 0, MAX_SCRIPT_CALL_NAME_LEN);
2396+
if (funcName.length() >= MAX_SCRIPT_CALL_NAME_LEN)
2397+
{
2398+
TFE_System::logWrite(LOG_ERROR, "InfSerialization", "Function name %s too long, the limit is 63 characters.", funcName.c_str());
2399+
}
2400+
else
2401+
{
2402+
strcpy(scriptCall->funcName, funcName.c_str());
2403+
}
23912404
}
23922405
}
23932406
} break;

TheForceEngine/TFE_Jedi/InfSystem/infSystem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ namespace TFE_Jedi
3636
// Serialization & State
3737
void inf_clearState();
3838
void inf_serialize(Stream* stream);
39+
void inf_fixupScriptCalls();
3940

4041
// ** Runtime API **
4142
// Messages are the way entities and the player interact with the INF system during gameplay.

TheForceEngine/TFE_Jedi/InfSystem/infTypesInternal.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ namespace TFE_Jedi
8383
TELEPORT_CHUTE = 1
8484
};
8585

86+
enum ScriptCallConst
87+
{
88+
MAX_SCRIPT_CALL_NAME_LEN = 64,
89+
MAX_SCRIPT_CALL_ARG = 5,
90+
};
91+
8692
struct Teleport
8793
{
8894
RSector* sector;
@@ -150,7 +156,8 @@ namespace TFE_Jedi
150156
{
151157
void* funcPtr;
152158
s32 argCount;
153-
TFE_ForceScript::ScriptArg args[5];
159+
TFE_ForceScript::ScriptArg args[MAX_SCRIPT_CALL_ARG];
160+
char funcName[MAX_SCRIPT_CALL_NAME_LEN]; // Needed for serialization.
154161
};
155162

156163
struct Slave

0 commit comments

Comments
 (0)