259 lines
7.8 KiB
C++
259 lines
7.8 KiB
C++
static u64 S2_CallFunctionIndexFromString(string String)
|
|
{
|
|
u64 Result = 0;
|
|
for(u64 Index = 0; Index < ArrayCount(S2_CallNameLookup); Index += 1)
|
|
{
|
|
if(AreEqual(String, S2_CallNameLookup[Index]))
|
|
{
|
|
Result = Index;
|
|
break;
|
|
}
|
|
}
|
|
return(Result);
|
|
}
|
|
|
|
static scene2_call_function *S2_CallFunctionFromString(string String)
|
|
{
|
|
scene2_call_function *Result = S2_Call_Stub;
|
|
for(u64 Index = 0; Index < ArrayCount(S2_CallNameLookup); Index += 1)
|
|
{
|
|
if(AreEqual(String, S2_CallNameLookup[Index]))
|
|
{
|
|
Result = S2_CallBindingLookup[Index];
|
|
break;
|
|
}
|
|
}
|
|
return(Result);
|
|
}
|
|
|
|
static S2_CALL_FUNCTION(S2_Call_StackSanity)
|
|
{
|
|
scene2_object Value = S2_StackPop(Runtime);
|
|
Assert(Value.Kind == S2_ObjectKind_Number && Runtime->StackPointer == (u64)Value.As.Number);
|
|
}
|
|
|
|
static S2_CALL_FUNCTION(S2_Call_TextClear)
|
|
{
|
|
scene_view *SceneView = (scene_view *)Runtime->Data;
|
|
SceneView->TextboxUsed = 0;
|
|
SceneView->TextboxRevealed = 0;
|
|
}
|
|
|
|
static S2_CALL_FUNCTION(S2_Call_NewLine)
|
|
{
|
|
scene_view *SceneView = (scene_view *)Runtime->Data;
|
|
if(SceneView->TextboxUsed < ArrayCount(SceneView->TextboxData))
|
|
{
|
|
SceneView->TextboxData[SceneView->TextboxUsed++] = '\n';
|
|
}
|
|
}
|
|
|
|
static S2_CALL_FUNCTION(S2_Call_TextAppend)
|
|
{
|
|
scene_view *SceneView = (scene_view *)Runtime->Data;
|
|
|
|
temp Scratch = GetScratch();
|
|
string Addend = S2_StringFromObject(Scratch.Arena, S2_StackPop(Runtime));
|
|
|
|
Addend.Count = Min(Addend.Count, ArrayCount(SceneView->TextboxData)-SceneView->TextboxUsed);
|
|
|
|
Copy(SceneView->TextboxData+SceneView->TextboxUsed, Addend.Data, Addend.Count);
|
|
SceneView->TextboxUsed += Addend.Count;
|
|
|
|
ReleaseScratch(Scratch);
|
|
}
|
|
|
|
static S2_CALL_FUNCTION(S2_Call_ProcSet)
|
|
{
|
|
temp Scratch = GetScratch();
|
|
S2_SetCurrentProc(Runtime, S2_ProcFromName(Compiled, S2_StringFromObject(Scratch.Arena, S2_StackPop(Runtime))));
|
|
ReleaseScratch(Scratch);
|
|
}
|
|
|
|
static S2_CALL_FUNCTION(S2_Call_CharacterSet)
|
|
{
|
|
scene_view *SceneView = (scene_view *)Runtime->Data;
|
|
|
|
scene2_object IDObject = S2_StackPop(Runtime);
|
|
scene2_object TargetObject = S2_StackPop(Runtime);
|
|
|
|
// sixten(TODO): this should fail gracefully
|
|
Assert(IDObject.Kind == S2_ObjectKind_Number || IDObject.Kind == S2_ObjectKind_Nil);
|
|
Assert(TargetObject.Kind == S2_ObjectKind_String);
|
|
|
|
string Target = TargetObject.As.String;
|
|
asset_id ID = IDObject.Kind == S2_ObjectKind_Number ? (asset_id)IDObject.As.Number : AssetID_None;
|
|
|
|
scene_view_character_data *CharacterBegin = SceneView->Characters;
|
|
scene_view_character_data *CharacterUsedEnd = SceneView->Characters+SceneView->CharactersUsed;
|
|
scene_view_character_data *CharacterEnd = SceneView->Characters+ArrayCount(SceneView->Characters);
|
|
scene_view_character_data *Character = CharacterBegin;
|
|
|
|
for(;Character < CharacterEnd; Character += 1)
|
|
{
|
|
// sixten: check if the character doesn't exist
|
|
if(Character == CharacterUsedEnd)
|
|
{
|
|
// sixten: "create" new character
|
|
ZeroStruct(Character);
|
|
Character->Name = PushString(SceneView->SceneArena, Target);
|
|
SceneView->CharactersUsed += 1;
|
|
Character->PctP = ((r32)SceneView->CharactersUsed / (r32)(SceneView->CharactersUsed+1));
|
|
break;
|
|
}
|
|
|
|
// sixten: check if character exists
|
|
if(AreEqual(Character->Name, Target))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(Character != CharacterEnd)
|
|
{
|
|
Character->Active = true;
|
|
if(ID != AssetID_None)
|
|
{
|
|
Character->Info.Texture = A_TextureFromAssetID(ID);
|
|
Character->Info.Scale = A_ScaleFromAssetID(ID);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// sixten: we've run out of characters
|
|
}
|
|
}
|
|
|
|
static S2_CALL_FUNCTION(S2_Call_CharacterRemove)
|
|
{
|
|
scene_view *SceneView = (scene_view *)Runtime->Data;
|
|
|
|
scene2_object TargetObject = S2_StackPop(Runtime);
|
|
|
|
// sixten(TODO): this should fail gracefully
|
|
Assert(TargetObject.Kind == S2_ObjectKind_String);
|
|
|
|
string Target = TargetObject.As.String;
|
|
|
|
scene_view_character_data *CharacterBegin = SceneView->Characters;
|
|
scene_view_character_data *CharacterEnd = SceneView->Characters+SceneView->CharactersUsed;
|
|
scene_view_character_data *Character = CharacterBegin;
|
|
|
|
// sixten: check if the character exists
|
|
for(;Character < CharacterEnd; Character += 1)
|
|
{
|
|
if(AreEqual(Character->Name, Target))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
// sixten: if the character exists, request its deletion
|
|
if(Character != CharacterEnd)
|
|
{
|
|
Character->Active = false;
|
|
Character->Talking = false;
|
|
}
|
|
}
|
|
|
|
static S2_CALL_FUNCTION(S2_Call_CharacterSetTalking)
|
|
{
|
|
scene_view *SceneView = (scene_view *)Runtime->Data;
|
|
|
|
scene2_object TargetObject = S2_StackPop(Runtime);
|
|
|
|
// sixten(TODO): this should fail gracefully
|
|
Assert(TargetObject.Kind == S2_ObjectKind_String);
|
|
|
|
string Target = TargetObject.As.String;
|
|
|
|
scene_view_character_data *CharacterBegin = SceneView->Characters;
|
|
scene_view_character_data *CharacterEnd = SceneView->Characters+SceneView->CharactersUsed;
|
|
scene_view_character_data *Character = CharacterBegin;
|
|
|
|
// sixten: check if the character exists
|
|
for(;Character < CharacterEnd; Character += 1)
|
|
{
|
|
if(AreEqual(Character->Name, Target))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
// sixten: if the character exists, request its deletion
|
|
if(Character != CharacterEnd)
|
|
{
|
|
Character->Talking = true;
|
|
}
|
|
}
|
|
|
|
static S2_CALL_FUNCTION(S2_Call_CharacterUnsetAllTalking)
|
|
{
|
|
scene_view *SceneView = (scene_view *)Runtime->Data;
|
|
|
|
scene_view_character_data *CharacterBegin = SceneView->Characters;
|
|
scene_view_character_data *CharacterEnd = SceneView->Characters+SceneView->CharactersUsed;
|
|
scene_view_character_data *Character = CharacterBegin;
|
|
|
|
for(;Character < CharacterEnd; Character += 1)
|
|
{
|
|
Character->Talking = false;
|
|
}
|
|
}
|
|
|
|
static void SV_LoadNavItems(string FileName);
|
|
static S2_CALL_FUNCTION(S2_Call_NavLoad)
|
|
{
|
|
scene2_object Object = S2_StackPop(Runtime);
|
|
if(Object.Kind == S2_ObjectKind_String)
|
|
{
|
|
SV_LoadNavItems(Object.As.String);
|
|
}
|
|
}
|
|
|
|
static S2_CALL_FUNCTION(S2_Call_Puzzle15)
|
|
{
|
|
scene_view *SceneView = (scene_view *)Runtime->Data;
|
|
SceneView->Mode = SV_Mode_P15;
|
|
SceneView->BoardOpenT = 0;
|
|
SceneView->TimeSinceBoardUpdate = 0;
|
|
SceneView->TimeSinceBoardClear = 0;
|
|
SceneView->BoardIsComplete = false;
|
|
|
|
// sixten: generate random board
|
|
for(s32 BoardY = 0; BoardY < 4; BoardY += 1)
|
|
{
|
|
for(s32 BoardX = 0; BoardX < 4; BoardX += 1)
|
|
{
|
|
SceneView->Board[BoardY][BoardX] = (1+BoardX+BoardY*4)%16;
|
|
}
|
|
}
|
|
|
|
v2_s32 EmptyP = V2S32(3, 3);
|
|
s32 ShuffleCount = 10000;
|
|
for(s32 Index = 0; Index < ShuffleCount; Index += 1)
|
|
{
|
|
s32 DeltaX = (rand() % 2)*2-1;
|
|
s32 DeltaY = (rand() % 2)*2-1;
|
|
|
|
// sixten: apply x-action
|
|
s32 NewEmptyX = EmptyP.x+DeltaX;
|
|
if(0 <= NewEmptyX && NewEmptyX < 4)
|
|
{
|
|
SceneView->Board[EmptyP.y][EmptyP.x] = SceneView->Board[EmptyP.y][NewEmptyX];
|
|
SceneView->Board[EmptyP.y][NewEmptyX] = 0;
|
|
EmptyP.x = NewEmptyX;
|
|
}
|
|
|
|
// sixten: apply y-action
|
|
s32 NewEmptyY = EmptyP.y+DeltaY;
|
|
if(0 <= NewEmptyY && NewEmptyY < 4)
|
|
{
|
|
SceneView->Board[EmptyP.y][EmptyP.x] = SceneView->Board[NewEmptyY][EmptyP.x];
|
|
SceneView->Board[NewEmptyY][EmptyP.x] = 0;
|
|
EmptyP.y = NewEmptyY;
|
|
}
|
|
}
|
|
|
|
Copy(SceneView->PrevBoard, SceneView->Board, sizeof(SceneView->Board));
|
|
} |