mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
ACS basic implementation
- BEHAVIOR lumps successfully load & run from maps. Currently they do not get unloaded between maps, though. - Print and Timer are the only implemented CallFuncs. All of the base language functions (Delay, etc) are already implemented by the VM though. - ACS compiler files are included, for use with GDCC. (Picked instead of ACC because it's less ZDoom-centric) - Additionally, also added the configs for Zone Builder to be able to compile it in editor. Syntax highlighting is very incomplete atm.
This commit is contained in:
parent
26477941ed
commit
cb8dddbedc
18 changed files with 882 additions and 26 deletions
116
extras/conf/RingRacers_ACS.cfg
Normal file
116
extras/conf/RingRacers_ACS.cfg
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*******************************************************************\
|
||||||
|
Doom Builder Script highlighting definitions for ACS
|
||||||
|
\*******************************************************************/
|
||||||
|
|
||||||
|
// Compiler settings
|
||||||
|
compiler = "ringracers_gdcc";
|
||||||
|
parameters = "-I \"%PT\" -I \"%PS\" %FI %FO";
|
||||||
|
resultlump = "BEHAVIOR";
|
||||||
|
|
||||||
|
// Editor settings
|
||||||
|
description = "Ring Racers ACS script";
|
||||||
|
codepage = 0;
|
||||||
|
extensions = "acs";
|
||||||
|
casesensitive = false;
|
||||||
|
insertcase = 0; // 0=Normal, 1=Lowercase, 2=Uppercase
|
||||||
|
lexer = 35; // CPP-style, case-insensitive
|
||||||
|
functionopen = "(";
|
||||||
|
functionclose = ")";
|
||||||
|
codeblockopen = "{";
|
||||||
|
codeblockclose = "}";
|
||||||
|
arrayopen = "[";
|
||||||
|
arrayclose = "]";
|
||||||
|
argumentdelimiter = ",";
|
||||||
|
terminator = ";";
|
||||||
|
extrawordchars = "#"; // Extra characters to be treated as a part of a word by the Script Editor
|
||||||
|
//keywordhelp = "http://www.zdoom.org/wiki/index.php?title=%K";
|
||||||
|
snippetsdir = "acs";
|
||||||
|
scripttype = 1; //0 = unknown script, 1 = acc, 2 = modeldef, 3 = decorate
|
||||||
|
|
||||||
|
keywords
|
||||||
|
{
|
||||||
|
#define = "#Define identifier expression";
|
||||||
|
#encryptstrings = "#EncryptStrings";
|
||||||
|
#import = "#Import";
|
||||||
|
#include = "#Include";
|
||||||
|
#libdefine = "#LibDefine identifier expression";
|
||||||
|
#library = "#Library";
|
||||||
|
#NoCompact = "#NoCompact";
|
||||||
|
#NoWadAuthor = "#NoWadAuthor";
|
||||||
|
#WadAuthor = "#WadAuthor";
|
||||||
|
#region = "#region block";
|
||||||
|
#endregion = "end of #region block";
|
||||||
|
ACS_Execute = "ACS_Execute(int script, int arg1, int arg2, int arg3)";
|
||||||
|
ACS_ExecuteAlways = "ACS_ExecuteAlways(int script, int arg1, int arg2, int arg3)";
|
||||||
|
ACS_ExecuteWait = "ACS_ExecuteWait(int script, int arg1, int arg2, int arg3)";
|
||||||
|
ACS_ExecuteWithResult = "ACS_ExecuteWithResult(int script, int arg1, int arg2, int arg3)";
|
||||||
|
ACS_Suspend = "ACS_Suspend(int script)";
|
||||||
|
ACS_Terminate = "ACS_Terminate(int script)";
|
||||||
|
ACS_NamedExecute = "ACS_NamedExecute(str script, int arg1, int arg2, int arg3)";
|
||||||
|
ACS_NamedExecuteAlways = "ACS_NamedExecuteAlways(str script, int arg1, int arg2, int arg3)";
|
||||||
|
ACS_NamedExecuteWait = "ACS_NamedExecuteWait(str script, int arg1, int arg2, int arg3)";
|
||||||
|
ACS_NamedExecuteWithResult = "ACS_ExecuteWithResult(str script, int arg1, int arg2, int arg3)";
|
||||||
|
ACS_NamedSuspend = "ACS_NamedSuspend(str script)";
|
||||||
|
ACS_NamedTerminate = "ACS_NamedTerminate(str script)";
|
||||||
|
ActivatorSound = "ActivatorSound(str name, int volume)";
|
||||||
|
ActivatorTID = "ActivatorTID()";
|
||||||
|
Bool = "Bool expression";
|
||||||
|
Break = "Break";
|
||||||
|
Return = "Return";
|
||||||
|
Case = "Case expression:";
|
||||||
|
Const = "Const";
|
||||||
|
Continue = "Continue";
|
||||||
|
Death = "Script expression Death";
|
||||||
|
Default = "Default:";
|
||||||
|
Delay = "void Delay(int tics)";
|
||||||
|
Disconnect = "Script expression Disconnect";
|
||||||
|
Do = "Do";
|
||||||
|
Else = "Else";
|
||||||
|
Enter = "Script expression Enter";
|
||||||
|
For = "For(initialization, condition, iteration)";
|
||||||
|
Function = "Function Void expression (Void)";
|
||||||
|
If = "if(expression)";
|
||||||
|
Int = "int expression";
|
||||||
|
Open = "Script expression Open";
|
||||||
|
PolyWait = "void PolyWait(int polyid)";
|
||||||
|
Print = "void Print(type:expression)\nPrint will print something to the screen.\nPrint will only display for the activator of the script\nFor printing to all players, use PrintBold.";
|
||||||
|
PrintBold = "void PrintBold(type:expression)\nThis is exactly the same as Print, except all players will see the printed text\non the screen instead of just the activator of the script.";
|
||||||
|
Random = "int Random(int min, int max)";
|
||||||
|
Restart = "Restart";
|
||||||
|
Script = "Script expression";
|
||||||
|
ScriptWait = "void ScriptWait(int script)";
|
||||||
|
Special = "Special";
|
||||||
|
str = "str expression";
|
||||||
|
Suspend = "Suspend";
|
||||||
|
Switch = "Switch(expression)";
|
||||||
|
TagWait = "void TagWait(int tag)";
|
||||||
|
Terminate = "Terminate";
|
||||||
|
Timer = "int Timer(void)";
|
||||||
|
Unloading = "Script expression Unloading";
|
||||||
|
Until = "Until(expression)";
|
||||||
|
Void = "Void";
|
||||||
|
While = "While(expression)";
|
||||||
|
World = "World Int expression:identifier";
|
||||||
|
}
|
||||||
|
|
||||||
|
constants
|
||||||
|
{
|
||||||
|
TRUE;
|
||||||
|
FALSE;
|
||||||
|
ON;
|
||||||
|
OFF;
|
||||||
|
YES;
|
||||||
|
NO;
|
||||||
|
LINE_FRONT;
|
||||||
|
LINE_BACK;
|
||||||
|
SIDE_FRONT;
|
||||||
|
SIDE_BACK;
|
||||||
|
TEXTURE_TOP;
|
||||||
|
TEXTURE_MIDDLE;
|
||||||
|
TEXTURE_BOTTOM;
|
||||||
|
GAMETYPE_RACE;
|
||||||
|
GAMETYPE_BATTLE;
|
||||||
|
GAMESPEED_EASY;
|
||||||
|
GAMESPEED_NORMAL;
|
||||||
|
GAMESPEED_HARD;
|
||||||
|
}
|
||||||
16
extras/conf/gdcc.cfg
Normal file
16
extras/conf/gdcc.cfg
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
compilers
|
||||||
|
{
|
||||||
|
// This defines what files a compiler uses
|
||||||
|
// The setting named "program" defines what .exe to run
|
||||||
|
// The "interface" setting defines what interal interface to use for processing and error feedback
|
||||||
|
// All others are the required files (the setting names do not matter)
|
||||||
|
ringracers_gdcc
|
||||||
|
{
|
||||||
|
interface = "AccCompiler";
|
||||||
|
program = "gdcc-acc.exe";
|
||||||
|
zcommon = "rrcommon.acs";
|
||||||
|
zdefs = "rrdefs.acs";
|
||||||
|
zspecial = "rrspecial.acs";
|
||||||
|
}
|
||||||
|
}
|
||||||
23
extras/gdcc/rrcommon.acs
Normal file
23
extras/gdcc/rrcommon.acs
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright(C) 2015 David Hill
|
||||||
|
// Copyright(C) 2022 Sally Cochenour
|
||||||
|
//
|
||||||
|
// See COPYLIB for license information.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Header for target library libacs.
|
||||||
|
//
|
||||||
|
// Defines for Dr. Robotnik's Ring Racers' ACS.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef __GDCC_Header__ACS__rrcommon_acs__
|
||||||
|
#define __GDCC_Header__ACS__rrcommon_acs__
|
||||||
|
|
||||||
|
#include "rrspecial.acs"
|
||||||
|
#include "rrdefs.acs"
|
||||||
|
|
||||||
|
#endif//__GDCC_Header__ACS__rrcommon_acs__
|
||||||
|
|
||||||
41
extras/gdcc/rrdefs.acs
Normal file
41
extras/gdcc/rrdefs.acs
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Header for target library libacs.
|
||||||
|
//
|
||||||
|
// Defines for Dr. Robotnik's Ring Racers' ACS.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef __GDCC_Header__ACS__rrdefs_acs__
|
||||||
|
#define __GDCC_Header__ACS__rrdefs_acs__
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------|
|
||||||
|
// Macros |
|
||||||
|
//
|
||||||
|
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
||||||
|
#define ON 1
|
||||||
|
#define OFF 0
|
||||||
|
#define YES 1
|
||||||
|
#define NO 0
|
||||||
|
|
||||||
|
#define LINE_FRONT 0
|
||||||
|
#define LINE_BACK 1
|
||||||
|
|
||||||
|
#define SIDE_FRONT 0
|
||||||
|
#define SIDE_BACK 1
|
||||||
|
|
||||||
|
#define TEXTURE_TOP 0
|
||||||
|
#define TEXTURE_MIDDLE 1
|
||||||
|
#define TEXTURE_BOTTOM 2
|
||||||
|
|
||||||
|
#define GAMETYPE_RACE 0
|
||||||
|
#define GAMETYPE_BATTLE 1
|
||||||
|
|
||||||
|
#define GAMESPEED_EASY 0
|
||||||
|
#define GAMESPEED_NORMAL 1
|
||||||
|
#define GAMESPEED_HARD 2
|
||||||
|
|
||||||
|
#endif//__GDCC_Header__ACS__rrdefs_acs__
|
||||||
|
|
||||||
324
extras/gdcc/rrspecial.acs
Normal file
324
extras/gdcc/rrspecial.acs
Normal file
|
|
@ -0,0 +1,324 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright(C) 2015-2017 David Hill
|
||||||
|
// Copyright(C) 2022 Sally Cochenour
|
||||||
|
//
|
||||||
|
// See COPYLIB for license information.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Header for target library libacs.
|
||||||
|
//
|
||||||
|
// Defines for Dr. Robotnik's Ring Racers' ACS.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef __GDCC_Header__ACS__rrspecial_acs__
|
||||||
|
#define __GDCC_Header__ACS__rrspecial_acs__
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------|
|
||||||
|
// Macros |
|
||||||
|
//
|
||||||
|
|
||||||
|
#define ACS_ExecuteWait(num, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
int __execute_wait_num = (num); \
|
||||||
|
ACS_Execute(__execute_wait_num, __VA_ARGS__); \
|
||||||
|
ScriptWait(__execute_wait_num); \
|
||||||
|
} \
|
||||||
|
while(0)
|
||||||
|
|
||||||
|
#define ACS_NamedExecuteWait(name, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
str __execute_wait_name = (name); \
|
||||||
|
ACS_NamedExecute(__execute_wait_name, __VA_ARGS__); \
|
||||||
|
NamedScriptWait(__execute_wait_name); \
|
||||||
|
} \
|
||||||
|
while(0)
|
||||||
|
|
||||||
|
#define ACS_PrintPropertyBase() \
|
||||||
|
(char): PrintChar, \
|
||||||
|
(str): PrintString, \
|
||||||
|
\
|
||||||
|
a(global): PrintGlobalCharArray, \
|
||||||
|
a(global): PrintGlobalCharRange, \
|
||||||
|
a(local): PrintLocalCharArray, \
|
||||||
|
a(local): PrintLocalCharRange, \
|
||||||
|
a(module): PrintModuleCharArray, \
|
||||||
|
a(module): PrintModuleCharRange, \
|
||||||
|
a(world): PrintWorldCharArray, \
|
||||||
|
a(world): PrintWorldCharRange, \
|
||||||
|
\
|
||||||
|
b: PrintBinary, \
|
||||||
|
c: PrintChar, \
|
||||||
|
d: PrintInt, \
|
||||||
|
f: PrintFixed, \
|
||||||
|
i: PrintInt, \
|
||||||
|
s: PrintString, \
|
||||||
|
x: PrintHex
|
||||||
|
|
||||||
|
#pragma state save
|
||||||
|
#pragma define raw ON
|
||||||
|
#define suspend do (__suspend()); while(0)
|
||||||
|
#pragma state restore
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------|
|
||||||
|
// Functions |
|
||||||
|
//
|
||||||
|
|
||||||
|
// [type] [ID]:[function name]([required args], [optional args])
|
||||||
|
|
||||||
|
// Currently just implements linedef executors.
|
||||||
|
// Ideally would implement as many as possible.
|
||||||
|
|
||||||
|
special
|
||||||
|
int 400:Floor_SetHeightTexture(2,3), // tag, height[, texture]
|
||||||
|
int 401:Ceiling_SetHeightTexture(2,3), // tag, height[, texture]
|
||||||
|
int 402:Light_ChangeToValue(2), // tag, value
|
||||||
|
int 403:Floor_Move(3,5), // tag, height, speed[, texture, script]
|
||||||
|
int 404:Ceiling_Move(3,5), // tag, height, speed[, texture, script]
|
||||||
|
int 405:Floor_MoveByOffset(3,4), // tag, offset, speed[, instant]
|
||||||
|
|
||||||
|
int 407:Ceiling_MoveByOffset(3,4), // tag, offset, speed[, instant]
|
||||||
|
|
||||||
|
int 409:Sector_ChangeTag(2), // old tag, new tag
|
||||||
|
int 410:Line_ChangeFrontSectorTag(2), // line tag, new tag
|
||||||
|
|
||||||
|
int 411:Sector_StopMovement(1), // tag
|
||||||
|
int 412:Thing_Teleport(2, 5), // thing tag, sector tag[, silent, keep angle, keep speed]. Relative teleport is now a separate function.
|
||||||
|
|
||||||
|
// TODO: split all these damn features up into separate functions, instead of optional variables
|
||||||
|
int 413:Level_SetMusic(1, 12), // name[, track, loop, local, reload reset, force reset, position, position is offset, fade out time, fade in time, fade out vol, fade in vol]
|
||||||
|
|
||||||
|
int 414:Thing_PlaySound(1, 3), // name[, local, origin enum]. Doing it from a sector is now a separate function.
|
||||||
|
// int 415:Console_Execute(1), // script id
|
||||||
|
int 416:Light_Flicker(2, 4), // tag, value a[, value b, frequency]
|
||||||
|
int 417:Light_Pulse(2, 4), // tag, value a[, value b, frequency]
|
||||||
|
int 418:Light_BlinkUnsynced(4, 5), // tag, low time, hi time, value a[, value b]
|
||||||
|
int 419:Light_Blink(4, 5), // tag, low time, hi time, value a[, value b]
|
||||||
|
int 420:Light_Fade(3, 5), // tag, value, speed[, speed is tics, no interrupt]
|
||||||
|
int 421:Light_Stop(1), // tag
|
||||||
|
int 422:Player_CutAwayView(2, 3), // tid, tics[, pitch]
|
||||||
|
int 423:Level_SetSky(1, 2), // texture[, global]
|
||||||
|
int 424:Level_SetWeather(1, 2), // effect[, global]
|
||||||
|
int 425:Thing_SetState(1), // string
|
||||||
|
int 426:Thing_Stop(0, 1), // [sector]
|
||||||
|
int 427:Player_AddScore(1), // amount
|
||||||
|
int 428:FOF_StartMovement(8, 9), // tag, bottom low, bottom hi, top low, top hi, speed, start delay, swap delay[, invert]
|
||||||
|
int 429:Ceiling_Crush(2, 3), // tag, speed[, constant]
|
||||||
|
int 430:Floor_Crush(2, 3), // tag, speed[, constant]
|
||||||
|
int 431:Sector_Crush(2, 3), // tag, speed[, constant]
|
||||||
|
// int 432:Thing_Set2D(1), // bool
|
||||||
|
int 433:Thing_SetFlip(1), // bool
|
||||||
|
// int 434:Player_CustomPower(?),
|
||||||
|
int 435:Scroll_Change(3), // tag, dir, speed
|
||||||
|
int 436:FOF_Shatter(2), // target, control
|
||||||
|
int 437:Player_DisableControl(1, 2), // time[, allowjump]
|
||||||
|
int 438:Thing_SetScale(1), // size
|
||||||
|
int 439:Line_CopyTextures(1, 2), // tag[, existing]
|
||||||
|
// int 440:Level_StartMetalSonicRace(0),
|
||||||
|
int 441:SetUnlockableTrigger(1), // ID
|
||||||
|
int 442:Sector_NextThingState(2, 3), // tag, type[, state]
|
||||||
|
int 443:Lua_Execute(1), // script
|
||||||
|
int 444:Earthquake(1, 2), // tics[, intensity]
|
||||||
|
int 445:FOF_SetExists(2, 3), // target, control[, exists]
|
||||||
|
int 446:FOF_Crumble(2, 3), // target, control[, options]
|
||||||
|
int 447:Sector_SetColormap(2, 8), // tag, light[, fade, extra, flags, force light, force fade, force extra]
|
||||||
|
int 448:SetSkyboxViewpoint(1, 2), // viewpoint ID[, global]. Center point is now a separate function
|
||||||
|
int 449:SetBossActive(1, 2), // boss ID[, active?]
|
||||||
|
int 450:ACS_ExecuteAlways(1,4), // script[, arg1, arg2, arg3]
|
||||||
|
int 451:ACS_ExecuteRandomAlways(2,5), // script low, script high[, arg1, arg2, arg3]
|
||||||
|
int 452:FOF_SetAlpha(3, 5), // target, control, alpha[, add, update flags]
|
||||||
|
int 453:FOF_Fade(4, 5), // target, control, alpha, time[, options]
|
||||||
|
int 454:FOF_StopFade(2, 3), // target, control[, interrupt]
|
||||||
|
// int 455:Sector_FadeColormap(?), // TODO
|
||||||
|
int 456:Sector_StopColormapFade(1), // tag
|
||||||
|
int 457:Thing_StartTracking(5), // tag, tolerance, time, script, continue
|
||||||
|
int 458:Thing_StopTracking(0),
|
||||||
|
int 459:Prompt_Open(1, 3), // prompt[, allow control, close script]. Closing is now a separate function.
|
||||||
|
int 460:Player_AddRings(1, 2), // amount[, freq]
|
||||||
|
int 461:Thing_Spawn(4, 5), // type, x, y, z[, angle]. Randomized coordinates can be handled by code.
|
||||||
|
int 462:Level_Stopwatch(0),
|
||||||
|
int 463:Thing_Dye(1), // color
|
||||||
|
// int 464:TriggerEggCapsule(1, 2), // capsule ID[, end level]
|
||||||
|
|
||||||
|
int 466:Level_SetFailed(0, 1), // [success?]
|
||||||
|
|
||||||
|
int 480:Polyobj_DoorSlide(5), // po, speed, angle, dist, delay
|
||||||
|
int 481:Polyobj_DoorSwing(4), // po, speed, angle, delay
|
||||||
|
int 482:Polyobj_Move(4), // po, speed, angle, dist
|
||||||
|
int 483:Polyobj_OR_Move(4), // po, speed, angle, dist
|
||||||
|
int 484:Polyobj_RotateRight(3), // po, speed, angle
|
||||||
|
int 485:Polyobj_OR_RotateRight(3), // po, speed, angle
|
||||||
|
int 486:Polyobj_RotateLeft(3), // po, speed, angle
|
||||||
|
int 487:Polyobj_OR_RotateLeft(3), // po, speed, angle
|
||||||
|
int 488:Polyobj_MoveByWaypoints(4), // po, speed, sequence[, options]
|
||||||
|
int 489:Polyobj_InvisibleIntangible(1, 2), // po[, just visibility]
|
||||||
|
int 490:Polyobj_VisibleTangible(1, 2), // po[, just visibility]
|
||||||
|
int 491:Polyobj_SetAlpha(2, 3), // po, alpha[, add]
|
||||||
|
int 492:Polyobj_FadeAlpha(2, 3), // po, alpha, speed[, options]
|
||||||
|
|
||||||
|
int 499:Sector_ToggleWaypoints(0, 1), // [enable?]
|
||||||
|
|
||||||
|
// internal functions have negative values
|
||||||
|
int -1:GetLineUDMFInt(2, int, str),
|
||||||
|
fixed -2:GetLineUDMFFixed(2, int, str),
|
||||||
|
int -3:GetThingUDMFInt(2, int, str),
|
||||||
|
fixed -4:GetThingUDMFFixed(2, int, str),
|
||||||
|
int -5:GetSectorUDMFInt(2, int, str),
|
||||||
|
fixed -6:GetSectorUDMFFixed(2, int, str),
|
||||||
|
int -7:GetSideUDMFInt(3, int, int, str),
|
||||||
|
fixed -8:GetSideUDMFFixed(3, int, int, str),
|
||||||
|
int -9:ACS_Execute(1, int, int, int, int),
|
||||||
|
int -10:ACS_Suspend(1, int),
|
||||||
|
int -11:ACS_Terminate(1, int),
|
||||||
|
int -12:ACS_ExecuteWithResult(1, int, int, int, int),
|
||||||
|
int -13:ACS_NamedExecute(1, str, int, int, int),
|
||||||
|
int -14:ACS_NamedSuspend(1, str),
|
||||||
|
int -15:ACS_NamedTerminate(1, str),
|
||||||
|
int -16:ACS_NamedExecuteWithResult(1, str, int, int, int),
|
||||||
|
int -17:ACS_NamedExecuteAlways(1, str, int, int, int),
|
||||||
|
int -18:UniqueTID(0, int, int),
|
||||||
|
int -19:IsTIDUsed(1, int),
|
||||||
|
int -20:Sqrt(1, int),
|
||||||
|
fixed -21:FixedSqrt(1, fixed),
|
||||||
|
fixed -22:VectorLength(2, fixed, fixed),
|
||||||
|
int -23:StrCmp(2, str, str, int),
|
||||||
|
int -24:StrICmp(2, str, str, int),
|
||||||
|
int -24:StrCaseCmp(2, str, str, int),
|
||||||
|
str -25:StrLeft(2, str, int),
|
||||||
|
str -25:StrRight(2, str, int),
|
||||||
|
str -26:StrMid(3, str, int, int),
|
||||||
|
int -27:GetChar(2, str, int),
|
||||||
|
int -28:StrArg(1, str),
|
||||||
|
fixed -29:Floor(1, fixed),
|
||||||
|
fixed -30:Round(1, fixed),
|
||||||
|
fixed -31:Ceil(1, fixed),
|
||||||
|
|
||||||
|
void { 2 }:__suspend(void),
|
||||||
|
|
||||||
|
// 0 to 56: Implemented by ACSVM
|
||||||
|
void { 55, 56}:Delay(int),
|
||||||
|
int { 57, 58}:Random(int, int),
|
||||||
|
fixed { 57, 58}:RandomFixed(fixed, fixed),
|
||||||
|
int { 59, 60}:ThingCount(int, int),
|
||||||
|
void { 61, 62}:TagWait(int),
|
||||||
|
void { 63, 64}:PolyWait(int),
|
||||||
|
void { 65, 66}:ChangeFloor(int, str),
|
||||||
|
void { 67, 68}:ChangeCeiling(int, str),
|
||||||
|
// 69 to 79: Implemented by ACSVM
|
||||||
|
int { 80 }:LineSide(void),
|
||||||
|
void { 81, 82}:ScriptWait(int), // 81 to 82: Implemented by ACSVM
|
||||||
|
void { 83 }:ClearLineSpecial(void),
|
||||||
|
// 84 to 85: Implemented by ACSVM
|
||||||
|
void { 85 }:BeginPrint(void),
|
||||||
|
void { 85 }:BeginPrintBold(void),
|
||||||
|
void { 86 }:EndPrint(void),
|
||||||
|
void { 87 }:PrintString(str), // 87 to 89: Implemented by ACSVM
|
||||||
|
void { 88 }:PrintInt(int),
|
||||||
|
void { 88 }:PrintNumber(int),
|
||||||
|
void { 89 }:PrintChar(int),
|
||||||
|
int { 90 }:PlayerCount(void),
|
||||||
|
int { 91 }:GameType(void),
|
||||||
|
int { 92 }:GameSpeed(void),
|
||||||
|
int { 93 }:Timer(void),
|
||||||
|
void { 94 }:SectorSound(str, int),
|
||||||
|
void { 95 }:AmbientSound(str, int),
|
||||||
|
|
||||||
|
void { 97 }:SetLineTexture(int, int, int, str),
|
||||||
|
void { 98 }:SetLineBlocking(int, int),
|
||||||
|
void { 99 }:SetLineSpecial(int, int, int, int, int, int, int),
|
||||||
|
void {100 }:ThingSound(int, str, int),
|
||||||
|
void {101 }:EndPrintBold(void),
|
||||||
|
|
||||||
|
int {118 }:IsMultiplayer(void),
|
||||||
|
int {118 }:IsNetworkGame(void),
|
||||||
|
|
||||||
|
int {135 }:SinglePlayer(void),
|
||||||
|
int {136 }:FixedMul(int, int), // 136 to 137: Implemented by ACSVM
|
||||||
|
int {137 }:FixedDiv(int, int),
|
||||||
|
|
||||||
|
void {157 }:PrintFixed(fixed), // 157: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 167 to 173: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 175 to 179: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 181 to 189: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 203 to 217: Implemented by ACSVM
|
||||||
|
|
||||||
|
fixed {220 }:Sin(fixed),
|
||||||
|
fixed {221 }:Cos(fixed),
|
||||||
|
fixed {222 }:VectorAngle(fixed, fixed),
|
||||||
|
|
||||||
|
// 225 to 243: Implemented by ACSVM
|
||||||
|
|
||||||
|
int {247 }:PlayerNumber(void),
|
||||||
|
int {248 }:ActivatorTID(void),
|
||||||
|
|
||||||
|
int {253 }:StrLen(str), // 253: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 256 to 257: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 263: Implemented by ACSVM
|
||||||
|
|
||||||
|
int {267 }:PlayerInGame(int),
|
||||||
|
int {268 }:PlayerIsBot(int),
|
||||||
|
|
||||||
|
void {349 }:PrintBinary(int),
|
||||||
|
void {350 }:PrintHex(int),
|
||||||
|
|
||||||
|
void {273 }:PrintModuleCharArray(int, int), // 273 to 275: Implemented by ACSVM
|
||||||
|
void {274 }:PrintWorldCharArray(int, int),
|
||||||
|
void {275 }:PrintGlobalCharArray(int, int),
|
||||||
|
|
||||||
|
// 291 to 325: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 330: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 349 to 361: Implemented by ACSVM
|
||||||
|
|
||||||
|
str {352 }:EndStrParam(void),
|
||||||
|
void {353 }:PrintModuleCharRange(int, int, int, int),
|
||||||
|
void {354 }:PrintWorldCharRange(int, int, int, int),
|
||||||
|
void {355 }:PrintGlobalCharRange(int, int, int, int),
|
||||||
|
int {356 }:StrCpyToModuleCharRange(int, int, int, int, str, int),
|
||||||
|
int {357 }:StrCpyToWorldCharRange(int, int, int, int, str, int),
|
||||||
|
int {358 }:StrCpyToGlobalCharRange(int, int, int, int, str, int),
|
||||||
|
|
||||||
|
void {361 }:NamedScriptWait(str),
|
||||||
|
|
||||||
|
// 363 to 380: Implemented by ACSVM
|
||||||
|
|
||||||
|
void {378 }:PrintLocalCharArray(int, int),
|
||||||
|
void {379 }:PrintLocalCharRange(int, int, int, int),
|
||||||
|
int {380 }:StrCpyToLocalCharRange(int, int, int, int, str, int);
|
||||||
|
|
||||||
|
print __Print
|
||||||
|
(
|
||||||
|
(begin): BeginPrint,
|
||||||
|
(end): EndPrint,
|
||||||
|
|
||||||
|
ACS_PrintPropertyBase()
|
||||||
|
);
|
||||||
|
|
||||||
|
print __PrintBold
|
||||||
|
(
|
||||||
|
(begin): BeginPrintBold,
|
||||||
|
(end): EndPrintBold,
|
||||||
|
|
||||||
|
ACS_PrintPropertyBase()
|
||||||
|
);
|
||||||
|
|
||||||
|
print PrintRaw
|
||||||
|
(
|
||||||
|
ACS_PrintPropertyBase()
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif//__GDCC_Header__ACS__rrspecial_acs__
|
||||||
|
|
||||||
|
|
@ -27,11 +27,13 @@ extern "C"
|
||||||
//
|
//
|
||||||
// ACSVM_Module_GetName
|
// ACSVM_Module_GetName
|
||||||
//
|
//
|
||||||
ACSVM_ModuleName ACSVM_Module_GetName(ACSVM_Module const *module_)
|
void ACSVM_Module_GetName(ACSVM_Module const *module_, ACSVM_ModuleName *out)
|
||||||
{
|
{
|
||||||
auto module = reinterpret_cast<ACSVM::Module const *>(module_);
|
auto module = reinterpret_cast<ACSVM::Module const *>(module_);
|
||||||
|
|
||||||
return {reinterpret_cast<ACSVM_String *>(module->name.s), module->name.p, module->name.i};
|
out->s = reinterpret_cast<ACSVM_String *>(module->name.s);
|
||||||
|
out->p = module->name.p;
|
||||||
|
out->i = module->name.i;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ struct ACSVM_ModuleName
|
||||||
// Extern Functions |
|
// Extern Functions |
|
||||||
//
|
//
|
||||||
|
|
||||||
ACSVM_ModuleName ACSVM_Module_GetName(ACSVM_Module const *module);
|
void ACSVM_Module_GetName(ACSVM_Module const *module, ACSVM_ModuleName *out);
|
||||||
|
|
||||||
// Returns false if reading fails.
|
// Returns false if reading fails.
|
||||||
bool ACSVM_Module_ReadBytecode(ACSVM_Module *module, ACSVM_Byte const *data, size_t size);
|
bool ACSVM_Module_ReadBytecode(ACSVM_Module *module, ACSVM_Byte const *data, size_t size);
|
||||||
|
|
|
||||||
|
|
@ -125,3 +125,5 @@ k_director.c
|
||||||
k_follower.c
|
k_follower.c
|
||||||
k_profiles.c
|
k_profiles.c
|
||||||
k_acs.c
|
k_acs.c
|
||||||
|
k_acs-func.c
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1863,6 +1863,7 @@ static const char *CON_LoadingStrings[LOADED_ALLDONE+1] =
|
||||||
"Init rendering daemon...", //LOADED_RINIT
|
"Init rendering daemon...", //LOADED_RINIT
|
||||||
"Init audio subsystem...", //LOADED_SINITSFXCHANNELS
|
"Init audio subsystem...", //LOADED_SINITSFXCHANNELS
|
||||||
"Cache HUD...", //LOADED_STINIT
|
"Cache HUD...", //LOADED_STINIT
|
||||||
|
"Init ACSVM...", //LOADED_ACSINIT
|
||||||
"Check game status...", //LOADED_DCHECKNETGAME
|
"Check game status...", //LOADED_DCHECKNETGAME
|
||||||
"Now starting..."
|
"Now starting..."
|
||||||
}; // see also con_loadprogress_t in console.h
|
}; // see also con_loadprogress_t in console.h
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ typedef enum
|
||||||
LOADED_RINIT,
|
LOADED_RINIT,
|
||||||
LOADED_SINITSFXCHANNELS,
|
LOADED_SINITSFXCHANNELS,
|
||||||
LOADED_STINIT,
|
LOADED_STINIT,
|
||||||
|
LOADED_ACSINIT,
|
||||||
LOADED_DCHECKNETGAME,
|
LOADED_DCHECKNETGAME,
|
||||||
LOADED_ALLDONE = LOADED_DCHECKNETGAME,
|
LOADED_ALLDONE = LOADED_DCHECKNETGAME,
|
||||||
} con_loadprogress_t;
|
} con_loadprogress_t;
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@
|
||||||
#include "k_boss.h"
|
#include "k_boss.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "m_random.h" // P_ClearRandom
|
#include "m_random.h" // P_ClearRandom
|
||||||
|
#include "k_acs.h"
|
||||||
|
|
||||||
#ifdef CMAKECONFIG
|
#ifdef CMAKECONFIG
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
@ -1612,6 +1613,10 @@ void D_SRB2Main(void)
|
||||||
ST_Init();
|
ST_Init();
|
||||||
CON_SetLoadingProgress(LOADED_STINIT);
|
CON_SetLoadingProgress(LOADED_STINIT);
|
||||||
|
|
||||||
|
CONS_Printf("ACS_Init(): Init Action Code Script VM.\n");
|
||||||
|
ACS_Init();
|
||||||
|
CON_SetLoadingProgress(LOADED_ACSINIT);
|
||||||
|
|
||||||
//------------------------------------------------ COMMAND LINE PARAMS
|
//------------------------------------------------ COMMAND LINE PARAMS
|
||||||
|
|
||||||
// this must be done after loading gamedata,
|
// this must be done after loading gamedata,
|
||||||
|
|
|
||||||
51
src/k_acs-func.c
Normal file
51
src/k_acs-func.c
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
// DR. ROBOTNIK'S RING RACERS
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
|
||||||
|
// Copyright (C) 2022 by Kart Krew
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file k_acs-func.c
|
||||||
|
/// \brief ACS CallFunc definitions
|
||||||
|
|
||||||
|
#include "k_acs.h"
|
||||||
|
|
||||||
|
#include "doomtype.h"
|
||||||
|
#include "doomdef.h"
|
||||||
|
#include "d_think.h"
|
||||||
|
#include "p_mobj.h"
|
||||||
|
#include "p_tick.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
|
||||||
|
#include "CAPI/BinaryIO.h"
|
||||||
|
#include "CAPI/Environment.h"
|
||||||
|
#include "CAPI/Module.h"
|
||||||
|
#include "CAPI/PrintBuf.h"
|
||||||
|
#include "CAPI/Scope.h"
|
||||||
|
#include "CAPI/String.h"
|
||||||
|
#include "CAPI/Thread.h"
|
||||||
|
|
||||||
|
bool ACS_CF_EndPrint(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
||||||
|
{
|
||||||
|
ACSVM_PrintBuf *buf = NULL;
|
||||||
|
|
||||||
|
(void)argV;
|
||||||
|
(void)argC;
|
||||||
|
|
||||||
|
buf = ACSVM_Thread_GetPrintBuf(thread);
|
||||||
|
CONS_Printf("%s\n", ACSVM_PrintBuf_GetData(buf));
|
||||||
|
ACSVM_PrintBuf_Drop(buf);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ACS_CF_Timer(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
||||||
|
{
|
||||||
|
(void)argV;
|
||||||
|
(void)argC;
|
||||||
|
|
||||||
|
ACSVM_Thread_DataStk_Push(thread, leveltime);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
279
src/k_acs.c
279
src/k_acs.c
|
|
@ -14,6 +14,10 @@
|
||||||
|
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
|
#include "doomstat.h"
|
||||||
|
#include "z_zone.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
#include "i_system.h"
|
||||||
|
|
||||||
#include "CAPI/BinaryIO.h"
|
#include "CAPI/BinaryIO.h"
|
||||||
#include "CAPI/Environment.h"
|
#include "CAPI/Environment.h"
|
||||||
|
|
@ -23,29 +27,264 @@
|
||||||
#include "CAPI/String.h"
|
#include "CAPI/String.h"
|
||||||
#include "CAPI/Thread.h"
|
#include "CAPI/Thread.h"
|
||||||
|
|
||||||
static tic_t ExecTime = 0;
|
static ACSVM_Environment *ACSenv = NULL;
|
||||||
|
|
||||||
boolean K_ACS_EndPrint(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
ACSVM_Environment *ACS_GetEnvironment(void)
|
||||||
{
|
{
|
||||||
(void)thread;
|
return ACSenv;
|
||||||
(void)argV;
|
|
||||||
(void)argC;
|
|
||||||
|
|
||||||
/*
|
|
||||||
ACSVM_PrintBuf *buf = ACSVM_Thread_GetPrintBuf(thread);
|
|
||||||
|
|
||||||
CONS_Printf("%s\n", ACSVM_PrintBuf_GetData(buf));
|
|
||||||
ACSVM_PrintBuf_Drop(buf);
|
|
||||||
*/
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean K_ACS_Timer(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
ACSVM_GlobalScope *ACS_GetGlobal(void)
|
||||||
{
|
{
|
||||||
(void)argV;
|
return ACSVM_Environment_GetGlobalScope(ACSenv, 0);
|
||||||
(void)argC;
|
}
|
||||||
|
|
||||||
ACSVM_Thread_DataStk_Push(thread, ExecTime);
|
ACSVM_HubScope *ACS_GetHub(void)
|
||||||
return false;
|
{
|
||||||
|
ACSVM_GlobalScope *global = ACS_GetGlobal();
|
||||||
|
|
||||||
|
if (global == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ACSVM_GlobalScope_GetHubScope(global, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACSVM_MapScope *ACS_GetMap(void)
|
||||||
|
{
|
||||||
|
ACSVM_HubScope *hub = ACS_GetHub();
|
||||||
|
|
||||||
|
if (hub == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ACSVM_HubScope_GetMapScope(hub, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ACS_EnvBadAlloc(ACSVM_Environment *env, char const *what)
|
||||||
|
{
|
||||||
|
(void)env;
|
||||||
|
I_Error("Error allocating memory for ACS (%s)\n", what);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ACS_EnvReadError(ACSVM_Environment *env, char const *what)
|
||||||
|
{
|
||||||
|
(void)env;
|
||||||
|
I_Error("Error reading ACS module (%s)\n", what);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ACS_EnvConstruct(ACSVM_Environment *env)
|
||||||
|
{
|
||||||
|
ACSVM_GlobalScope *global = ACSVM_Environment_GetGlobalScope(env, 0);
|
||||||
|
|
||||||
|
// Activate global scope immediately,
|
||||||
|
// since we don't want it off.
|
||||||
|
ACSVM_GlobalScope_SetActive(global, true);
|
||||||
|
|
||||||
|
// Add the data & function pointers
|
||||||
|
// See also:
|
||||||
|
// https://doomwiki.org/wiki/ACS0_instruction_set
|
||||||
|
//
|
||||||
|
// 0 to 56: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 69 to 79: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 81 to 82: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 84 to 85: Implemented by ACSVM
|
||||||
|
ACSVM_Environment_AddCodeDataACS0(env, 86, "", ACSVM_Code_CallFunc, 0, ACSVM_Environment_AddCallFunc(env, ACS_CF_EndPrint));
|
||||||
|
// 87 to 89: Implemented by ACSVM
|
||||||
|
ACSVM_Environment_AddCodeDataACS0(env, 93, "", ACSVM_Code_CallFunc, 0, ACSVM_Environment_AddCallFunc(env, ACS_CF_Timer));
|
||||||
|
// 136 to 137: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 157: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 167 to 173: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 175 to 179: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 181 to 189: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 203 to 217: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 225 to 243: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 253: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 256 to 257: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 263: Implemented by ACSVM
|
||||||
|
ACSVM_Environment_AddCodeDataACS0(env, 270, "", ACSVM_Code_CallFunc, 0, ACSVM_Environment_AddCallFunc(env, ACS_CF_EndPrint));
|
||||||
|
// 273 to 275: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 291 to 325: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 330: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 349 to 361: Implemented by ACSVM
|
||||||
|
|
||||||
|
// 363 to 380: Implemented by ACSVM
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ACS_EnvLoadModule(ACSVM_Environment *env, ACSVM_Module *module)
|
||||||
|
{
|
||||||
|
ACSVM_ModuleName name = {0};
|
||||||
|
const char *str = NULL;
|
||||||
|
|
||||||
|
size_t lumpLen = 0;
|
||||||
|
|
||||||
|
ACSVM_Byte *data = NULL;
|
||||||
|
size_t size = 0;
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
(void)env;
|
||||||
|
|
||||||
|
ACSVM_Module_GetName(module, &name);
|
||||||
|
str = ACSVM_String_GetStr(name.s);
|
||||||
|
|
||||||
|
if (name.i == (size_t)LUMPERROR)
|
||||||
|
{
|
||||||
|
// No lump given for module.
|
||||||
|
CONS_Alert(CONS_ERROR, "Bad lump for ACS module \"%s\"\n", str);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lumpLen = W_LumpLength(name.i);
|
||||||
|
|
||||||
|
if (W_IsLumpWad(name.i) == true || lumpLen == 0)
|
||||||
|
{
|
||||||
|
// The lump given is a virtual resource.
|
||||||
|
// Try to grab it from there.
|
||||||
|
virtres_t *vRes = vres_GetMap(name.i);
|
||||||
|
virtlump_t *vLump = vres_Find(vRes, "BEHAVIOR");
|
||||||
|
|
||||||
|
CONS_Printf("Attempting to load ACS module from map's virtual resource...\n");
|
||||||
|
|
||||||
|
if (vLump != NULL)
|
||||||
|
{
|
||||||
|
data = Z_Calloc(vLump->size, PU_STATIC, NULL);
|
||||||
|
memcpy(data, vLump->data, vLump->size);
|
||||||
|
size = vLump->size;
|
||||||
|
CONS_Printf("Successfully found BEHAVIOR lump.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CONS_Printf("No BEHAVIOR lump found.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// It's a real lump.
|
||||||
|
data = Z_Calloc(lumpLen, PU_STATIC, NULL);
|
||||||
|
W_ReadLump(name.i, data);
|
||||||
|
size = lumpLen;
|
||||||
|
CONS_Printf("Loading ACS module directly from lump.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data != NULL && size > 0)
|
||||||
|
{
|
||||||
|
CONS_Printf("Reading bytecode of ACS module...\n");
|
||||||
|
ret = ACSVM_Module_ReadBytecode(module, data, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Unlike Hexen, BEHAVIOR is not required.
|
||||||
|
// Simply ignore in this instance.
|
||||||
|
CONS_Printf("No data received, ignoring...\n");
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Z_Free(data);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ACS_Init(void)
|
||||||
|
{
|
||||||
|
// Initialize ACS on engine start-up.
|
||||||
|
ACSVM_EnvironmentFuncs funcs = {0};
|
||||||
|
|
||||||
|
funcs.bad_alloc = ACS_EnvBadAlloc;
|
||||||
|
funcs.readError = ACS_EnvReadError;
|
||||||
|
funcs.ctor = ACS_EnvConstruct;
|
||||||
|
funcs.loadModule = ACS_EnvLoadModule;
|
||||||
|
|
||||||
|
ACSenv = ACSVM_AllocEnvironment(&funcs, NULL);
|
||||||
|
|
||||||
|
I_AddExitFunc(ACS_Shutdown);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ACS_Shutdown(void)
|
||||||
|
{
|
||||||
|
// Delete ACS environment.
|
||||||
|
ACSVM_FreeEnvironment(ACSenv);
|
||||||
|
ACSenv = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ACS_LoadLevelScripts(size_t mapID)
|
||||||
|
{
|
||||||
|
ACSVM_Environment *env = ACSenv;
|
||||||
|
ACSVM_StringTable *strTab = ACSVM_Environment_GetStringTable(env);
|
||||||
|
|
||||||
|
ACSVM_HubScope *hub = NULL;
|
||||||
|
ACSVM_MapScope *map = NULL;
|
||||||
|
|
||||||
|
ACSVM_Module **modules = NULL;
|
||||||
|
size_t modules_len = 0;
|
||||||
|
size_t modules_size = 4;
|
||||||
|
|
||||||
|
// No hub support. Simply always reset it.
|
||||||
|
hub = ACS_GetHub();
|
||||||
|
ACSVM_HubScope_SetActive(hub, true);
|
||||||
|
|
||||||
|
// Start up map scope.
|
||||||
|
map = ACSVM_HubScope_GetMapScope(hub, 0);
|
||||||
|
ACSVM_MapScope_SetActive(map, true);
|
||||||
|
|
||||||
|
// Allocate module list.
|
||||||
|
modules = Z_Calloc(modules_size * sizeof(ACSVM_Module *), PU_STATIC, NULL);
|
||||||
|
|
||||||
|
// Insert BEHAVIOR lump.
|
||||||
|
{
|
||||||
|
char const *str = mapheaderinfo[mapID]->lumpname;
|
||||||
|
size_t len = strlen(str);
|
||||||
|
size_t hash = ACSVM_StrHash(str, len);
|
||||||
|
|
||||||
|
ACSVM_ModuleName name = {0};
|
||||||
|
|
||||||
|
name.s = ACSVM_StringTable_GetStringByData(strTab, str, len, hash);
|
||||||
|
name.i = mapheaderinfo[mapID]->lumpnum;
|
||||||
|
|
||||||
|
if (modules_len >= modules_size)
|
||||||
|
{
|
||||||
|
modules_size *= 2;
|
||||||
|
modules = Z_Realloc(modules, modules_size * sizeof(ACSVM_Module *), PU_STATIC, &modules);
|
||||||
|
}
|
||||||
|
|
||||||
|
modules[modules_len] = ACSVM_Environment_GetModule(env, name);
|
||||||
|
modules_len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modules_len > 0)
|
||||||
|
{
|
||||||
|
// Register the modules with map scope.
|
||||||
|
ACSVM_MapScope_AddModules(map, modules, modules_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start OPEN scripts.
|
||||||
|
ACSVM_MapScope_ScriptStartType(map, 1, NULL, 0, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ACS_Tick(void)
|
||||||
|
{
|
||||||
|
ACSVM_Environment *env = ACSenv;
|
||||||
|
|
||||||
|
if (ACSVM_Environment_HasActiveThread(env) == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ACSVM_Environment_Exec(env);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
23
src/k_acs.h
23
src/k_acs.h
|
|
@ -24,7 +24,26 @@
|
||||||
#include "CAPI/String.h"
|
#include "CAPI/String.h"
|
||||||
#include "CAPI/Thread.h"
|
#include "CAPI/Thread.h"
|
||||||
|
|
||||||
boolean K_ACS_EndPrint(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
typedef enum
|
||||||
boolean K_ACS_Timer(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
{
|
||||||
|
ACS_ST_OPEN = 1, // OPEN: Runs once when the level starts.
|
||||||
|
ACS_ST_RESPAWN = 2, // RESPAWN: Runs when a player respawns.
|
||||||
|
ACS_ST_DEATH = 3, // DEATH: Runs when a player dies.
|
||||||
|
ACS_ST_ENTER = 4, // ENTER: Runs when a player enters the game; both on start of the level, and when un-spectating.
|
||||||
|
} acs_scriptType_e;
|
||||||
|
|
||||||
|
ACSVM_Environment *ACS_GetEnvironment(void);
|
||||||
|
|
||||||
|
ACSVM_GlobalScope *ACS_GetGlobal(void);
|
||||||
|
ACSVM_HubScope *ACS_GetHub(void);
|
||||||
|
ACSVM_MapScope *ACS_GetMap(void);
|
||||||
|
|
||||||
|
void ACS_Init(void);
|
||||||
|
void ACS_Shutdown(void);
|
||||||
|
void ACS_LoadLevelScripts(size_t mapID);
|
||||||
|
void ACS_Tick(void);
|
||||||
|
|
||||||
|
bool ACS_CF_EndPrint(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||||
|
bool ACS_CF_Timer(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||||
|
|
||||||
#endif // __K_ACS__
|
#endif // __K_ACS__
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ precise_t ps_botticcmd_time = 0;
|
||||||
precise_t ps_thinkertime = 0;
|
precise_t ps_thinkertime = 0;
|
||||||
|
|
||||||
precise_t ps_thlist_times[NUM_THINKERLISTS];
|
precise_t ps_thlist_times[NUM_THINKERLISTS];
|
||||||
|
precise_t ps_acs_time = 0;
|
||||||
|
|
||||||
int ps_checkposition_calls = 0;
|
int ps_checkposition_calls = 0;
|
||||||
|
|
||||||
|
|
@ -350,7 +351,8 @@ static void M_DrawTickStats(void)
|
||||||
ps_tictime -
|
ps_tictime -
|
||||||
ps_playerthink_time -
|
ps_playerthink_time -
|
||||||
ps_thinkertime -
|
ps_thinkertime -
|
||||||
ps_lua_thinkframe_time;
|
ps_lua_thinkframe_time -
|
||||||
|
ps_acs_time;
|
||||||
|
|
||||||
perfstatrow_t tictime_row[] = {
|
perfstatrow_t tictime_row[] = {
|
||||||
{"logic ", "Game logic: ", &ps_tictime},
|
{"logic ", "Game logic: ", &ps_tictime},
|
||||||
|
|
@ -374,6 +376,7 @@ static void M_DrawTickStats(void)
|
||||||
|
|
||||||
perfstatrow_t extra_thinker_time_row[] = {
|
perfstatrow_t extra_thinker_time_row[] = {
|
||||||
{"lthinkf", "LUAh_ThinkFrame:", &ps_lua_thinkframe_time},
|
{"lthinkf", "LUAh_ThinkFrame:", &ps_lua_thinkframe_time},
|
||||||
|
{"acs ", "ACS_Tick: ", &ps_acs_time},
|
||||||
{"botcmd ", "Bot logic: ", &ps_botticcmd_time},
|
{"botcmd ", "Bot logic: ", &ps_botticcmd_time},
|
||||||
{"other ", "Other: ", &extratime},
|
{"other ", "Other: ", &extratime},
|
||||||
{0}
|
{0}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ extern precise_t ps_botticcmd_time;
|
||||||
extern precise_t ps_thinkertime;
|
extern precise_t ps_thinkertime;
|
||||||
|
|
||||||
extern precise_t ps_thlist_times[];
|
extern precise_t ps_thlist_times[];
|
||||||
|
extern precise_t ps_acs_time;
|
||||||
|
|
||||||
extern int ps_checkposition_calls;
|
extern int ps_checkposition_calls;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,7 @@
|
||||||
#include "k_brightmap.h"
|
#include "k_brightmap.h"
|
||||||
#include "k_terrain.h" // TRF_TRIPWIRE
|
#include "k_terrain.h" // TRF_TRIPWIRE
|
||||||
#include "k_director.h" // K_InitDirector
|
#include "k_director.h" // K_InitDirector
|
||||||
|
#include "k_acs.h"
|
||||||
|
|
||||||
// Replay names have time
|
// Replay names have time
|
||||||
#if !defined (UNDER_CE)
|
#if !defined (UNDER_CE)
|
||||||
|
|
@ -4252,6 +4253,12 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||||
// clear special respawning que
|
// clear special respawning que
|
||||||
iquehead = iquetail = 0;
|
iquehead = iquetail = 0;
|
||||||
|
|
||||||
|
// Initialize ACS scripts
|
||||||
|
if (!fromnetsave)
|
||||||
|
{
|
||||||
|
ACS_LoadLevelScripts(gamemap-1);
|
||||||
|
}
|
||||||
|
|
||||||
// Remove the loading shit from the screen
|
// Remove the loading shit from the screen
|
||||||
if (rendermode != render_none && !titlemapinaction && !reloadinggamestate)
|
if (rendermode != render_none && !titlemapinaction && !reloadinggamestate)
|
||||||
F_WipeColorFill(levelfadecol);
|
F_WipeColorFill(levelfadecol);
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
#include "k_boss.h"
|
#include "k_boss.h"
|
||||||
#include "k_waypoint.h"
|
#include "k_waypoint.h"
|
||||||
#include "k_director.h"
|
#include "k_director.h"
|
||||||
|
#include "k_acs.h"
|
||||||
|
|
||||||
tic_t leveltime;
|
tic_t leveltime;
|
||||||
|
|
||||||
|
|
@ -359,6 +360,10 @@ static inline void P_RunThinkers(void)
|
||||||
|
|
||||||
if ((gametyperules & GTR_BUMPERS) && battleovertime.enabled)
|
if ((gametyperules & GTR_BUMPERS) && battleovertime.enabled)
|
||||||
K_RunBattleOvertime();
|
K_RunBattleOvertime();
|
||||||
|
|
||||||
|
ps_acs_time = I_GetPreciseTime();
|
||||||
|
ACS_Tick();
|
||||||
|
ps_acs_time = I_GetPreciseTime() - ps_acs_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue