1 //**************************************************************************
2 //**
3 //**	##   ##    ##    ##   ##   ####     ####   ###     ###
4 //**	##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
5 //**	 ## ##  ##    ##  ## ##  ##    ## ##    ## ## ## ## ##
6 //**	 ## ##  ########  ## ##  ##    ## ##    ## ##  ###  ##
7 //**	  ###   ##    ##   ###    ##  ##   ##  ##  ##       ##
8 //**	   #    ##    ##    #      ####     ####   ##       ##
9 //**
10 //**	$Id: vc_object.h 4201 2010-04-03 14:20:46Z dj_jl $
11 //**
12 //**	Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //**	This program is free software; you can redistribute it and/or
15 //**  modify it under the terms of the GNU General Public License
16 //**  as published by the Free Software Foundation; either version 2
17 //**  of the License, or (at your option) any later version.
18 //**
19 //**	This program is distributed in the hope that it will be useful,
20 //**  but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //**  GNU General Public License for more details.
23 //**
24 //**************************************************************************
25 //**
26 //**	Vavoom object base class.
27 //**
28 //**************************************************************************
29 
30 // HEADER FILES ------------------------------------------------------------
31 
32 // MACROS ------------------------------------------------------------------
33 
34 // Define private default constructor.
35 #define NO_DEFAULT_CONSTRUCTOR(cls) \
36 	protected: cls() {} public:
37 
38 // Declare the base VObject class.
39 #define DECLARE_BASE_CLASS(TClass, TSuperClass, TStaticFlags) \
40 public: \
41 	/* Identification */ \
42 	enum {StaticClassFlags = TStaticFlags}; \
43 	private: static VClass PrivateStaticClass; public: \
44 	typedef TSuperClass Super;\
45 	typedef TClass ThisClass;\
46 	static VClass* StaticClass() \
47 		{ return &PrivateStaticClass; }
48 
49 // Declare a concrete class.
50 #define DECLARE_CLASS(TClass, TSuperClass, TStaticFlags) \
51 	DECLARE_BASE_CLASS(TClass, TSuperClass, TStaticFlags) \
52 	virtual ~TClass() \
53 		{ ConditionalDestroy(); } \
54 	friend inline VStream& operator<<(VStream& Strm, TClass*& Obj) \
55 		{ return Strm << *(VObject**)&Obj; } \
56 	static void InternalConstructor() \
57 		{ new TClass(); }
58 
59 // Declare an abstract class.
60 #define DECLARE_ABSTRACT_CLASS(TClass, TSuperClass, TStaticFlags) \
61 	DECLARE_BASE_CLASS(TClass, TSuperClass, TStaticFlags | CLASS_Abstract) \
62 	virtual ~TClass() \
63 		{ ConditionalDestroy(); } \
64 	friend inline VStream& operator<<(VStream& Strm, TClass*& Obj) \
65 		{ return Strm << *(VObject**)&Obj; }
66 
67 // Register a class at startup time.
68 #define IMPLEMENT_CLASS(Pre, TClass) \
69 	VClass Pre##TClass::PrivateStaticClass \
70 	( \
71 		EC_NativeConstructor, \
72 		sizeof(Pre##TClass), \
73 		Pre##TClass::StaticClassFlags, \
74 		Pre##TClass::Super::StaticClass(), \
75 		NAME_##TClass, \
76 		Pre##TClass::InternalConstructor \
77 	); \
78 	VClass* autoclass##Pre##TClass = Pre##TClass::StaticClass();
79 
80 #define DECLARE_FUNCTION(func) \
81 	static FBuiltinInfo funcinfo##func; \
82 	static void exec##func();
83 
84 #define IMPLEMENT_FUNCTION(TClass, Func) \
85 	FBuiltinInfo TClass::funcinfo##Func(#Func, TClass::StaticClass(), \
86 		TClass::exec##Func); \
87 	void TClass::exec##Func()
88 
89 // ENUMERATIONS ------------------------------------------------------------
90 
91 //
92 // Flags describing an object instance.
93 //
94 enum EObjectFlags
95 {
96 	_OF_Destroyed		= 0x00000001,	// Object Destroy has already been called.
97 	_OF_DelayedDestroy	= 0x00000002,
98 	_OF_CleanupRef		= 0x00000004,
99 };
100 
101 // TYPES -------------------------------------------------------------------
102 
103 //==========================================================================
104 //
105 //	VObject
106 //
107 //==========================================================================
108 
109 //
110 // The base class of all objects.
111 //
112 class VObject : public VInterface
113 {
114 	// Declarations.
115 	DECLARE_BASE_CLASS(VObject, VObject, CLASS_Abstract)
116 
117 	// Friends.
118 	friend class FObjectIterator;
119 
120 private:
121 	// Internal per-object variables.
122 	VMethod**				vtable;
123 	vint32					Index;				// Index of object into table.
124 	vuint32					ObjectFlags;		// Private EObjectFlags used by object manager.
125 	VClass*					Class;	  			// Class the object belongs to.
126 
127 	// Private systemwide variables.
128 	static bool				GObjInitialised;
129 	static TArray<VObject*>	GObjObjects;		// List of all objects.
130 	static TArray<int>		GObjAvailable;		// Available object indices.
131 	static VObject*			GObjHash[4096];		// Object hash.
132 	static int				GNumDeleted;
133 	static bool				GInGarbageCollection;
134 	static void*			GNewObject;			// For internal constructors.
135 
136 public:
137 	// Constructors.
138 	VObject();
InternalConstructor()139 	static void InternalConstructor()
140 		{ new VObject(); }
141 
142 	// Destructors.
143 	virtual ~VObject();
144 
145 #ifdef ZONE_DEBUG_NEW
146 #undef new
147 #endif
148 	void* operator new(size_t);
149 	void* operator new(size_t, const char*, int);
150 	void operator delete(void*);
151 	void operator delete(void*, const char*, int);
152 #ifdef ZONE_DEBUG_NEW
153 #define new ZONE_DEBUG_NEW
154 #endif
155 
156 	// VObject interface.
157 	virtual void Register();
158 	virtual void Destroy();
159 	virtual void Serialise(VStream&);
160 	virtual void ClearReferences();
161 	virtual bool ExecuteNetMethod(VMethod*);
162 
163 	// Systemwide functions.
164 	static void StaticInit();
165 	static void StaticExit();
166 	static VObject* StaticSpawnObject(VClass*);
167 	static void CollectGarbage();
168 	static VObject* GetIndexObject(int);
169 	static int GetObjectsCount();
170 
171 	static VStack ExecuteFunction(VMethod*);
172 	static void DumpProfile();
173 
174 	// Functions.
175 	bool ConditionalDestroy();
176 	bool IsA(VClass *SomeBaseClass) const;
177 
178 	// Accessors.
GetClass()179 	VClass* GetClass() const
180 	{
181 		return Class;
182 	}
GetFlags()183 	vuint32 GetFlags() const
184 	{
185 		return ObjectFlags;
186 	}
SetFlags(vuint32 NewFlags)187 	void SetFlags(vuint32 NewFlags)
188 	{
189 		ObjectFlags |= NewFlags;
190 	}
ClearFlags(vuint32 NewFlags)191 	void ClearFlags(vuint32 NewFlags)
192 	{
193 		ObjectFlags &= ~NewFlags;
194 	}
GetIndex()195 	vuint32 GetIndex() const
196 	{
197 		return Index;
198 	}
GetVFunctionIdx(int InIndex)199 	VMethod *GetVFunctionIdx(int InIndex) const
200 	{
201 		return vtable[InIndex];
202 	}
203 	VMethod *GetVFunction(VName FuncName) const;
204 
205 	DECLARE_FUNCTION(Destroy)
206 	DECLARE_FUNCTION(IsA)
207 	DECLARE_FUNCTION(IsDestroyed)
208 
209 	//	Error functions
210 	DECLARE_FUNCTION(Error)
211 	DECLARE_FUNCTION(FatalError)
212 
213 	//	Cvar functions
214 	DECLARE_FUNCTION(CreateCvar)
215 	DECLARE_FUNCTION(GetCvar)
216 	DECLARE_FUNCTION(SetCvar)
217 	DECLARE_FUNCTION(GetCvarF)
218 	DECLARE_FUNCTION(SetCvarF)
219 	DECLARE_FUNCTION(GetCvarS)
220 	DECLARE_FUNCTION(SetCvarS)
221 
222 	//	Math functions
223 	DECLARE_FUNCTION(AngleMod360)
224 	DECLARE_FUNCTION(AngleMod180)
225 	DECLARE_FUNCTION(abs)
226 	DECLARE_FUNCTION(fabs)
227 	DECLARE_FUNCTION(Min)
228 	DECLARE_FUNCTION(FMin)
229 	DECLARE_FUNCTION(Max)
230 	DECLARE_FUNCTION(FMax)
231 	DECLARE_FUNCTION(Clamp)
232 	DECLARE_FUNCTION(FClamp)
233 	DECLARE_FUNCTION(sin)
234 	DECLARE_FUNCTION(cos)
235 	DECLARE_FUNCTION(tan)
236 	DECLARE_FUNCTION(asin)
237 	DECLARE_FUNCTION(acos)
238 	DECLARE_FUNCTION(atan)
239 	DECLARE_FUNCTION(atan2)
240 	DECLARE_FUNCTION(sqrt)
241 	DECLARE_FUNCTION(Normalise)
242 	DECLARE_FUNCTION(Length)
243 	DECLARE_FUNCTION(DotProduct)
244 	DECLARE_FUNCTION(CrossProduct)
245 	DECLARE_FUNCTION(AngleVectors)
246 	DECLARE_FUNCTION(AngleVector)
247 	DECLARE_FUNCTION(VectorAngles)
248 	DECLARE_FUNCTION(GetPlanePointZ)
249 	DECLARE_FUNCTION(PointOnPlaneSide)
250 	DECLARE_FUNCTION(RotateDirectionVector)
251 	DECLARE_FUNCTION(VectorRotateAroundZ)
252 	DECLARE_FUNCTION(RotateVectorAroundVector)
253 
254 	//	String functions
255 	DECLARE_FUNCTION(strlen)
256 	DECLARE_FUNCTION(strcmp)
257 	DECLARE_FUNCTION(stricmp)
258 	DECLARE_FUNCTION(strcat)
259 	DECLARE_FUNCTION(strlwr)
260 	DECLARE_FUNCTION(strupr)
261 	DECLARE_FUNCTION(substr)
262 	DECLARE_FUNCTION(va)
263 	DECLARE_FUNCTION(atoi)
264 	DECLARE_FUNCTION(atof)
265 	DECLARE_FUNCTION(StrStartsWith)
266 	DECLARE_FUNCTION(StrEndsWith)
267 	DECLARE_FUNCTION(StrReplace)
268 
269 	//	Random numbers
270 	DECLARE_FUNCTION(Random)
271 	DECLARE_FUNCTION(P_Random)
272 
273 	//	Textures
274 	DECLARE_FUNCTION(CheckTextureNumForName)
275 	DECLARE_FUNCTION(TextureNumForName)
276 	DECLARE_FUNCTION(CheckFlatNumForName)
277 	DECLARE_FUNCTION(FlatNumForName)
278 	DECLARE_FUNCTION(TextureHeight)
279 	DECLARE_FUNCTION(GetTextureName)
280 
281 	//	Printing in console
282 	DECLARE_FUNCTION(print)
283 	DECLARE_FUNCTION(dprint)
284 
285 	//	Type conversions
286 	DECLARE_FUNCTION(itof)
287 	DECLARE_FUNCTION(ftoi)
288 	DECLARE_FUNCTION(StrToName)
289 
290 	//	Console command functions
291 	DECLARE_FUNCTION(Cmd_CheckParm)
292 	DECLARE_FUNCTION(CmdBuf_AddText)
293 
294 	//	Class methods
295 	DECLARE_FUNCTION(FindClass)
296 	DECLARE_FUNCTION(FindClassLowerCase)
297 	DECLARE_FUNCTION(ClassIsChildOf)
298 	DECLARE_FUNCTION(GetClassName)
299 	DECLARE_FUNCTION(GetClassParent)
300 	DECLARE_FUNCTION(GetClassReplacement)
301 	DECLARE_FUNCTION(GetClassReplacee)
302 	DECLARE_FUNCTION(FindClassState)
303 	DECLARE_FUNCTION(GetClassNumOwnedStates)
304 	DECLARE_FUNCTION(GetClassFirstState)
305 
306 	//	State methods
307 	DECLARE_FUNCTION(StateIsInRange)
308 	DECLARE_FUNCTION(StateIsInSequence)
309 	DECLARE_FUNCTION(GetStateSpriteName)
310 	DECLARE_FUNCTION(GetStateDuration)
311 	DECLARE_FUNCTION(GetStatePlus)
312 	DECLARE_FUNCTION(AreStateSpritesPresent)
313 
314 	//	Iterators
315 	DECLARE_FUNCTION(AllObjects)
316 	DECLARE_FUNCTION(AllClasses)
317 
318 	//	Misc
319 	DECLARE_FUNCTION(Info_ValueForKey)
320 	DECLARE_FUNCTION(WadLumpPresent)
321 	DECLARE_FUNCTION(SpawnObject)
322 	DECLARE_FUNCTION(FindAnimDoor)
323 	DECLARE_FUNCTION(GetLangString)
324 	DECLARE_FUNCTION(RGB)
325 	DECLARE_FUNCTION(RGBA)
326 	DECLARE_FUNCTION(GetLockDef)
327 	DECLARE_FUNCTION(ParseColour)
328 	DECLARE_FUNCTION(TextColourString)
329 	DECLARE_FUNCTION(StartTitleMap)
330 	DECLARE_FUNCTION(LoadBinaryLump)
331 	DECLARE_FUNCTION(IsMapPresent)
332 	DECLARE_FUNCTION(Clock)
333 	DECLARE_FUNCTION(Unclock)
334 
335 #ifdef CLIENT
336 	DECLARE_FUNCTION(P_GetMapName)
337 	DECLARE_FUNCTION(P_GetMapLumpName)
338 	DECLARE_FUNCTION(P_TranslateMap)
339 	DECLARE_FUNCTION(P_GetNumEpisodes)
340 	DECLARE_FUNCTION(P_GetEpisodeDef)
341 	DECLARE_FUNCTION(P_GetNumSkills)
342 	DECLARE_FUNCTION(P_GetSkillDef)
343 	DECLARE_FUNCTION(KeyNameForNum)
344 	DECLARE_FUNCTION(IN_GetBindingKeys)
345 	DECLARE_FUNCTION(IN_SetBinding)
346 	DECLARE_FUNCTION(SV_GetSaveString)
347 	DECLARE_FUNCTION(StartSearch)
348 	DECLARE_FUNCTION(GetSlist)
349 
350 	DECLARE_FUNCTION(LoadTextLump)
351 
352 	//	Graphics
353 	DECLARE_FUNCTION(SetVirtualScreen)
354 	DECLARE_FUNCTION(R_RegisterPic)
355 	DECLARE_FUNCTION(R_RegisterPicPal)
356 	DECLARE_FUNCTION(R_GetPicInfo)
357 	DECLARE_FUNCTION(R_DrawPic)
358 	DECLARE_FUNCTION(R_InstallSprite)
359 	DECLARE_FUNCTION(R_DrawSpritePatch)
360 	DECLARE_FUNCTION(InstallModel)
361 	DECLARE_FUNCTION(R_DrawModelFrame)
362 	DECLARE_FUNCTION(R_FillRect)
363 
364 	//	Client side sound
365 	DECLARE_FUNCTION(LocalSound)
366 	DECLARE_FUNCTION(IsLocalSoundPlaying)
367 	DECLARE_FUNCTION(StopLocalSounds)
368 
369 	DECLARE_FUNCTION(TranslateKey)
370 #endif
371 #ifdef SERVER
372 	//	Map utilites
373 	DECLARE_FUNCTION(LineOpenings)
374 	DECLARE_FUNCTION(P_BoxOnLineSide)
375 	DECLARE_FUNCTION(FindThingGap)
376 	DECLARE_FUNCTION(FindOpening)
377 	DECLARE_FUNCTION(PointInRegion)
378 
379 	//	Sound functions
380 	DECLARE_FUNCTION(SectorStopSound)
381 	DECLARE_FUNCTION(GetSoundPlayingInfo)
382 	DECLARE_FUNCTION(GetSoundID)
383 	DECLARE_FUNCTION(SetSeqTrans)
384 	DECLARE_FUNCTION(GetSeqTrans)
385 	DECLARE_FUNCTION(GetSeqSlot)
386 
387 	DECLARE_FUNCTION(SB_Start)
388 	DECLARE_FUNCTION(TerrainType)
389 	DECLARE_FUNCTION(GetSplashInfo)
390 	DECLARE_FUNCTION(GetTerrainInfo)
391 	DECLARE_FUNCTION(FindClassFromEditorId)
392 	DECLARE_FUNCTION(FindClassFromScriptId)
393 #endif
394 };
395 
396 // Dynamically cast an object type-safely.
Cast(VObject * Src)397 template<class T> T* Cast(VObject* Src)
398 {
399 	return Src && Src->IsA(T::StaticClass()) ? (T*)Src : NULL;
400 }
CastChecked(U * Src)401 template<class T, class U> T* CastChecked(U* Src)
402 {
403 	if (!Src || !Src->IsA(T::StaticClass()))
404 		Sys_Error("Cast to %s failed", T::StaticClass()->GetName());
405 	return (T*)Src;
406 }
407 
408 /*----------------------------------------------------------------------------
409 	Object iterators.
410 ----------------------------------------------------------------------------*/
411 
412 //
413 // Class for iterating through all objects.
414 //
415 class FObjectIterator
416 {
417 public:
418 	FObjectIterator(VClass* InClass = VObject::StaticClass())
Class(InClass)419 	:	Class(InClass), Index(-1)
420 	{
421 		++*this;
422 	}
423 	void operator++()
424 	{
425 		while (++Index < VObject::GObjObjects.Num() &&
426 			(!VObject::GObjObjects[Index] ||
427 				!VObject::GObjObjects[Index]->IsA(Class)));
428 	}
429 	VObject* operator*()
430 	{
431 		return VObject::GObjObjects[Index];
432 	}
433 	VObject* operator->()
434 	{
435 		return VObject::GObjObjects[Index];
436 	}
437 	operator bool()
438 	{
439 		return Index < VObject::GObjObjects.Num();
440 	}
441 protected:
442 	VClass* Class;
443 	int Index;
444 };
445 
446 //
447 // Class for iterating through all objects which inherit from a
448 // specified base class.
449 //
450 template<class T> class TObjectIterator : public FObjectIterator
451 {
452 public:
TObjectIterator()453 	TObjectIterator()
454 	:	FObjectIterator(T::StaticClass())
455 	{}
456 	T* operator*()
457 	{
458 		return (T*)FObjectIterator::operator*();
459 	}
460 	T* operator->()
461 	{
462 		return (T*)FObjectIterator::operator->();
463 	}
464 };
465 
466 //
467 //	Object creation template
468 //
Spawn()469 template<class T> T* Spawn()
470 {
471 	return (T*)VObject::StaticSpawnObject(T::StaticClass());
472 }
473 
GetTypeHash(VObject * Obj)474 inline vuint32 GetTypeHash(VObject* Obj)
475 {
476 	return Obj ? Obj->GetIndex() : 0;
477 }
478 
479 //
480 //	Helper macros for implementing native VavoomC functions and calls to the
481 // VavoomC methods. This will make it simpler to port it to 64 bit platforms.
482 //
483 
484 //
485 //	Macros for passign arguments to VavoomC methods.
486 //
487 #define P_PASS_INT(v)		PR_Push(v)
488 #define P_PASS_BYTE(v)		PR_Push(v)
489 #define P_PASS_FLOAT(v)		PR_Pushf(v)
490 #define P_PASS_BOOL(v)		PR_Push(v)
491 #define P_PASS_NAME(v)		PR_PushName(v)
492 #define P_PASS_STR(v)		PR_PushStr(v)
493 #define P_PASS_VEC(v)		PR_Pushv(v)
494 #define P_PASS_AVEC(v)		PR_Pushav(v)
495 #define P_PASS_REF(v)		PR_PushPtr(v)
496 #define P_PASS_PTR(v)		PR_PushPtr(v)
497 #define P_PASS_SELF			PR_PushPtr(this)
498 
499 //
500 //	Macros for calling VavoomC methods with different return types.
501 //
502 #define EV_RET_VOID(v)		ExecuteFunction(GetVFunction(v))
503 #define EV_RET_INT(v)		return ExecuteFunction(GetVFunction(v)).i
504 #define EV_RET_BYTE(v)		return ExecuteFunction(GetVFunction(v)).i
505 #define EV_RET_FLOAT(v)		return ExecuteFunction(GetVFunction(v)).f
506 #define EV_RET_BOOL(v)		return !!ExecuteFunction(GetVFunction(v)).i
507 #define EV_RET_NAME(v)		vint32 ret = ExecuteFunction(GetVFunction(v)).i; return *(VName*)&ret
508 #define EV_RET_STR(v)		VStack Ret = ExecuteFunction(GetVFunction(v)); PR_PushPtr(Ret.p); return PR_PopStr()
509 #define EV_RET_VEC(v)		Sys_Error("Not implemented")//ExecuteFunction(GetVFunction(v))
510 #define EV_RET_AVEC(v)		Sys_Error("Not implemented")//ExecuteFunction(GetVFunction(v))
511 #define EV_RET_REF(t, v)	return (t*)ExecuteFunction(GetVFunction(v)).p
512 #define EV_RET_PTR(t, v)	return (t*)ExecuteFunction(GetVFunction(v)).p
513 
514 #define EV_RET_VOID_IDX(v)		ExecuteFunction(GetVFunctionIdx(v))
515 #define EV_RET_INT_IDX(v)		return ExecuteFunction(GetVFunctionIdx(v)).i
516 #define EV_RET_BYTE_IDX(v)		return ExecuteFunction(GetVFunctionIdx(v)).i
517 #define EV_RET_FLOAT_IDX(v)		return ExecuteFunction(GetVFunctionIdx(v)).f
518 #define EV_RET_BOOL_IDX(v)		return !!ExecuteFunction(GetVFunctionIdx(v)).i
519 #define EV_RET_NAME_IDX(v)		vint32 ret = ExecuteFunction(GetVFunctionIdx(v)).i; return *(VName*)&ret
520 #define EV_RET_STR_IDX(v)		VStack Ret = ExecuteFunction(GetVFunctionIdx(v)); PR_PushPtr(Ret.p); return PR_PopStr()
521 #define EV_RET_VEC_IDX(v)		Sys_Error("Not implemented")//ExecuteFunction(GetVFunctionIdx(v))
522 #define EV_RET_AVEC_IDX(v)		Sys_Error("Not implemented")//ExecuteFunction(GetVFunctionIdx(v))
523 #define EV_RET_REF_IDX(t, v)	return (t*)ExecuteFunction(GetVFunctionIdx(v)).p
524 #define EV_RET_PTR_IDX(t, v)	return (t*)ExecuteFunction(GetVFunctionIdx(v)).p
525 
526 //
527 //	Parameter get macros. Parameters must be retrieved in backwards order.
528 //
529 #define P_GET_INT(v)		vint32 v = PR_Pop()
530 #define P_GET_BYTE(v)		vuint8 v = PR_Pop()
531 #define P_GET_FLOAT(v)		float v = PR_Popf()
532 #define P_GET_BOOL(v)		bool v = !!PR_Pop()
533 #define P_GET_NAME(v)		VName v = PR_PopName()
534 #define P_GET_STR(v)		VStr v = PR_PopStr()
535 #define P_GET_VEC(v)		TVec v = PR_Popv()
536 #define P_GET_AVEC(v)		TAVec v = PR_Popav()
537 #define P_GET_REF(c, v)		c* v = (c*)PR_PopPtr()
538 #define P_GET_PTR(t, v)		t* v = (t*)PR_PopPtr()
539 #define P_GET_SELF			ThisClass* Self = (ThisClass*)PR_PopPtr()
540 
541 #define P_GET_INT_OPT(v, d)		bool specified_##v = !!PR_Pop(); \
542 	vint32 v = PR_Pop(); if (!specified_##v) v = d
543 #define P_GET_BYTE_OPT(v, d)	bool specified_##v = !!PR_Pop(); \
544 	vuint8 v = PR_Pop(); if (!specified_##v) v = d
545 #define P_GET_FLOAT_OPT(v, d)	bool specified_##v = !!PR_Pop(); \
546 	float v = PR_Popf(); if (!specified_##v) v = d
547 #define P_GET_BOOL_OPT(v, d)	bool specified_##v = !!PR_Pop(); \
548 	bool v = !!PR_Pop(); if (!specified_##v) v = d
549 #define P_GET_NAME_OPT(v, d)	bool specified_##v = !!PR_Pop(); \
550 	VName v = PR_PopName(); if (!specified_##v) v = d
551 #define P_GET_STR_OPT(v, d)		bool specified_##v = !!PR_Pop(); \
552 	VStr v = PR_PopStr(); if (!specified_##v) v = d
553 #define P_GET_VEC_OPT(v, d)		bool specified_##v = !!PR_Pop(); \
554 	TVec v = PR_Popv(); if (!specified_##v) v = d
555 #define P_GET_AVEC_OPT(v, d)	bool specified_##v = !!PR_Pop(); \
556 	TAVec v = PR_Popav(); if (!specified_##v) v = d
557 #define P_GET_REF_OPT(c, v, d)	bool specified_##v = !!PR_Pop(); \
558 	c* v = (c*)PR_PopPtr(); if (!specified_##v) v = d
559 #define P_GET_PTR_OPT(t, v, d)	bool specified_##v = !!PR_Pop(); \
560 	t* v = (t*)PR_PopPtr(); if (!specified_##v) v = d
561 
562 //
563 //	Method return macros.
564 //
565 #define RET_INT(v)			PR_Push(v)
566 #define RET_BYTE(v)			PR_Push(v)
567 #define RET_FLOAT(v)		PR_Pushf(v)
568 #define RET_BOOL(v)			PR_Push(v)
569 #define RET_NAME(v)			PR_PushName(v)
570 #define RET_STR(v)			PR_PushStr(v)
571 #define RET_VEC(v)			PR_Pushv(v)
572 #define RET_AVEC(v)			PR_Pushav(v)
573 #define RET_REF(v)			PR_PushPtr(v)
574 #define RET_PTR(v)			PR_PushPtr(v)
575 
576 //==========================================================================
577 //
578 //	VScriptIterator
579 //
580 //==========================================================================
581 
582 class VScriptIterator : public VInterface
583 {
584 public:
585 	VScriptIterator*	Next;	//	Linked list of active iterators.
586 
587 	virtual bool GetNext() = 0;
588 };
589