2 Copyright (C) 1998 BJ Eirich (aka vecna)
\r
3 This program is free software; you can redistribute it and/or
\r
4 modify it under the terms of the GNU General Public License
\r
5 as published by the Free Software Foundation; either version 2
\r
6 of the License, or (at your option) any later version.
\r
7 This program is distributed in the hope that it will be useful,
\r
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
\r
10 See the GNU General Public Lic
\r
11 See the GNU General Public License for more details.
\r
12 You should have received a copy of the GNU General Public License
\r
13 along with this program; if not, write to the Free Software
\r
14 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
17 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
\r
26 #define USERFUNC_MARKER 10000
\r
28 // ================================= Data ====================================
\r
30 char *sysvc, *mapvc, *basevc; // VC pool ptrs
\r
31 char *code; // VC current instruction pointer (IP)
\r
33 int *globalint; // system.vc global int variables
\r
34 int maxint; // maximum allocated # of ints
\r
35 char *stringbuf; // vc string workspace
\r
36 int vcreturn; // return value of last function
\r
37 char *movescriptbuf; // VC EntityMove buffer
\r
38 char vctrack=0; // VC call tracking to verge.log
\r
40 quad *vcstack; // VC stack (seperate from main stack)
\r
41 quad *vcsp; // VC stack pointer [esp]
\r
43 int mapevents; // number of map events in this VC
\r
44 char *mapvctbl[1024]; // map VC offset table
\r
50 // -----------------
\r
56 int numargs, numlocals;
\r
86 // -- local func vars --
\r
97 // ============================== Prototypes =================================
\r
99 void ResolveString(char *buffer);
\r
100 void ExecuteSection();
\r
101 void ExecuteEvent(int i);
\r
102 void ExecuteUserFunc(int i);
\r
104 // ================================= Code ====================================
\r
106 int ProcessOperand(); // Mutually dependant functions suck.
\r
107 int ProcessIfOperand(); // Hell yeah they do, bitch.
\r
108 void HandleExternFunc();
\r
109 void HandleStdLib();
\r
110 void ExecuteBlock();
\r
112 void LoadSystemVC()
\r
117 Log("Initializing VC interpreter");
\r
118 if (!(f=vopen("system.idx"))) err("Could not open system.idx.");
\r
119 vread(&numvars, 4, f);
\r
120 vars=(vardecl *) valloc(numvars*sizeof(vardecl), "LoadSystemVC:vars", OID_VC);
\r
121 vread(vars, numvars*48, f);
\r
122 vread(&numfuncs, 4, f);
\r
123 funcs=(funcdecl *) valloc(numfuncs*sizeof(funcdecl), "LoadSystemVC:funcs", OID_VC);
\r
124 vread(funcs, numfuncs*76, f);
\r
125 vread(&numstr, 4, f);
\r
126 str=(strdecl *) valloc(numstr*sizeof(strdecl), "LoadSystemVC:str", OID_VC);
\r
127 vread(str, numstr*44, f);
\r
130 if (!(f=vopen("system.vcs"))) err("Could not open system.vcs");
\r
132 sysvc=(char *) valloc(i, "LoadSystemVC:sysvc", OID_VC);
\r
133 vread(&numfuncs, 4, f);
\r
134 vread(&maxint, 4, f);
\r
135 vread(&stralloc, 4, f);
\r
137 globalint=(int *) valloc(maxint ? maxint*4 : 4, "globalint", OID_VC);
\r
140 stringbuf=(char *) valloc((stralloc*256),
\r
141 "LoadSystemVC:stringbuf", OID_VC);
\r
145 stringbuf=(char *) valloc(256,
\r
146 "LoadSystemVC:stringbuf (256)", OID_VC);
\r
148 vread(sysvc, i, f);
\r
151 // Initialize VC stack
\r
152 vcstack=(quad *) valloc(6000, "vcstack", OID_VC);
\r
155 movescriptbuf=(char *) valloc(65535, "movescriptbuf", OID_VC);
\r
157 Log("system vclib init: %d funcs, %d ints (%d bytes), %d strings (%d bytes)",
\r
158 numfuncs, numvars, maxint*4, numstr, stralloc*256);
\r
161 void LoadMapVC(VFILE *f)
\r
164 vread(&mapevents, 4, f);
\r
165 vread(mapvctbl, 4*mapevents, f);
\r
166 vread(&codesize, 4, f);
\r
167 mapvc=(char *) valloc(codesize, "mapvc", OID_VC);
\r
168 vread(mapvc, codesize, f);
\r
178 word *ptr=(word *) code;
\r
185 quad *ptr=(quad *) code;
\r
190 void GrabString(char *str)
\r
204 int ReadInt(char category, int loc, int ofs)
\r
208 case op_UVAR: return globalint[loc];
\r
209 case op_UVARRAY: return globalint[loc];
\r
210 case op_HVAR0: switch (loc)
\r
212 case 0: return xwin;
\r
213 case 1: return ywin;
\r
214 case 2: return cameratracking;
\r
215 case 3: return timer_count;
\r
217 case 5: return down;
\r
218 case 6: return left;
\r
219 case 7: return right;
\r
222 case 10: return b3;
\r
223 case 11: return b4;
\r
224 case 12: return sx;
\r
225 case 13: return sy;
\r
226 case 14: return playernum;
\r
227 case 15: return cc;
\r
228 case 16: return tracker;
\r
229 case 17: return mx;
\r
230 case 18: return my;
\r
231 case 19: return mb;
\r
232 case 20: return vctrack;
\r
233 case 21: return width;
\r
234 case 22: return depth;
\r
235 case 23: return mp_volume;
\r
236 case 24: return (int)vsp;
\r
237 case 25: return lastent;
\r
238 case 26: return last_pressed;
\r
240 case op_HVAR1: switch (loc)
\r
242 case 0: return (int) screen[ofs];
\r
243 case 1: return entity[ofs].x;
\r
244 case 2: return entity[ofs].y;
\r
245 case 3: return entity[ofs].tx;
\r
246 case 4: return entity[ofs].ty;
\r
247 case 5: return entity[ofs].facing;
\r
248 case 6: return entity[ofs].moving;
\r
249 case 7: return entity[ofs].specframe;
\r
250 case 8: return entity[ofs].speed;
\r
251 // case 9: return entity[ofs].movecode;
\r
252 case 10: return entidx[ofs];
\r
253 case 11: return key[ofs];
\r
254 case 12: return layer[ofs].hline;
\r
255 case 13: return (int) (*(byte *)ofs);
\r
256 case 14: return (int) (*(word *)ofs);
\r
257 case 15: return (int) (*(quad *)ofs);
\r
258 case 16: return (int) pal[ofs];
\r
259 case 17: return (int) (*(char *)ofs);
\r
260 case 18: return (int) (*(short*)ofs);
\r
261 case 19: return (int) (*(int *)ofs);
\r
263 case op_LVAR: return lvar.nargs[loc];
\r
265 err("VC Execution error: Invalid ReadInt category %d", (int) category);
\r
270 void WriteInt(char category, int loc, int ofs, int value)
\r
274 case op_UVAR: globalint[loc]=value; break;
\r
275 case op_UVARRAY: globalint[loc]=value; break;
\r
276 case op_HVAR0: switch (loc)
\r
278 case 0: xwin=value; return;
\r
279 case 1: ywin=value; return;
\r
280 case 2: cameratracking=value; return;
\r
281 case 3: timer_count=value; return;
\r
282 case 16: tracker=value; return;
\r
283 case 20: vctrack=value; return;
\r
284 case 23: mp_volume=value; return;
\r
285 case 26: last_pressed=value; return;
\r
287 case op_HVAR1: switch (loc)
\r
289 case 0: screen[ofs]=(byte) value; return;
\r
290 case 1: entity[ofs].x=value; return;
\r
291 case 2: entity[ofs].y=value; return;
\r
292 case 3: entity[ofs].tx=value; return;
\r
293 case 4: entity[ofs].ty=value; return;
\r
294 case 5: entity[ofs].facing=value; return;
\r
295 case 6: entity[ofs].moving=value; return;
\r
296 case 7: entity[ofs].specframe=value; return;
\r
297 case 8: entity[ofs].speed=value; return;
\r
298 // case 9: entity[ofs].movecode=value; return;
\r
300 case 11: key[ofs]=value; return;
\r
301 case 12: layer[ofs].hline=value; return;
\r
302 case 13: (*(byte *)ofs)=(byte) value; return;
\r
303 case 14: (*(word *)ofs)=(word) value; return;
\r
304 case 15: (*(quad *)ofs)=(quad) value; return;
\r
305 case 16: pal[ofs]=value; return;
\r
306 case 17: (*(char *)ofs)=(byte) value; return;
\r
307 case 18: (*(short*)ofs)=(word) value; return;
\r
308 case 19: (*(int *)ofs)=(quad) value; return;
\r
310 case op_LVAR: lvar.nargs[loc]=value; return;
\r
312 err("VC Execution error: Invalid WriteInt category %d", (int) category);
\r
316 int ResolveOperand()
\r
322 cr=ProcessOperand(); // Get base number
\r
328 case op_ADD: cr += ProcessOperand(); continue;
\r
329 case op_SUB: cr -= ProcessOperand(); continue;
\r
330 case op_DIV: d=ProcessOperand();
\r
331 if (!d) cr=0; else cr /= d; continue;
\r
332 case op_MULT: cr = cr * ProcessOperand(); continue;
\r
333 case op_MOD: d=ProcessOperand();
\r
334 if (!d) cr=0; else cr %= d; continue;
\r
335 case op_SHL: cr = cr << ProcessOperand(); continue;
\r
336 case op_SHR: cr = cr >> ProcessOperand(); continue;
\r
337 case op_AND: cr = cr & ProcessOperand(); continue;
\r
338 case op_OR: cr = cr | ProcessOperand(); continue;
\r
339 case op_XOR: cr = cr ^ ProcessOperand(); continue;
\r
340 case op_END: break;
\r
347 int ProcessOperand()
\r
356 case op_IMMEDIATE: return GrabD();
\r
357 case op_HVAR0: c=GrabC(); return ReadInt(op_HVAR0, c, 0);
\r
358 case op_HVAR1: c=GrabC(); ofs=ResolveOperand(); return ReadInt(op_HVAR1, c, ofs);
\r
359 case op_UVAR: d=GrabD(); return ReadInt(op_UVAR, d, 0);
\r
360 case op_UVARRAY: d=GrabD(); d+=ResolveOperand(); return ReadInt(op_UVARRAY, d, 0);
\r
361 case op_LVAR: c=GrabC(); return lvar.nargs[c];
\r
362 case op_BFUNC: HandleStdLib();
\r
364 case op_UFUNC: HandleExternFunc();
\r
366 case op_GROUP: return ResolveOperand();
\r
367 default: sprintf(strbuf,"VC Execution error: Invalid operand %d.",op_desc);
\r
368 err(strbuf); break;
\r
373 void HandleStringOperand(char *buffer)
\r
386 case s_IMMEDIATE: GrabString(buffer); break;
\r
387 case s_GLOBAL: w=GrabW();
\r
388 d=(char *) (int) stringbuf + (w*256);
\r
390 if (strlen(buffer)+z+1>250)
\r
391 err("Combined string length exceeds 250 char max.");
\r
392 memcpy(buffer, d, z+1);
\r
394 case s_ARRAY: w=GrabW();
\r
395 w+=ResolveOperand();
\r
396 d=(char *) (int) stringbuf + (w*256);
\r
398 if (strlen(buffer)+z+1>250)
\r
399 err("Combined string length exceeds 250 char max.");
\r
400 memcpy(buffer, d, z+1);
\r
402 case s_NUMSTR: i=ResolveOperand();
\r
403 sprintf(buffer,"%d",i);
\r
405 case s_LEFT: ResolveString(tbuf);
\r
406 i=ResolveOperand();
\r
407 c=i<strlen(tbuf) ? i : strlen(tbuf);
\r
408 if (strlen(buffer)+c+1>250)
\r
409 err("Combined string length exceeds 250 char max.");
\r
410 memcpy(buffer, tbuf, c);
\r
413 case s_RIGHT: ResolveString(tbuf);
\r
414 i=ResolveOperand();
\r
415 c=i<strlen(tbuf) ? i : strlen(tbuf);
\r
416 if (strlen(buffer)+c+1>250)
\r
417 err("Combined string length exceeds 250 char max.");
\r
418 memcpy(buffer, tbuf+strlen(tbuf)-c, c);
\r
421 case s_MID: ResolveString(tbuf);
\r
422 i=ResolveOperand();
\r
423 j=ResolveOperand();
\r
424 i=i<strlen(tbuf) ? i : strlen(tbuf);
\r
425 j=j<strlen(tbuf)-i ? j : strlen(tbuf)-i;
\r
426 if (strlen(buffer)+j+1>250)
\r
427 err("Combined string length exceeds 250 char max.");
\r
428 memcpy(buffer, tbuf+i, j);
\r
431 case s_CHR: if (strlen(buffer)+2>50)
\r
432 err("Combined string length exceeds 250 char max.");
\r
433 buffer[0]=(char) ResolveOperand();
\r
436 case s_LOCAL: c=GrabC();
\r
439 if (strlen(buffer)+z+1>250)
\r
440 err("Combined string length exceeds 250 char max.");
\r
441 memcpy(buffer, d, z+1);
\r
443 default: err("Invalid VC string operand %d", (int) c);
\r
447 void ResolveString(char *buffer)
\r
450 HandleStringOperand(buffer);
\r
457 HandleStringOperand((char *) (int) buffer + strlen(buffer)); break;
\r
458 case s_END: return;
\r
460 err("VC execution error: Unknown string operator %d",(int) c);
\r
465 void vcpush(quad info)
\r
467 if (vcsp>=vcstack+1500) err("VC stack overflow.");
\r
474 if (vcsp==vcstack) err("VC stack underflow.");
\r
483 strlwr((char *) args[1]);
\r
484 for (i=0; i<=numvars; i++)
\r
485 if (!strcmp(vars[i].vname, (char *) args[1])) break;
\r
488 j=vars[i].varstartofs;
\r
489 if (vars[i].arraylen>1)
\r
490 j+=atoi((char *) args[2]);
\r
492 sprintf(strbuf,"%s:%d",vars[i].vname, j);
\r
493 Con_Printf(strbuf);
\r
496 for (i=0; i<=numstr; i++)
\r
497 if (!strcmp(str[i].vname, (char *) args[1])) break;
\r
500 j=(int) stringbuf + (i*256);
\r
501 sprintf(strbuf,"%s:%s",str[i].vname, (char *) j);
\r
502 Con_Printf(strbuf);
\r
505 Con_Printf("No such VC variable.");
\r
512 strlwr((char *) args[1]);
\r
513 for (i=0; i<=numvars; i++)
\r
514 if (!strcmp(vars[i].vname, (char *) args[1])) break;
\r
517 j=vars[i].varstartofs;
\r
518 if (vars[i].arraylen>1)
\r
520 j+=atoi((char *) args[2]);
\r
521 globalint[j]=atoi((char *) args[3]);
\r
523 else globalint[j]=atoi((char *) args[2]);
\r
524 sprintf(strbuf,"%s:%d", vars[i].vname, atoi((char *) args[2]));
\r
525 Con_Printf(strbuf);
\r
528 for (i=0; i<=numstr; i++)
\r
529 if (!strcmp(str[i].vname, (char *) args[1])) break;
\r
532 j=(int) stringbuf + (i*256);
\r
533 memcpy((char *) j, (char *) args[2], strlen((char *) args[2])+1);
\r
534 sprintf(strbuf,"%s:%s", str[i].vname, (char *) args[2]);
\r
535 Con_Printf(strbuf);
\r
538 Con_Printf("No such VC variable.");
\r
541 // ======================= VC Standard Function Library =======================
\r
548 ResolveString(strbuf);
\r
557 ResolveString(str1);
\r
558 i=ResolveOperand();
\r
566 i=ResolveOperand();
\r
567 vcreturn=(int) valloc(i, "vcreturn", OID_TEMP);
\r
569 Log("VC allocating %u bytes, ptr at %u.", i, vcreturn);
\r
571 if (!vcreturn) Message("Warning: VC failed malloc", 750);
\r
578 i=ResolveOperand();
\r
581 Log("VC freeing allocated heap at %u.", i);
\r
589 i=ResolveOperand();
\r
590 j=ResolveOperand();
\r
594 void vc_loadimage()
\r
600 t=VLoadImageBuf(s);
\r
604 void vc_copysprite()
\r
612 a=ResolveOperand();
\r
613 b=ResolveOperand();
\r
614 c=ResolveOperand();
\r
615 d=ResolveOperand();
\r
616 e=(byte *) ResolveOperand();
\r
617 if (!ClipOn && !LucentOn) CopySprite(a,b,c,d,e);
\r
618 if ( ClipOn && !LucentOn) CopySpriteClip(a,b,c,d,e);
\r
619 if (!ClipOn && LucentOn) CopySpriteLucent(a,b,c,d,e);
\r
620 if ( ClipOn && LucentOn) CopySpriteLucentClip(a,b,c,d,e);
\r
623 void vc_tcopysprite()
\r
631 a=ResolveOperand();
\r
632 b=ResolveOperand();
\r
633 c=ResolveOperand();
\r
634 d=ResolveOperand();
\r
635 e=(byte *) ResolveOperand();
\r
636 if (!ClipOn && !LucentOn) TCopySprite(a,b,c,d,e);
\r
637 if ( ClipOn && !LucentOn) TCopySpriteClip(a,b,c,d,e);
\r
638 if (!ClipOn && LucentOn) TCopySpriteLucent(a,b,c,d,e);
\r
639 if ( ClipOn && LucentOn) TCopySpriteLucentClip(a,b,c,d,e);
\r
642 void vc_EntitySpawn()
\r
648 a=ResolveOperand();
\r
649 b=ResolveOperand();
\r
650 ResolveString(chrname);
\r
651 vcreturn=AllocateEntity(a, b, chrname);
\r
654 void vc_SetPlayer()
\r
658 i=ResolveOperand();
\r
659 if (i>=entities) err("SetPlayer(): Entity index out of range");
\r
664 // entity[i].movecode=0;
\r
665 entity[i].moving=0;
\r
673 ResolveString(startmap);
\r
680 ResolveString(vcstr);
\r
681 vcreturn=LoadFont(vcstr);
\r
695 flibuf.data=screen;
\r
696 if (!(f=vopen(s))) err("PlayFLI: Could not open %s.",s);
\r
698 data=(byte *) malloc(i);
\r
699 if (!data) err("Not enough memory to play FLI.");
\r
702 play_memory_fli(data, &flibuf, 0, ShowPage);
\r
707 void vc_PrintString()
\r
712 i=ResolveOperand();
\r
725 if (!(f=vopen(s))) err("LoadRaw(): Could not open file %s",s);
\r
727 t=(char *) valloc(i, "LoadRaw:t", OID_VC);
\r
740 x=ResolveOperand();
\r
741 y=ResolveOperand();
\r
742 layr=ResolveOperand();
\r
743 value=ResolveOperand();
\r
752 case 5: layers[layr][(y*layer[layr].sizex)+x] = (short) value; break;
\r
753 case 6: obstruct[(y*layer[0].sizex)+x] = (byte) value; break;
\r
754 case 7: zone[(y*layer[0].sizex)+x] = (byte) value; break;
\r
755 default: err("SetTile(): Invalid layer value");
\r
759 void vc_ScaleSprite()
\r
761 int x,y,iw,ih,dw,dh,image;
\r
763 x=ResolveOperand();
\r
764 y=ResolveOperand();
\r
765 iw=ResolveOperand();
\r
766 ih=ResolveOperand();
\r
767 dw=ResolveOperand();
\r
768 dh=ResolveOperand();
\r
769 image=ResolveOperand();
\r
770 if (!LucentOn) CopySpriteZoomClip(x,y,iw,ih,dw,dh,(byte *)image);
\r
771 if ( LucentOn) CopySpriteZoomLucentClip(x,y,iw,ih,dw,dh,(byte *)image);
\r
774 void vc_EntityMove()
\r
778 i=ResolveOperand();
\r
779 entity[i].moving=0;
\r
780 entity[i].speedct=0;
\r
782 entity[i].delayct=0;
\r
786 ResolveString((char *) (int) movescriptbuf + (int) (i*256));
\r
787 entity[i].scriptofs=(char *) (int) movescriptbuf + (int) (i*256);
\r
788 entity[i].movecode=4;
\r
795 x=ResolveOperand();
\r
796 y=ResolveOperand();
\r
797 x2=ResolveOperand();
\r
798 c=ResolveOperand();
\r
799 if (!LucentOn) HLineClip(x,y,x2,c);
\r
800 if ( LucentOn) HLineLucentClip(x,y,x2,c);
\r
808 x=ResolveOperand();
\r
809 y=ResolveOperand();
\r
810 y2=ResolveOperand();
\r
811 c=ResolveOperand();
\r
812 if (!LucentOn) VLineClip(x,y,y2,c);
\r
813 if ( LucentOn) VLineLucentClip(x,y,y2,c);
\r
818 int x, y, x2, y2, c;
\r
820 x=ResolveOperand();
\r
821 y=ResolveOperand();
\r
822 x2=ResolveOperand();
\r
823 y2=ResolveOperand();
\r
824 c=ResolveOperand();
\r
825 if (!LucentOn) LineClip(x,y,x2,y2,c);
\r
826 if ( LucentOn) LineLucentClip(x,y,x2,y2,c);
\r
831 int x, y, radius, c;
\r
833 x=ResolveOperand();
\r
834 y=ResolveOperand();
\r
835 radius=ResolveOperand();
\r
836 c=ResolveOperand();
\r
837 if (!LucentOn) CircleClip(x,y,radius,c);
\r
838 if ( LucentOn) CircleLucentClip(x,y,radius,c);
\r
841 void vc_CircleFill()
\r
843 int x, y, radius, c;
\r
845 x=ResolveOperand();
\r
846 y=ResolveOperand();
\r
847 radius=ResolveOperand();
\r
848 c=ResolveOperand();
\r
849 if (!LucentOn) CircleFillClip(x,y,radius,c);
\r
850 if ( LucentOn) CircleFillLucentClip(x,y,radius,c);
\r
855 int x, y, x2, y2, c;
\r
857 x=ResolveOperand();
\r
858 y=ResolveOperand();
\r
859 x2=ResolveOperand();
\r
860 y2=ResolveOperand();
\r
861 c=ResolveOperand();
\r
862 if (!LucentOn) RectClip(x,y,x2,y2,c);
\r
863 if ( LucentOn) RectLucentClip(x,y,x2,y2,c);
\r
868 int x, y, x2, y2, c;
\r
870 x=ResolveOperand();
\r
871 y=ResolveOperand();
\r
872 x2=ResolveOperand();
\r
873 y2=ResolveOperand();
\r
874 c=ResolveOperand();
\r
875 if (!LucentOn) RectFillClip(x,y,x2,y2,c);
\r
876 if ( LucentOn) RectFillLucentClip(x,y,x2,y2,c);
\r
883 ResolveString(str);
\r
884 vcreturn=strlen(str);
\r
889 char str1[256], str2[256];
\r
891 ResolveString(str1);
\r
892 ResolveString(str2);
\r
893 vcreturn=strcmp(str1, str2);
\r
896 void vc_FontWidth()
\r
900 i=ResolveOperand();
\r
906 vcreturn=font[i].width;
\r
909 void vc_FontHeight()
\r
913 i=ResolveOperand();
\r
919 vcreturn=font[i].height;
\r
926 x=ResolveOperand();
\r
927 y=ResolveOperand();
\r
928 c=ResolveOperand();
\r
929 SetPixelClip(x,y,c);
\r
936 x=ResolveOperand();
\r
937 y=ResolveOperand();
\r
938 vcreturn=GetPixelClip(x,y);
\r
941 void vc_EntityOnScreen()
\r
945 i=ResolveOperand();
\r
946 for (j=0; j<cc; j++)
\r
959 x=ResolveOperand();
\r
960 y=ResolveOperand();
\r
961 l=ResolveOperand();
\r
970 case 5: vcreturn=(int) layers[l][(y*layer[l].sizex)+x]; break;
\r
971 case 6: vcreturn=(int) obstruct[(y*layer[0].sizex)+x]; break;
\r
972 case 7: vcreturn=(int) zone[(y*layer[0].sizex)+x]; break;
\r
973 default: err("GetTile(): Invalid layer value");
\r
977 void vc_SetResolution()
\r
981 xres=ResolveOperand();
\r
982 yres=ResolveOperand();
\r
984 vcreturn=InitVideo(xres,yres);
\r
987 void vc_SetRString()
\r
989 ResolveString(rstring);
\r
992 void vc_SetClipRect()
\r
994 cx1=ResolveOperand();
\r
995 cy1=ResolveOperand();
\r
996 cx2=ResolveOperand();
\r
997 cy2=ResolveOperand();
\r
1000 void vc_SetRenderDest()
\r
1002 sx=ResolveOperand();
\r
1003 sy=ResolveOperand();
\r
1004 screen=(byte *) ResolveOperand();
\r
1007 void vc_RestoreRenderSettings()
\r
1018 void vc_PartyMove()
\r
1022 entity[playernum].moving=0;
\r
1023 entity[playernum].speedct=0;
\r
1024 entity[playernum].delayct=0;
\r
1025 entity[playernum].mode=0;
\r
1026 entity[playernum].data1=0;
\r
1028 vcpush(cameratracking);
\r
1030 if (cameratracking==1)
\r
1033 tracker=playernum;
\r
1036 ResolveString((char *) (int) movescriptbuf + (int) (playernum*256));
\r
1037 entity[playernum].scriptofs=(char *) (int) movescriptbuf + (int) (playernum*256);
\r
1038 entity[playernum].movecode=4;
\r
1040 while (entity[playernum].movecode)
\r
1042 while (timer_count)
\r
1044 ProcessEntities();
\r
1051 cameratracking=vcpop();
\r
1052 player=&entity[playernum];
\r
1056 void vc_WrapBlit()
\r
1060 a=ResolveOperand();
\r
1061 b=ResolveOperand();
\r
1062 c=ResolveOperand();
\r
1063 d=ResolveOperand();
\r
1064 e=ResolveOperand();
\r
1065 if (!LucentOn) WrapBlit(a,b,c,d,(byte *) e);
\r
1066 else WrapBlitLucent(a,b,c,d,(byte *) e);
\r
1070 void vc_TWrapBlit()
\r
1074 a=ResolveOperand();
\r
1075 b=ResolveOperand();
\r
1076 c=ResolveOperand();
\r
1077 d=ResolveOperand();
\r
1078 e=ResolveOperand();
\r
1079 if (!LucentOn) WrapBlitMasked(a,b,c,d,(byte *) e);
\r
1080 else WrapBlitLucentMasked(a,b,c,d,(byte *) e);
\r
1083 void vc_SetMousePos()
\r
1087 x=ResolveOperand();
\r
1088 y=ResolveOperand();
\r
1092 void vc_HookRetrace()
\r
1100 case 1: script=ResolveOperand(); break;
\r
1101 case 2: script=GrabD(); break;
\r
1103 if (which==2) script+=USERFUNC_MARKER;
\r
1104 hookretrace=script;
\r
1107 void vc_HookTimer()
\r
1115 case 1: script=ResolveOperand(); break;
\r
1116 case 2: script=GrabD(); break;
\r
1118 if (which==2) script+=USERFUNC_MARKER;
\r
1124 int key, script=0;
\r
1127 key=ResolveOperand();
\r
1132 case 1: script=ResolveOperand(); break;
\r
1133 case 2: script=GrabD(); break;
\r
1135 if (which==2) script+=USERFUNC_MARKER;
\r
1136 bindarray[key]=script;
\r
1139 void vc_PlayMusic()
\r
1141 char songname[256];
\r
1143 ResolveString(songname);
\r
1144 PlayMusic(songname);
\r
1147 void vc_PaletteMorph()
\r
1149 int r,g,b,percent,intensity,i,wr,wg,wb;
\r
1151 r=ResolveOperand(); if (r<0) r=0; if (r>63) r=63;
\r
1152 g=ResolveOperand(); if (g<0) g=0; if (g>63) g=63;
\r
1153 b=ResolveOperand(); if (b<0) b=0; if (b>63) b=63;
\r
1154 percent=100-ResolveOperand();
\r
1155 intensity=ResolveOperand();
\r
1157 for (i=0; i<256; i++)
\r
1163 wr=((wr*percent)+(r*(100-percent)))/100;
\r
1164 wg=((wg*percent)+(g*(100-percent)))/100;
\r
1165 wb=((wb*percent)+(b*(100-percent)))/100;
\r
1167 pal2[(i*3)]=wr*intensity/63;
\r
1168 pal2[(i*3)+1]=wg*intensity/63;
\r
1169 pal2[(i*3)+2]=wb*intensity/63;
\r
1174 void EnforceNoDirectories(char *s)
\r
1179 p=(char *) (int) y + (int) strlen(y);
\r
1180 while (p>y && *p != '/' && *p != '\\')
\r
1182 if (*p == '/' || *p == '\\') p++;
\r
1186 void vc_OpenFile()
\r
1191 ResolveString(fname);
\r
1192 EnforceNoDirectories(fname);
\r
1195 vcreturn=(quad) f;
\r
1197 Log(" --> VC opened file %s, ptr %u", fname, (quad) f);
\r
1200 void vc_CloseFile()
\r
1204 f=(VFILE *) ResolveOperand();
\r
1207 Log(" --> VC closed file at ptr %u", (quad) f);
\r
1210 void vc_QuickRead()
\r
1212 char fname[256], c, *p;
\r
1217 ResolveString(fname);
\r
1218 EnforceNoDirectories(fname);
\r
1228 d=ResolveOperand();
\r
1230 l=ResolveOperand();
\r
1232 if (!(f=vopen(fname))) err("QuickRead() - could not open %s",fname);
\r
1234 p=(char *) (quad) stringbuf + ((w+d)*256);
\r
1235 for (i=0; i<l; i++)
\r
1239 if (*p == 10 || *p == 13) *p=0;
\r
1245 void vc_AddFollower()
\r
1249 i=ResolveOperand();
\r
1250 if (i>=entities) err("AddFollower(): Not a valid entity index. (%d)",i);
\r
1251 follower[(int)numfollowers]=i;
\r
1253 // ResetFollowers();
\r
1256 void vc_FlatPoly()
\r
1258 int a, b, c, d, e, f, g;
\r
1260 a=ResolveOperand();
\r
1261 b=ResolveOperand();
\r
1262 c=ResolveOperand();
\r
1263 d=ResolveOperand();
\r
1264 e=ResolveOperand();
\r
1265 f=ResolveOperand();
\r
1266 g=ResolveOperand();
\r
1267 FlatPoly(a,b,c,d,e,f,g);
\r
1270 void vc_TMapPoly()
\r
1272 int a,b,c,d,e,f,g,h,i,j,k,l,m,n,o;
\r
1274 a=ResolveOperand();
\r
1275 b=ResolveOperand();
\r
1276 c=ResolveOperand();
\r
1277 d=ResolveOperand();
\r
1278 e=ResolveOperand();
\r
1279 f=ResolveOperand();
\r
1280 g=ResolveOperand();
\r
1281 h=ResolveOperand();
\r
1282 i=ResolveOperand();
\r
1283 j=ResolveOperand();
\r
1284 k=ResolveOperand();
\r
1285 l=ResolveOperand();
\r
1286 m=ResolveOperand();
\r
1287 n=ResolveOperand();
\r
1288 o=ResolveOperand();
\r
1289 TMapPoly(a,b,c,d,e,f,g,h,i,j,k,l,m,n,(char *) o);
\r
1292 void vc_CacheSound()
\r
1296 ResolveString(fname);
\r
1297 vcreturn=CacheSound(fname);
\r
1301 void vc_PlaySound()
\r
1305 a=ResolveOperand();
\r
1306 b=ResolveOperand();
\r
1307 c=ResolveOperand();
\r
1308 PlaySound(a, b, c);
\r
1311 void vc_RotScale()
\r
1313 int a, b, c, d, e, f, g;
\r
1315 a=ResolveOperand();
\r
1316 b=ResolveOperand();
\r
1317 c=ResolveOperand();
\r
1318 d=ResolveOperand();
\r
1319 e=ResolveOperand();
\r
1320 f=ResolveOperand();
\r
1321 g=ResolveOperand();
\r
1323 RotScale(a, b, c, d, e*3.14159 / 180, (float) f/1000, (byte *) g);
\r
1329 int xtc, ytc, xofs, yofs;
\r
1331 x=ResolveOperand();
\r
1332 y=ResolveOperand();
\r
1333 sy=ResolveOperand();
\r
1334 l=ResolveOperand();
\r
1341 MapLine(xofs, sy, yofs, (word *) (layers[l]+((ytc*layer[l].sizex)+xtc)));
\r
1344 void vc_TMapLine()
\r
1347 int xtc, ytc, xofs, yofs;
\r
1349 x=ResolveOperand();
\r
1350 y=ResolveOperand();
\r
1351 sy=ResolveOperand();
\r
1352 l=ResolveOperand();
\r
1359 TMapLine(xofs, sy, yofs, (word *) (layers[l]+((ytc*layer[l].sizex)+xtc)));
\r
1370 void vc_TScaleSprite()
\r
1372 int x,y,iw,ih,dw,dh,image;
\r
1374 x=ResolveOperand();
\r
1375 y=ResolveOperand();
\r
1376 iw=ResolveOperand();
\r
1377 ih=ResolveOperand();
\r
1378 dw=ResolveOperand();
\r
1379 dh=ResolveOperand();
\r
1380 image=ResolveOperand();
\r
1381 if (!LucentOn) TCopySpriteZoomClip(x,y,iw,ih,dw,dh,(byte *) image);
\r
1382 if ( LucentOn) TCopySpriteZoomLucentClip(x,y,iw,ih,dw,dh,(byte *) image);
\r
1385 void vc_GrabRegion()
\r
1387 int x1, y1, x2, y2;
\r
1391 x1=ResolveOperand();
\r
1392 y1=ResolveOperand();
\r
1393 x2=ResolveOperand()+1;
\r
1394 y2=ResolveOperand()+1;
\r
1395 ptr=(char *) ResolveOperand();
\r
1397 if (x2>sx-1) x2=sx-1;
\r
1398 if (y2>sy-1) y2=sy-1;
\r
1405 for (j=y1; j<y2; j++)
\r
1406 for (i=x1; i<x2; i++)
\r
1407 ptr[((j-y1)*w)+i]=screen[(j*sx)+i];
\r
1418 void vc_fseekline()
\r
1423 line=ResolveOperand();
\r
1424 f=(VFILE *) ResolveOperand();
\r
1427 line=( line==0 ? 0 : line-1 );
\r
1429 for (i=0; i<line; i++)
\r
1430 vgets(strbuf, 255, f);
\r
1433 void vc_fseekpos()
\r
1438 pos=ResolveOperand();
\r
1439 f=(VFILE *) ResolveOperand();
\r
1449 buffer=(char *) ResolveOperand();
\r
1450 len=ResolveOperand();
\r
1451 f=(VFILE *) ResolveOperand();
\r
1452 vread(buffer, len, f);
\r
1455 void vc_fgetbyte()
\r
1460 f=(VFILE *) ResolveOperand();
\r
1465 void vc_fgetword()
\r
1470 f=(VFILE *) ResolveOperand();
\r
1475 void vc_fgetquad()
\r
1480 f=(VFILE *) ResolveOperand();
\r
1485 void vc_fgetline()
\r
1501 d=ResolveOperand();
\r
1503 f=(VFILE *) ResolveOperand();
\r
1504 p=(char *) (quad) stringbuf + (w*256);
\r
1508 if (*p == 10 || *p == 13) *p=0;
\r
1513 void vc_fgettoken()
\r
1529 d=ResolveOperand();
\r
1531 f=(VFILE *) ResolveOperand();
\r
1532 p=(char *) (quad) stringbuf + (w*256);
\r
1533 vscanf(f, "%s", p);
\r
1536 void vc_fwritestring()
\r
1542 f=(FILE *) ResolveOperand();
\r
1543 fprintf(f,"%s\n",s);
\r
1550 a=ResolveOperand();
\r
1551 b=ResolveOperand();
\r
1552 c=ResolveOperand();
\r
1553 fwrite((char *) a, 1, b, (FILE *) c);
\r
1558 char s1[256], s2[256];
\r
1560 ResolveString(s1);
\r
1561 ResolveString(s2);
\r
1562 EnforceNoDirectories(s1);
\r
1563 EnforceNoDirectories(s2);
\r
1566 Log(" --> VC renamed %s to %s.", s1, s2);
\r
1574 EnforceNoDirectories(s);
\r
1577 Log(" --> VC deleted %s.", s);
\r
1585 EnforceNoDirectories(s);
\r
1586 vcreturn=(int) fopen(s,"wb");
\r
1588 Log(" --> VC opened %s for writing, ptr %u.", s, vcreturn);
\r
1595 f=(FILE *) ResolveOperand();
\r
1598 Log(" --> VC close file opened for writing, ptr %u.", (int) f);
\r
1605 a=ResolveOperand();
\r
1606 b=ResolveOperand();
\r
1607 c=ResolveOperand();
\r
1608 memcpy((char *) a, (char *) b, c);
\r
1615 a=ResolveOperand();
\r
1616 b=ResolveOperand();
\r
1617 c=ResolveOperand();
\r
1618 memset((char *) a, (byte) b, c);
\r
1621 void vc_Silhouette()
\r
1623 int x=ResolveOperand();
\r
1624 int y=ResolveOperand();
\r
1625 int w=ResolveOperand();
\r
1626 int h=ResolveOperand();
\r
1627 byte *img=(byte *) ResolveOperand();
\r
1628 byte c=(byte) ResolveOperand();
\r
1632 LucentOn ? SilhouetteLucentClip(x,y,w,h,c,img)
\r
1633 : SilhouetteClip(x,y,w,h,c,img);
\r
1637 LucentOn ? SilhouetteLucent(x,y,w,h,c,img)
\r
1638 : Silhouette(x,y,w,h,c,img);
\r
1642 void vc_SilhouetteScale()
\r
1644 int x=ResolveOperand();
\r
1645 int y=ResolveOperand();
\r
1646 int sw=ResolveOperand();
\r
1647 int sh=ResolveOperand();
\r
1648 int dw=ResolveOperand();
\r
1649 int dh=ResolveOperand();
\r
1650 byte *img=(byte *) ResolveOperand();
\r
1651 byte c=(byte) ResolveOperand();
\r
1655 LucentOn ? SilhouetteZoomLucentClip(x,y,sw,sh,dw,dh,c,img)
\r
1656 : SilhouetteZoomClip(x,y,sw,sh,dw,dh,c,img);
\r
1660 LucentOn ? SilhouetteZoomLucent(x,y,sw,sh,dw,dh,c,img)
\r
1661 : SilhouetteZoom(x,y,sw,sh,dw,dh,c,img);
\r
1667 int x=ResolveOperand();
\r
1668 int y=ResolveOperand();
\r
1669 int w=ResolveOperand();
\r
1670 int h=ResolveOperand();
\r
1671 byte *img=(byte *)ResolveOperand();
\r
1672 byte c=(byte)ResolveOperand();
\r
1674 ClipOn ? TintClip(x,y,w,h,c,img)
\r
1675 : Tint(x,y,w,h,c,img);
\r
1678 void vc_TintScale()
\r
1680 int x=ResolveOperand();
\r
1681 int y=ResolveOperand();
\r
1682 int sw=ResolveOperand();
\r
1683 int sh=ResolveOperand();
\r
1684 int dw=ResolveOperand();
\r
1685 int dh=ResolveOperand();
\r
1686 byte *img=(byte *) ResolveOperand();
\r
1687 byte c=(byte) ResolveOperand();
\r
1689 ClipOn ? TintZoomClip(x,y,sw,sh,dw,dh,c,img)
\r
1690 : TintZoom(x,y,sw,sh,dw,dh,c,img);
\r
1695 int a,b,c,d,e,f,g;
\r
1697 a=ResolveOperand();
\r
1698 b=ResolveOperand();
\r
1699 c=ResolveOperand();
\r
1700 d=ResolveOperand();
\r
1701 e=ResolveOperand();
\r
1702 f=ResolveOperand();
\r
1703 g=ResolveOperand();
\r
1704 Mosaic(a,b,(byte *) c,d,e,f,g);
\r
1707 void vc_WriteVars()
\r
1711 f=(FILE *) ResolveOperand();
\r
1712 fwrite(globalint, 4, maxint, f);
\r
1713 fwrite(stringbuf, 256, stralloc, f);
\r
1716 void vc_ReadVars()
\r
1720 f=(VFILE *) ResolveOperand();
\r
1721 vread(globalint, 4*maxint, f);
\r
1722 vread(stringbuf, 256*stralloc, f);
\r
1730 vcreturn=(int) s[0];
\r
1733 void vc_NumForScript()
\r
1738 void vc_Filesize()
\r
1745 vcreturn=filesize(f);
\r
1751 VFILE *f=(VFILE *)ResolveOperand();
\r
1752 vcreturn=vtell(f);
\r
1755 void vc_CheckCorrupt()
\r
1757 Log("checking for corruption...");
\r
1758 CheckCorruption();
\r
1761 void HandleStdLib()
\r
1769 case 1: vc_Exit_(); break;
\r
1770 case 2: vc_Message(); break;
\r
1771 case 3: vc_Malloc(); break;
\r
1772 case 4: vc_Free(); break;
\r
1773 case 5: vc_pow(); break;
\r
1774 case 6: vc_loadimage(); break;
\r
1775 case 7: vc_copysprite(); break;
\r
1776 case 8: vc_tcopysprite(); break;
\r
1777 case 9: Render(); break;
\r
1778 case 10: ShowPage(); break;
\r
1779 case 11: vc_EntitySpawn(); break;
\r
1780 case 12: vc_SetPlayer(); break;
\r
1781 case 13: vc_Map(); break;
\r
1782 case 14: vc_LoadFont(); break;
\r
1783 case 15: vc_PlayFLI(); break;
\r
1784 case 16: curx=ResolveOperand(); cury=ResolveOperand(); break;
\r
1785 case 17: vc_PrintString(); break;
\r
1786 case 18: vc_LoadRaw(); break;
\r
1787 case 19: vc_SetTile(); break;
\r
1788 case 20: allowconsole=ResolveOperand(); break;
\r
1789 case 21: vc_ScaleSprite(); break;
\r
1790 case 22: ProcessEntities(); break;
\r
1791 case 23: UpdateControls(); break;
\r
1792 case 24: UnPress(ResolveOperand()); break;
\r
1793 case 25: vc_EntityMove(); break;
\r
1794 case 26: vc_HLine(); break;
\r
1795 case 27: vc_VLine(); break;
\r
1796 case 28: vc_Line(); break;
\r
1797 case 29: vc_Circle(); break;
\r
1798 case 30: vc_CircleFill(); break;
\r
1799 case 31: vc_Rect(); break;
\r
1800 case 32: vc_RectFill(); break;
\r
1801 case 33: vc_strlen(); break;
\r
1802 case 34: vc_strcmp(); break;
\r
1803 case 35: break; //CD_Stop(); break;
\r
1804 case 36: ResolveOperand(); break; //CD_Play(ResolveOperand()); break;
\r
1805 case 37: vc_FontWidth(); break;
\r
1806 case 38: vc_FontHeight(); break;
\r
1807 case 39: vc_SetPixel(); break;
\r
1808 case 40: vc_GetPixel(); break;
\r
1809 case 41: vc_EntityOnScreen(); break;
\r
1810 case 42: vcreturn=0;
\r
1811 if ((x=ResolveOperand()))
\r
1812 vcreturn=rand()%x;
\r
1814 case 43: vc_GetTile(); break;
\r
1815 case 44: vc_HookRetrace(); break;
\r
1816 case 45: vc_HookTimer(); break;
\r
1817 case 46: vc_SetResolution(); break;
\r
1818 case 47: vc_SetRString(); break;
\r
1819 case 48: vc_SetClipRect(); break;
\r
1820 case 49: vc_SetRenderDest(); break;
\r
1821 case 50: vc_RestoreRenderSettings(); break;
\r
1822 case 51: vc_PartyMove(); break;
\r
1823 case 52: vcreturn=sintbl[ResolveOperand()]; break;
\r
1824 case 53: vcreturn=costbl[ResolveOperand()]; break;
\r
1825 case 54: vcreturn=tantbl[ResolveOperand()]; break;
\r
1826 case 55: ReadMouse(); break;
\r
1827 case 56: ClipOn=ResolveOperand(); break;
\r
1828 case 57: LucentOn=ResolveOperand(); break;
\r
1829 case 58: vc_WrapBlit(); break;
\r
1830 case 59: vc_TWrapBlit(); break;
\r
1831 case 60: vc_SetMousePos(); break;
\r
1832 case 61: vc_HookKey(); break;
\r
1833 case 62: vc_PlayMusic(); break;
\r
1834 case 63: StopMusic(); break;
\r
1835 case 64: vc_PaletteMorph(); break;
\r
1836 case 65: vc_OpenFile(); break;
\r
1837 case 66: vc_CloseFile(); break;
\r
1838 case 67: vc_QuickRead(); break;
\r
1839 case 68: vc_AddFollower(); break;
\r
1840 // case 69: vc_KillFollower(); break;
\r
1841 // case 70: vc_KillAllFollowers(); break;
\r
1842 // case 71: ResetFollowers();
\r
1843 case 72: vc_FlatPoly(); break;
\r
1844 case 73: vc_TMapPoly(); break;
\r
1845 case 74: vc_CacheSound(); break;
\r
1846 case 75: FreeAllSounds(); break;
\r
1847 case 76: vc_PlaySound(); break;
\r
1848 case 77: vc_RotScale(); break;
\r
1849 case 78: vc_MapLine(); break;
\r
1850 case 79: vc_TMapLine(); break;
\r
1851 case 80: vc_val(); break;
\r
1852 case 81: vc_TScaleSprite(); break;
\r
1853 case 82: vc_GrabRegion(); break;
\r
1854 case 83: vc_Log(); break;
\r
1855 case 84: vc_fseekline(); break;
\r
1856 case 85: vc_fseekpos(); break;
\r
1857 case 86: vc_fread(); break;
\r
1858 case 87: vc_fgetbyte(); break;
\r
1859 case 88: vc_fgetword(); break;
\r
1860 case 89: vc_fgetquad(); break;
\r
1861 case 90: vc_fgetline(); break;
\r
1862 case 91: vc_fgettoken(); break;
\r
1863 case 92: vc_fwritestring(); break;
\r
1864 case 93: vc_fwrite(); break;
\r
1865 case 94: vc_frename(); break;
\r
1866 case 95: vc_fdelete(); break;
\r
1867 case 96: vc_fwopen(); break;
\r
1868 case 97: vc_fwclose(); break;
\r
1869 case 98: vc_memcpy(); break;
\r
1870 case 99: vc_memset(); break;
\r
1871 case 100: vc_Silhouette(); break;
\r
1872 case 101: vcreturn=(int) InitMosaicTable(); break;
\r
1873 case 102: vc_Mosaic(); break;
\r
1874 case 103: vc_WriteVars(); break;
\r
1875 case 104: vc_ReadVars(); break;
\r
1876 case 105: ExecuteEvent(ResolveOperand()); break;
\r
1877 case 106: vc_Asc(); break;
\r
1878 case 107: ExecuteUserFunc(ResolveOperand()); break;
\r
1879 case 108: vc_NumForScript(); break;
\r
1880 case 109: vc_Filesize(); break;
\r
1881 case 110: vc_FTell(); break;
\r
1882 case 111: vc_CheckCorrupt(); break;
\r
1883 default: err("VC Execution error: Invalid STDLIB index. (%d)",(int) c);
\r
1887 // ========================== VC Interpretation Core ==========================
\r
1893 exec=ProcessIfOperand(); // Get base value;
\r
1900 case i_AND: exec=exec & ProcessIfOperand(); continue;
\r
1901 case i_OR: exec=exec | ProcessIfOperand(); continue;
\r
1902 case i_UNGROUP: break;
\r
1909 int ProcessIfOperand()
\r
1914 eval=ResolveOperand();
\r
1918 case i_ZERO: if (!eval) return 1; else return 0;
\r
1919 case i_NONZERO: if (eval) return 1; else return 0;
\r
1920 case i_EQUALTO: if (eval == ResolveOperand()) return 1; else return 0;
\r
1921 case i_NOTEQUAL: if (eval != ResolveOperand()) return 1; else return 0;
\r
1922 case i_GREATERTHAN: if (eval > ResolveOperand()) return 1; else return 0;
\r
1923 case i_GREATERTHANOREQUAL: if (eval >= ResolveOperand()) return 1; else return 0;
\r
1924 case i_LESSTHAN: if (eval < ResolveOperand()) return 1; else return 0;
\r
1925 case i_LESSTHANOREQUAL: if (eval <= ResolveOperand()) return 1; else return 0;
\r
1926 case i_GROUP: if (ProcessIf()) return 1; else return 0;
\r
1940 d=(char *) GrabD();
\r
1941 code=(char *) (int) basevc + (int) d;
\r
1946 void HandleExternFunc()
\r
1949 //lvars *ob = NULL;
\r
1950 //lvars *save = NULL;
\r
1955 memcpy(&temp, &lvar, sizeof(lvars));
\r
1957 memset(&ob, 0, sizeof(lvars));
\r
1958 //ob = (lvars *)valloc(sizeof(lvars)); //2640); //sizeof(lvars)); //2640);
\r
1959 //MSS_CHECK_POINTER_VALIDITY(ob);
\r
1960 //MSS_SET_BLOCK_LABEL(ob, "ob");
\r
1964 for (j=0; j<funcs[i].numargs; j++)
\r
1966 switch (funcs[i].argtype[j])
\r
1968 case 1: ob.nargs[j] = ResolveOperand(); break;
\r
1969 case 3: ResolveString(ob.s + (k << 8)), k++; break;
\r
1974 memcpy(&lvar, &ob, sizeof(lvars));
\r
1980 vcpush((quad)basevc);
\r
1981 vcpush((quad)code);
\r
1984 code = (char *)(sysvc + funcs[i].syscodeofs);
\r
1988 Log(" --> Entering user func %s, codeofs %d",
\r
1989 funcs[i].fname, funcs[i].syscodeofs);
\r
1993 basevc = (char *)vcpop();
\r
1996 memcpy(&lvar, &temp, sizeof(lvars));
\r
1997 //memcpy(lvar, &temp, sizeof(lvars));
\r
2003 Log(" --> Returned from %s", funcs[i].fname);
\r
2006 // MSS_CHECK_ALL_BLOCKS;
\r
2009 void HandleAssign()
\r
2013 quad location=0, value, ofs=0;
\r
2020 if (c!=a_SET) err("VC execution error: Corrupt string assignment");
\r
2021 location=(quad) stringbuf + (w*256);
\r
2022 ResolveString((char *) location);
\r
2028 w+=ResolveOperand();
\r
2030 if (c!=a_SET) err("VC execution error: Corrupt string assignment");
\r
2031 location=(quad) stringbuf + (w*256);
\r
2032 ResolveString((char *) location);
\r
2039 if (c!=a_SET) err("VC execution error: Corrupt string assignment");
\r
2040 location=(quad) &lvar.s[w*256];
\r
2041 ResolveString((char *) location);
\r
2046 case op_UVAR: location=GrabD(); break;
\r
2047 case op_UVARRAY: location=GrabD(); location+=ResolveOperand(); break;
\r
2048 case op_HVAR0: location=(int) GrabC(); break;
\r
2049 case op_HVAR1: location=(int) GrabC(); ofs=ResolveOperand(); break;
\r
2050 case op_LVAR: location=(int) GrabC(); break;
\r
2051 default: err("VC Execution error: Unknown assignment category.");
\r
2053 value=ReadInt(c, location, ofs);
\r
2057 case a_SET: value=ResolveOperand(); break;
\r
2058 case a_INC: value++; break;
\r
2059 case a_DEC: value--; break;
\r
2060 case a_INCSET: value+=ResolveOperand(); break;
\r
2061 case a_DECSET: value-=ResolveOperand(); break;
\r
2063 err("VC Execution error: Invalid assignment operator %d.", (int) d);
\r
2065 WriteInt(c, location, ofs, value);
\r
2068 void HandleSwitch()
\r
2075 realvalue=ResolveOperand();
\r
2077 while (c!=opRETURN)
\r
2079 compvalue=ResolveOperand();
\r
2080 next=(byte *) GrabD();
\r
2081 if (compvalue!=realvalue)
\r
2083 code=(char *) (int) basevc+(int) next;
\r
2102 case opEXEC_STDLIB: HandleStdLib(); break;
\r
2103 case opEXEC_LOCALFUNC: break;
\r
2104 case opEXEC_EXTERNFUNC: HandleExternFunc(); break;
\r
2105 case opIF: HandleIf(); break;
\r
2106 case opELSE: break;
\r
2107 case opGOTO: code=basevc+GrabD(); break;
\r
2108 case opSWITCH: HandleSwitch(); break;
\r
2109 case opASSIGN: HandleAssign(); break;
\r
2110 case opRETURN: code=(char *) vcpop(); break;
\r
2111 case opSETRETVAL: vcreturn=ResolveOperand(); break;
\r
2113 err("Internal VC execution error. (%d)",(int) code - (int) basevc);
\r
2115 if ((int) code != -1) continue; else break;
\r
2119 void ExecuteBlock()
\r
2129 case opEXEC_STDLIB: HandleStdLib(); break;
\r
2130 case opEXEC_LOCALFUNC: break;
\r
2131 case opEXEC_EXTERNFUNC: HandleExternFunc(); break;
\r
2132 case opIF: HandleIf(); break;
\r
2133 case opELSE: break;
\r
2134 case opGOTO: code=basevc+GrabD(); break;
\r
2135 case opSWITCH: HandleSwitch(); break;
\r
2136 case opASSIGN: HandleAssign(); break;
\r
2137 case opRETURN: code=(char *) vcpop(); break;
\r
2138 case opSETRETVAL: vcreturn=ResolveOperand(); break;
\r
2140 err("Internal VC execution error. (%d)",(int) code - (int) basevc);
\r
2142 if (c != opRETURN) continue; else break;
\r
2146 void ExecuteSection()
\r
2156 case opEXEC_STDLIB: HandleStdLib(); break;
\r
2157 case opEXEC_LOCALFUNC: break;
\r
2158 case opEXEC_EXTERNFUNC: HandleExternFunc(); break;
\r
2159 case opIF: HandleIf(); break;
\r
2160 case opELSE: break;
\r
2161 case opGOTO: code=basevc+GrabD(); break;
\r
2162 case opSWITCH: HandleSwitch(); break;
\r
2163 case opASSIGN: HandleAssign(); break;
\r
2164 case opRETURN: break;
\r
2165 case opSETRETVAL: vcreturn=ResolveOperand(); break;
\r
2167 err("Internal VC execution error. (%d)", (int) code - (int) basevc);
\r
2169 if (c != opRETURN) continue; else break;
\r
2173 void ExecuteEvent(int i)
\r
2176 vcpush((quad) code);
\r
2177 vcpush((quad) basevc);
\r
2178 if (i>mapevents) err("VC event out of bounds (%d)",i);
\r
2180 code=(char *) (int) mapvc + (int) mapvctbl[i];
\r
2183 basevc=(char *) vcpop();
\r
2184 code=(char *) vcpop();
\r
2188 void ExecuteUserFunc(int i)
\r
2194 memcpy(&temp, &lvar, sizeof(lvars));
\r
2196 vcpush((quad) code);
\r
2197 vcpush((quad) basevc);
\r
2200 err("VC event out of bounds");
\r
2203 code = (char *)(sysvc + funcs[i].syscodeofs);
\r
2207 memset(&lvar, 0, sizeof(lvar));
\r
2209 //lvar = (lvars *)valloc(sizeof(lvars)); //2640);
\r
2210 //MSS_SET_BLOCK_LABEL(lvar, "lvar");
\r
2213 basevc = (char *) vcpop();
\r
2214 code = (char *) vcpop();
\r
2220 memcpy(&lvar, &temp, sizeof(lvars));
\r
2223 void HookRetrace()
\r
2225 if (!hookretrace) return;
\r
2226 if (hookretrace<USERFUNC_MARKER) ExecuteEvent(hookretrace);
\r
2227 if (hookretrace>=USERFUNC_MARKER) ExecuteUserFunc(hookretrace-USERFUNC_MARKER);
\r
2232 if (!hooktimer) return;
\r
2233 if (hooktimer<USERFUNC_MARKER) ExecuteEvent(hooktimer);
\r
2234 if (hooktimer>=USERFUNC_MARKER) ExecuteUserFunc(hooktimer-USERFUNC_MARKER);
\r
2237 void HookKey(int script)
\r
2239 if (!script) return;
\r
2240 if (script<USERFUNC_MARKER) ExecuteEvent(script);
\r
2241 if (script>=USERFUNC_MARKER) ExecuteUserFunc(script-USERFUNC_MARKER);
\r