• R/O
  • SSH

zandronum-zdoom-sync: Commit


Commit MetaInfo

Revisionbaea43980f5706560b39637774649047680b9955 (tree)
Time2014-07-27 12:58:47
AuthorRandy Heit <rheit@zdoo...>
CommiterRandy Heit

Log Message

Add script array support to ZDoom

Change Summary

Incremental Difference

diff -r aab96d2cda11 -r baea43980f57 src/p_acs.cpp
--- a/src/p_acs.cpp Thu Jan 28 12:04:47 2016 +0100
+++ b/src/p_acs.cpp Sat Jul 26 22:58:47 2014 -0500
@@ -251,10 +251,11 @@
251251
252252 struct CallReturn
253253 {
254- CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, bool discard, unsigned int runaway)
254+ CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, ACSLocalArrays *arrays, bool discard, unsigned int runaway)
255255 : ReturnFunction(func),
256256 ReturnModule(module),
257257 ReturnLocals(locals),
258+ ReturnArrays(arrays),
258259 ReturnAddress(pc),
259260 bDiscardResult(discard),
260261 EntryInstrCount(runaway)
@@ -263,6 +264,7 @@
263264 ScriptFunction *ReturnFunction;
264265 FBehavior *ReturnModule;
265266 SDWORD *ReturnLocals;
267+ ACSLocalArrays *ReturnArrays;
266268 int ReturnAddress;
267269 int bDiscardResult;
268270 unsigned int EntryInstrCount;
@@ -2070,6 +2072,26 @@
20702072 }
20712073 }
20722074
2075+static int ParseLocalArrayChunk(void *chunk, ACSLocalArrays *arrays, int offset)
2076+{
2077+ unsigned count = (LittleShort(((unsigned *)chunk)[1]) - 2) / 4;
2078+ int *sizes = (int *)((BYTE *)chunk + 10);
2079+ arrays->Count = count;
2080+ if (count > 0)
2081+ {
2082+ ACSLocalArrayInfo *info = new ACSLocalArrayInfo[count];
2083+ arrays->Info = info;
2084+ for (unsigned i = 0; i < count; ++i)
2085+ {
2086+ info[i].Size = LittleLong(sizes[i]);
2087+ info[i].Offset = offset;
2088+ offset += info[i].Size;
2089+ }
2090+ }
2091+ // Return the new local variable size, with space for the arrays
2092+ return offset;
2093+}
2094+
20732095 FBehavior::FBehavior (int lumpnum, FileReader * fr, int len)
20742096 {
20752097 BYTE *object;
@@ -2216,12 +2238,45 @@
22162238 {
22172239 DWORD *chunk;
22182240
2219- Functions = FindChunk (MAKE_ID('F','U','N','C'));
2220- if (Functions != NULL)
2221- {
2222- NumFunctions = LittleLong(((DWORD *)Functions)[1]) / 8;
2223- Functions += 8;
2241+ // Load functions
2242+ BYTE *funcs;
2243+ Functions = NULL;
2244+ funcs = FindChunk (MAKE_ID('F','U','N','C'));
2245+ if (funcs != NULL)
2246+ {
2247+ NumFunctions = LittleLong(((DWORD *)funcs)[1]) / 8;
2248+ funcs += 8;
22242249 FunctionProfileData = new ACSProfileInfo[NumFunctions];
2250+ Functions = new ScriptFunction[NumFunctions];
2251+ for (i = 0; i < NumFunctions; ++i)
2252+ {
2253+ ScriptFunctionInFile *funcf = &((ScriptFunctionInFile *)funcs)[i];
2254+ ScriptFunction *funcm = &Functions[i];
2255+ funcm->ArgCount = funcf->ArgCount;
2256+ funcm->HasReturnValue = funcf->HasReturnValue;
2257+ funcm->ImportNum = funcf->ImportNum;
2258+ funcm->LocalCount = funcf->LocalCount;
2259+ funcm->Address = funcf->Address;
2260+ }
2261+ }
2262+
2263+ // Load local arrays for functions
2264+ if (NumFunctions > 0)
2265+ {
2266+ for (chunk = (DWORD *)FindChunk(MAKE_ID('F','A','R','Y')); chunk != NULL; chunk = (DWORD *)NextChunk((BYTE *)chunk))
2267+ {
2268+ int size = LittleLong(chunk[1]);
2269+ if (size >= 6)
2270+ {
2271+ unsigned int func_num = LittleShort(((WORD *)chunk)[4]);
2272+ if (func_num < (unsigned int)NumFunctions)
2273+ {
2274+ ScriptFunction *func = &Functions[func_num];
2275+ // Unlike scripts, functions do not include their arg count in their local count.
2276+ func->LocalCount = ParseLocalArrayChunk(chunk, &func->LocalArrays, func->LocalCount + func->ArgCount) - func->ArgCount;
2277+ }
2278+ }
2279+ }
22252280 }
22262281
22272282 // Load JUMP points
@@ -2532,6 +2587,11 @@
25322587 delete[] ArrayStore;
25332588 ArrayStore = NULL;
25342589 }
2590+ if (Functions != NULL)
2591+ {
2592+ delete[] Functions;
2593+ Functions = NULL;
2594+ }
25352595 if (FunctionProfileData != NULL)
25362596 {
25372597 delete[] FunctionProfileData;
@@ -2699,6 +2759,21 @@
26992759 }
27002760 }
27012761
2762+ // Load script array sizes. (One chunk per script that uses arrays.)
2763+ for (scripts.b = FindChunk(MAKE_ID('S','A','R','Y')); scripts.dw != NULL; scripts.b = NextChunk(scripts.b))
2764+ {
2765+ int size = LittleLong(scripts.dw[1]);
2766+ if (size >= 6)
2767+ {
2768+ int script_num = LittleShort(scripts.w[4]);
2769+ ScriptPtr *ptr = const_cast<ScriptPtr *>(FindScript(script_num));
2770+ if (ptr != NULL)
2771+ {
2772+ ptr->VarCount = ParseLocalArrayChunk(scripts.b, &ptr->LocalArrays, ptr->VarCount);
2773+ }
2774+ }
2775+ }
2776+
27022777 // Load script names (if any)
27032778 scripts.b = FindChunk(MAKE_ID('S','N','A','M'));
27042779 if (scripts.dw != NULL)
@@ -6956,14 +7031,50 @@
69567031 return res;
69577032 }
69587033
7034+static bool CharArrayParms(int &capacity, int &offset, int &a, int *Stack, int &sp, bool ranged)
7035+{
7036+ if (ranged)
7037+ {
7038+ capacity = STACK(1);
7039+ offset = STACK(2);
7040+ if (capacity < 1 || offset < 0)
7041+ {
7042+ sp -= 4;
7043+ return false;
7044+ }
7045+ sp -= 2;
7046+ }
7047+ else
7048+ {
7049+ capacity = INT_MAX;
7050+ offset = 0;
7051+ }
7052+ a = STACK(1);
7053+ offset += STACK(2);
7054+ sp -= 2;
7055+ return true;
7056+}
7057+
69597058 int DLevelScript::RunScript ()
69607059 {
69617060 DACSThinker *controller = DACSThinker::ActiveThinker;
69627061 SDWORD *locals = localvars;
7062+ ACSLocalArrays noarrays;
7063+ ACSLocalArrays *localarrays = &noarrays;
69637064 ScriptFunction *activeFunction = NULL;
69647065 FRemapTable *translation = 0;
69657066 int resultValue = 1;
69667067
7068+ if (InModuleScriptNumber >= 0)
7069+ {
7070+ ScriptPtr *ptr = activeBehavior->GetScriptPtr(InModuleScriptNumber);
7071+ assert(ptr != NULL);
7072+ if (ptr != NULL)
7073+ {
7074+ localarrays = &ptr->LocalArrays;
7075+ }
7076+ }
7077+
69677078 // Hexen truncates all special arguments to bytes (only when using an old MAPINFO and old ACS format
69687079 const int specialargmask = ((level.flags2 & LEVEL2_HEXENHACK) && activeBehavior->GetFormat() == ACS_Old) ? 255 : ~0;
69697080
@@ -7338,9 +7449,10 @@
73387449 }
73397450 sp += i;
73407451 ::new(&Stack[sp]) CallReturn(activeBehavior->PC2Ofs(pc), activeFunction,
7341- activeBehavior, mylocals, pcd == PCD_CALLDISCARD, runaway);
7452+ activeBehavior, mylocals, localarrays, pcd == PCD_CALLDISCARD, runaway);
73427453 sp += (sizeof(CallReturn) + sizeof(int) - 1) / sizeof(int);
73437454 pc = module->Ofs2PC (func->Address);
7455+ localarrays = &func->LocalArrays;
73447456 activeFunction = func;
73457457 activeBehavior = module;
73467458 fmt = module->GetFormat();
@@ -7374,6 +7486,7 @@
73747486 activeBehavior = ret->ReturnModule;
73757487 fmt = activeBehavior->GetFormat();
73767488 locals = ret->ReturnLocals;
7489+ localarrays = ret->ReturnArrays;
73777490 if (!ret->bDiscardResult)
73787491 {
73797492 Stack[sp++] = value;
@@ -7472,6 +7585,11 @@
74727585 sp--;
74737586 break;
74747587
7588+ case PCD_ASSIGNSCRIPTARRAY:
7589+ localarrays->Set(locals, NEXTBYTE, STACK(2), STACK(1));
7590+ sp -= 2;
7591+ break;
7592+
74757593 case PCD_ASSIGNMAPARRAY:
74767594 activeBehavior->SetArrayVal (*(activeBehavior->MapVars[NEXTBYTE]), STACK(2), STACK(1));
74777595 sp -= 2;
@@ -7503,6 +7621,10 @@
75037621 PushToStack (ACS_GlobalVars[NEXTBYTE]);
75047622 break;
75057623
7624+ case PCD_PUSHSCRIPTARRAY:
7625+ STACK(1) = localarrays->Get(locals, NEXTBYTE, STACK(1));
7626+ break;
7627+
75067628 case PCD_PUSHMAPARRAY:
75077629 STACK(1) = activeBehavior->GetArrayVal (*(activeBehavior->MapVars[NEXTBYTE]), STACK(1));
75087630 break;
@@ -7535,6 +7657,14 @@
75357657 sp--;
75367658 break;
75377659
7660+ case PCD_ADDSCRIPTARRAY:
7661+ {
7662+ int a = NEXTBYTE, i = STACK(2);
7663+ localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) + STACK(1));
7664+ sp -= 2;
7665+ }
7666+ break;
7667+
75387668 case PCD_ADDMAPARRAY:
75397669 {
75407670 int a = *(activeBehavior->MapVars[NEXTBYTE]);
@@ -7580,6 +7710,14 @@
75807710 sp--;
75817711 break;
75827712
7713+ case PCD_SUBSCRIPTARRAY:
7714+ {
7715+ int a = NEXTBYTE, i = STACK(2);
7716+ localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) - STACK(1));
7717+ sp -= 2;
7718+ }
7719+ break;
7720+
75837721 case PCD_SUBMAPARRAY:
75847722 {
75857723 int a = *(activeBehavior->MapVars[NEXTBYTE]);
@@ -7625,6 +7763,14 @@
76257763 sp--;
76267764 break;
76277765
7766+ case PCD_MULSCRIPTARRAY:
7767+ {
7768+ int a = NEXTBYTE, i = STACK(2);
7769+ localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) * STACK(1));
7770+ sp -= 2;
7771+ }
7772+ break;
7773+
76287774 case PCD_MULMAPARRAY:
76297775 {
76307776 int a = *(activeBehavior->MapVars[NEXTBYTE]);
@@ -7698,6 +7844,19 @@
76987844 }
76997845 break;
77007846
7847+ case PCD_DIVSCRIPTARRAY:
7848+ if (STACK(1) == 0)
7849+ {
7850+ state = SCRIPT_DivideBy0;
7851+ }
7852+ else
7853+ {
7854+ int a = NEXTBYTE, i = STACK(2);
7855+ localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) / STACK(1));
7856+ sp -= 2;
7857+ }
7858+ break;
7859+
77017860 case PCD_DIVMAPARRAY:
77027861 if (STACK(1) == 0)
77037862 {
@@ -7786,6 +7945,19 @@
77867945 }
77877946 break;
77887947
7948+ case PCD_MODSCRIPTARRAY:
7949+ if (STACK(1) == 0)
7950+ {
7951+ state = SCRIPT_ModulusBy0;
7952+ }
7953+ else
7954+ {
7955+ int a = NEXTBYTE, i = STACK(2);
7956+ localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) % STACK(1));
7957+ sp -= 2;
7958+ }
7959+ break;
7960+
77897961 case PCD_MODMAPARRAY:
77907962 if (STACK(1) == 0)
77917963 {
@@ -7847,6 +8019,14 @@
78478019 sp--;
78488020 break;
78498021
8022+ case PCD_ANDSCRIPTARRAY:
8023+ {
8024+ int a = NEXTBYTE, i = STACK(2);
8025+ localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) & STACK(1));
8026+ sp -= 2;
8027+ }
8028+ break;
8029+
78508030 case PCD_ANDMAPARRAY:
78518031 {
78528032 int a = *(activeBehavior->MapVars[NEXTBYTE]);
@@ -7892,6 +8072,14 @@
78928072 sp--;
78938073 break;
78948074
8075+ case PCD_EORSCRIPTARRAY:
8076+ {
8077+ int a = NEXTBYTE, i = STACK(2);
8078+ localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) ^ STACK(1));
8079+ sp -= 2;
8080+ }
8081+ break;
8082+
78958083 case PCD_EORMAPARRAY:
78968084 {
78978085 int a = *(activeBehavior->MapVars[NEXTBYTE]);
@@ -7937,6 +8125,14 @@
79378125 sp--;
79388126 break;
79398127
8128+ case PCD_ORSCRIPTARRAY:
8129+ {
8130+ int a = NEXTBYTE, i = STACK(2);
8131+ localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) | STACK(1));
8132+ sp -= 2;
8133+ }
8134+ break;
8135+
79408136 case PCD_ORMAPARRAY:
79418137 {
79428138 int a = *(activeBehavior->MapVars[NEXTBYTE]);
@@ -7983,6 +8179,14 @@
79838179 sp--;
79848180 break;
79858181
8182+ case PCD_LSSCRIPTARRAY:
8183+ {
8184+ int a = NEXTBYTE, i = STACK(2);
8185+ localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) << STACK(1));
8186+ sp -= 2;
8187+ }
8188+ break;
8189+
79868190 case PCD_LSMAPARRAY:
79878191 {
79888192 int a = *(activeBehavior->MapVars[NEXTBYTE]);
@@ -8028,6 +8232,14 @@
80288232 sp--;
80298233 break;
80308234
8235+ case PCD_RSSCRIPTARRAY:
8236+ {
8237+ int a = NEXTBYTE, i = STACK(2);
8238+ localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) >> STACK(1));
8239+ sp -= 2;
8240+ }
8241+ break;
8242+
80318243 case PCD_RSMAPARRAY:
80328244 {
80338245 int a = *(activeBehavior->MapVars[NEXTBYTE]);
@@ -8070,6 +8282,14 @@
80708282 ++ACS_GlobalVars[NEXTBYTE];
80718283 break;
80728284
8285+ case PCD_INCSCRIPTARRAY:
8286+ {
8287+ int a = NEXTBYTE, i = STACK(1);
8288+ localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) + 1);
8289+ sp--;
8290+ }
8291+ break;
8292+
80738293 case PCD_INCMAPARRAY:
80748294 {
80758295 int a = *(activeBehavior->MapVars[NEXTBYTE]);
@@ -8111,6 +8331,14 @@
81118331 --ACS_GlobalVars[NEXTBYTE];
81128332 break;
81138333
8334+ case PCD_DECSCRIPTARRAY:
8335+ {
8336+ int a = NEXTBYTE, i = STACK(1);
8337+ localarrays->Set(locals, a, i, localarrays->Get(locals, a, i) - 1);
8338+ sp--;
8339+ }
8340+ break;
8341+
81148342 case PCD_DECMAPARRAY:
81158343 {
81168344 int a = *(activeBehavior->MapVars[NEXTBYTE]);
@@ -8537,37 +8765,35 @@
85378765 }
85388766 break;
85398767
8768+ // Print script character array
8769+ case PCD_PRINTSCRIPTCHARARRAY:
8770+ case PCD_PRINTSCRIPTCHRANGE:
8771+ {
8772+ int capacity, offset, a, c;
8773+ if (CharArrayParms(capacity, offset, a, Stack, sp, pcd == PCD_PRINTSCRIPTCHRANGE))
8774+ {
8775+ while (capacity-- && (c = localarrays->Get(locals, a, offset)) != '\0')
8776+ {
8777+ work += (char)c;
8778+ offset++;
8779+ }
8780+ }
8781+ }
8782+ break;
8783+
85408784 // [JB] Print map character array
85418785 case PCD_PRINTMAPCHARARRAY:
85428786 case PCD_PRINTMAPCHRANGE:
85438787 {
8544- int capacity, offset;
8545-
8546- if (pcd == PCD_PRINTMAPCHRANGE)
8547- {
8548- capacity = STACK(1);
8549- offset = STACK(2);
8550- if (capacity < 1 || offset < 0)
8551- {
8552- sp -= 4;
8553- break;
8554- }
8555- sp -= 2;
8556- }
8557- else
8558- {
8559- capacity = 0x7FFFFFFF;
8560- offset = 0;
8561- }
8562-
8563- int a = *(activeBehavior->MapVars[STACK(1)]);
8564- offset += STACK(2);
8565- int c;
8566- while(capacity-- && (c = activeBehavior->GetArrayVal (a, offset)) != '\0') {
8567- work += (char)c;
8568- offset++;
8569- }
8570- sp-= 2;
8788+ int capacity, offset, a, c;
8789+ if (CharArrayParms(capacity, offset, a, Stack, sp, pcd == PCD_PRINTMAPCHRANGE))
8790+ {
8791+ while (capacity-- && (c = activeBehavior->GetArrayVal (a, offset)) != '\0')
8792+ {
8793+ work += (char)c;
8794+ offset++;
8795+ }
8796+ }
85718797 }
85728798 break;
85738799
@@ -8575,32 +8801,15 @@
85758801 case PCD_PRINTWORLDCHARARRAY:
85768802 case PCD_PRINTWORLDCHRANGE:
85778803 {
8578- int capacity, offset;
8579- if (pcd == PCD_PRINTWORLDCHRANGE)
8580- {
8581- capacity = STACK(1);
8582- offset = STACK(2);
8583- if (capacity < 1 || offset < 0)
8584- {
8585- sp -= 4;
8586- break;
8587- }
8588- sp -= 2;
8589- }
8590- else
8591- {
8592- capacity = 0x7FFFFFFF;
8593- offset = 0;
8594- }
8595-
8596- int a = STACK(1);
8597- offset += STACK(2);
8598- int c;
8599- while(capacity-- && (c = ACS_WorldArrays[a][offset]) != '\0') {
8600- work += (char)c;
8601- offset++;
8602- }
8603- sp-= 2;
8804+ int capacity, offset, a, c;
8805+ if (CharArrayParms(capacity, offset, a, Stack, sp, pcd == PCD_PRINTWORLDCHRANGE))
8806+ {
8807+ while (capacity-- && (c = ACS_WorldArrays[a][offset]) != '\0')
8808+ {
8809+ work += (char)c;
8810+ offset++;
8811+ }
8812+ }
86048813 }
86058814 break;
86068815
@@ -8608,32 +8817,15 @@
86088817 case PCD_PRINTGLOBALCHARARRAY:
86098818 case PCD_PRINTGLOBALCHRANGE:
86108819 {
8611- int capacity, offset;
8612- if (pcd == PCD_PRINTGLOBALCHRANGE)
8613- {
8614- capacity = STACK(1);
8615- offset = STACK(2);
8616- if (capacity < 1 || offset < 0)
8617- {
8618- sp -= 4;
8619- break;
8620- }
8621- sp -= 2;
8622- }
8623- else
8624- {
8625- capacity = 0x7FFFFFFF;
8626- offset = 0;
8627- }
8628-
8629- int a = STACK(1);
8630- offset += STACK(2);
8631- int c;
8632- while(capacity-- && (c = ACS_GlobalArrays[a][offset]) != '\0') {
8633- work += (char)c;
8634- offset++;
8635- }
8636- sp-= 2;
8820+ int capacity, offset, a, c;
8821+ if (CharArrayParms(capacity, offset, a, Stack, sp, pcd == PCD_PRINTGLOBALCHRANGE))
8822+ {
8823+ while (capacity-- && (c = ACS_GlobalArrays[a][offset]) != '\0')
8824+ {
8825+ work += (char)c;
8826+ offset++;
8827+ }
8828+ }
86378829 }
86388830 break;
86398831
@@ -10587,6 +10779,7 @@
1058710779 }
1058810780 break;
1058910781
10782+ case PCD_STRCPYTOSCRIPTCHRANGE:
1059010783 case PCD_STRCPYTOMAPCHRANGE:
1059110784 case PCD_STRCPYTOWORLDCHRANGE:
1059210785 case PCD_STRCPYTOGLOBALCHRANGE:
@@ -10617,7 +10810,7 @@
1061710810 break;
1061810811 }
1061910812
10620- for (int i = 0;i < STACK(1); i++)
10813+ for (int i = 0; i < STACK(1); i++)
1062110814 {
1062210815 if (! (*(lookup++)))
1062310816 {
@@ -10628,43 +10821,55 @@
1062810821
1062910822 switch (pcd)
1063010823 {
10631- case PCD_STRCPYTOMAPCHRANGE:
10632- {
10633- int a = STACK(5);
10634- if (a < NUM_MAPVARS && a > 0 &&
10635- activeBehavior->MapVars[a])
10636- {
10637- Stack[sp-6] = activeBehavior->CopyStringToArray(*(activeBehavior->MapVars[a]), index, capacity, lookup);
10638- }
10639- }
10640- break;
10641- case PCD_STRCPYTOWORLDCHRANGE:
10824+ case PCD_STRCPYTOSCRIPTCHRANGE:
10825+ {
10826+ int a = STACK(5);
10827+
10828+ while (capacity-- > 0)
1064210829 {
10643- int a = STACK(5);
10644-
10645- while (capacity-- > 0)
10646- {
10647- ACS_WorldArrays[a][index++] = *lookup;
10648- if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0
10649- }
10650-
10651- Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied
10830+ localarrays->Set(locals, a, index++, *lookup);
10831+ if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0
1065210832 }
10653- break;
10654- case PCD_STRCPYTOGLOBALCHRANGE:
10833+
10834+ Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied
10835+ }
10836+ break;
10837+ case PCD_STRCPYTOMAPCHRANGE:
10838+ {
10839+ int a = STACK(5);
10840+ if (a < NUM_MAPVARS && a > 0 &&
10841+ activeBehavior->MapVars[a])
1065510842 {
10656- int a = STACK(5);
10657-
10658- while (capacity-- > 0)
10659- {
10660- ACS_GlobalArrays[a][index++] = *lookup;
10661- if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0
10662- }
10663-
10664- Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied
10843+ Stack[sp-6] = activeBehavior->CopyStringToArray(*(activeBehavior->MapVars[a]), index, capacity, lookup);
1066510844 }
10666- break;
10667-
10845+ }
10846+ break;
10847+ case PCD_STRCPYTOWORLDCHRANGE:
10848+ {
10849+ int a = STACK(5);
10850+
10851+ while (capacity-- > 0)
10852+ {
10853+ ACS_WorldArrays[a][index++] = *lookup;
10854+ if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0
10855+ }
10856+
10857+ Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied
10858+ }
10859+ break;
10860+ case PCD_STRCPYTOGLOBALCHRANGE:
10861+ {
10862+ int a = STACK(5);
10863+
10864+ while (capacity-- > 0)
10865+ {
10866+ ACS_GlobalArrays[a][index++] = *lookup;
10867+ if (! (*(lookup++))) goto STRCPYTORANGECOMPLETE; // complete with terminating 0
10868+ }
10869+
10870+ Stack[sp-6] = !(*lookup); // true/success if only terminating 0 was not copied
10871+ }
10872+ break;
1066810873 }
1066910874 sp -= 5;
1067010875 }
diff -r aab96d2cda11 -r baea43980f57 src/p_acs.h
--- a/src/p_acs.h Thu Jan 28 12:04:47 2016 +0100
+++ b/src/p_acs.h Sat Jul 26 22:58:47 2014 -0500
@@ -152,6 +152,51 @@
152152 int Index;
153153 };
154154
155+struct ACSLocalArrayInfo
156+{
157+ unsigned int Size;
158+ int Offset;
159+};
160+
161+struct ACSLocalArrays
162+{
163+ unsigned int Count;
164+ ACSLocalArrayInfo *Info;
165+
166+ ACSLocalArrays()
167+ {
168+ Count = 0;
169+ Info = NULL;
170+ }
171+ ~ACSLocalArrays()
172+ {
173+ if (Info != NULL)
174+ {
175+ delete[] Info;
176+ Info = NULL;
177+ }
178+ }
179+
180+ // Bounds-checking Set and Get for local arrays
181+ void Set(int *locals, int arraynum, int arrayentry, int value)
182+ {
183+ if ((unsigned int)arraynum < Count &&
184+ (unsigned int)arrayentry < Info[arraynum].Size)
185+ {
186+ locals[Info[arraynum].Offset + arrayentry] = value;
187+ }
188+ }
189+ int Get(int *locals, int arraynum, int arrayentry)
190+ {
191+ if ((unsigned int)arraynum < Count &&
192+ (unsigned int)arrayentry < Info[arraynum].Size)
193+ {
194+ return locals[Info[arraynum].Offset + arrayentry];
195+ }
196+ return 0;
197+ }
198+};
199+
155200 // The in-memory version
156201 struct ScriptPtr
157202 {
@@ -161,6 +206,7 @@
161206 BYTE ArgCount;
162207 WORD VarCount;
163208 WORD Flags;
209+ ACSLocalArrays LocalArrays;
164210
165211 ACSProfileInfo ProfileData;
166212 };
@@ -197,7 +243,7 @@
197243 WORD Flags;
198244 };
199245
200-struct ScriptFunction
246+struct ScriptFunctionInFile
201247 {
202248 BYTE ArgCount;
203249 BYTE LocalCount;
@@ -206,6 +252,16 @@
206252 DWORD Address;
207253 };
208254
255+struct ScriptFunction
256+{
257+ BYTE ArgCount;
258+ BYTE HasReturnValue;
259+ BYTE ImportNum;
260+ int LocalCount;
261+ DWORD Address;
262+ ACSLocalArrays LocalArrays;
263+};
264+
209265 // Script types
210266 enum
211267 {
@@ -372,7 +428,7 @@
372428 BYTE *Chunks;
373429 ScriptPtr *Scripts;
374430 int NumScripts;
375- BYTE *Functions;
431+ ScriptFunction *Functions;
376432 ACSProfileInfo *FunctionProfileData;
377433 int NumFunctions;
378434 ArrayInfo *ArrayStore;
@@ -781,12 +837,29 @@
781837 PCD_SCRIPTWAITNAMED,
782838 PCD_TRANSLATIONRANGE3,
783839 PCD_GOTOSTACK,
840+ PCD_ASSIGNSCRIPTARRAY,
841+ PCD_PUSHSCRIPTARRAY,
842+ PCD_ADDSCRIPTARRAY,
843+ PCD_SUBSCRIPTARRAY,
844+ PCD_MULSCRIPTARRAY,
845+ PCD_DIVSCRIPTARRAY,
846+/*370*/ PCD_MODSCRIPTARRAY,
847+ PCD_INCSCRIPTARRAY,
848+ PCD_DECSCRIPTARRAY,
849+ PCD_ANDSCRIPTARRAY,
850+ PCD_EORSCRIPTARRAY,
851+ PCD_ORSCRIPTARRAY,
852+ PCD_LSSCRIPTARRAY,
853+ PCD_RSSCRIPTARRAY,
854+ PCD_PRINTSCRIPTCHARARRAY,
855+ PCD_PRINTSCRIPTCHRANGE,
856+/*380*/ PCD_STRCPYTOSCRIPTCHRANGE,
784857
785858 // [BB] We need to fix the number for the new commands!
786859 // [CW] Begin team additions.
787860 PCD_GETTEAMPLAYERCOUNT,
788861 // [CW] End team additions.
789-/*363*/ PCODE_COMMAND_COUNT
862+/*381*/ PCODE_COMMAND_COUNT
790863 };
791864
792865 // Some constants used by ACS scripts
Show on old repository browser