Mar 2 2013, 04:01 AM Post #1 | |
Coding like a Rockstar! Posts: 1,468 From: ??? Joined: 28-May 09 | Download Please avoid "wotzit" questions, as the readme (available on the download page) explains just about everything. There are demo scripts provided with the download. SuperVars is heavily used in The Black Market Mod, which is why I'm releasing it now. I've had SuperVars for about a year now, so it's heavily tested, I just kept it to myself for a while... Selfish. And, here is a bonus: https://pastebin.com/46ayUR24 I call this Objective-SCM (difficulty: Brainfuck). Wotzit? It's a relatively low-level objective-oriented implementation for CLEO 4 (though it would only take replacing ALLOCATE_MEMORY to make it CLEO 3-friendly). Once you understand the example scripts given with SuperVars, this isn't too much to handle when using it but concentrate on the low-level source and your eyes may burn a bit. The source is pretty well commented, though. It's not included as part of the SuperVars example scripts as I consider it worthy of a bit more light, however this is a great example of SuperVars' power for this topic (its just best to see the example scripts with the download first). Objective-SCM allows you to create your own virtual 'types' and create C++-like objects with them. For example: CONST CAnimal__SizeOf = 12 CHuman__SizeOf = 4 CDog__SizeOf = 0 CCat__Sizeof = 0 END :CAnimal // type() RET 3 @CAnimal_ctor 0 CAnimal__SizeOf :CHuman // (inherits CAnimal) 0A8E: 0@ = CAnimal__SizeOf + CHumanSizeOf RET 3 @CHuman_ctor 0 0@ :CDog // (inherits CAnimal) 0A8E: 0@ = CAnimal__SizeOf + CDogSizeOf RET 3 @CDog_ctor 0 0@ :CCat // (inherits CAnimal) 0A8E: 0@ = CAnimal__SizeOf + CCatSizeOf RET 3 @CCat_ctor 0 0@ @CCat, for example, can now be passed to @new (just like the C++ new, see the Objective-SCM :new source for more info) which initialises a 12 byte structure, or an array of 12 byte structures: CALL @new @CCat 1 1@ @CCat_ctor is a constructor (0 is the destructor param, use 0 to not use a constructor/destructor), which will be automatically called by @new after allocation, or in the case of an array, will call the constructor for every object in the array after allocation: CONST this = 0@ CAnimal_Type = -1@ CAnimal_NumLegs = -2@ CAnimal_HasTail = -3@ CHuman_NumArms = -4@ ANIMAL_TYPE_UNSPECIFIED = -1 ANIMAL_TYPE_HUMAN = 0 ANIMAL_TYPE_DOG = 1 ANIMAL_TYPE_CAT = 2 SuperVar = string END VAR this: array 4 of SuperVar END :CAnimal_ctor{\__(obj*)__} // Using SuperVars, any variable can be treated more like a real object 0006: this[this] = @CAnimal_VTBL // default VTBL for abstract class 0006: this[CAnimal_Type] = ANIMAL_TYPE_UNSPECIFIED RET 0 :CHuman_ctor{\__(obj*)__} CALL @CAnimal_ctor 1 this 0006: this[CAnimal_Type] = ANIMAL_TYPE_HUMAN 0006: this[CAnimal_NumLegs] = 2 0006: this[CAnimal_HasTail] = FALSE 0006: this[CHuman_NumArms] = 2 RET 0 :CDog_ctor{\__(obj*)__} CALL @CAnimal_ctor 1 this 0006: this[this] = @CDog_VTBL 0006: this[CAnimal_Type] = ANIMAL_TYPE_DOG 0006: this[CAnimal_NumLegs] = 4 0006: this[CAnimal_HasTail] = TRUE RET 0 :CCat_ctor{\__(obj*)__} CALL @CAnimal_ctor 1 this 0006: this[this] = @CCat_VTBL 0006: this[CAnimal_Type] = ANIMAL_TYPE_CAT 0006: this[CAnimal_NumLegs] = 4 0006: this[CAnimal_HasTail] = TRUE RET 0 Here we have a constructor setting the default (initial) values of a 'CDog', 'CCat' or 'CAnimal'. It also sets a 'virtual table', so lets have a look at them... :CAnimal_VTBL HEX @_object_vtbl @CAnimal_GetNumLegs @CAnimal_Speak END :CDog_VTBL HEX @_object_vtbl @CAnimal_GetNumLegs @CDog_Speak END :CCat_VTBL HEX @_object_vtbl @Animal_GetNumLegs @CDog_Speak END Note that the first field of the VTBL must be a pointer to the object base VTBL. Actually, you could also have the first field point to another virtual table, and have that point to the object base VTBL, and so on... :CAnimal_Speak PRINTSTRING "Hello" RET 0 :CCat_Speak PRINTSTRING "Miaow" RET 0 :CDog_Speak PRINTSTRING "Woof" RET 0 :CAnimal_GetNumLegs RET 1 this[CAnimal_NumLegs] So calling GetNumLegs with a cat would return 4, for a dog it would also return 4, but for a human it would return 2. But for 'Speak', different animal classes have to use different methods, as they all speak differently. If we knew our object type was definitely a CDog, we could just do: CALL @CDog_Speak 1 1@ // 1@ was returned from @new However, the idea of a virtual table is that we could also have a different VTBL for a similar object, but we could still call the same method: CONST CAnimal_Speak = -2@ // index of the Speak method for each CAnimal object's VTBL END CALL 1@(CAnimal_Speak,4s) 1@ If 1@ is a CCat, it will print "Miaow", if it's a CDog, it will print "Woof" and the default method is "Hello", which will cover a CHuman and any other CAnimal-based type which is created without it's own unique VTBL. Don't worry, lots of confusion and questions are expected, unless you are both a CLEO and C++ pro, so fire away. Cheerio. Download -------------------- | CLEO 4.3.22 | A?i?a?o?3D | UI SDK | Black Market Mod 1.0.1 | GInput 0.3 | Cheat Keyboard | Tactile Cheat Activation | Stream Ini Extender 0.7 | SuperVars | ScrDebug | Vigilante Justice: San Andreas | |
Mar 2 2013, 01:06 PM Post #2 | |
Trained Member Posts: 76 From: Nederland, NL Joined: 1-May 12 | Is this going to slow the game down a lot? Adding classes to SCM seems to be a bit overkill imo. |
Mar 2 2013, 01:56 PM Post #3 | |
Coding like a Rockstar! Posts: 1,468 From: ??? Joined: 28-May 09 | Is this going to slow the game down a lot? Adding classes to SCM seems to be a bit overkill imo. Only if you add so much CLEO code that the game would become slow anyway. It's just using arrays with a memory address as a base pointer. Besides, Objective-SCM is just a fancy show-off bonus of SuperVars, so it's not really about having classes in CLEO but having the ability to create such epic things with SuperVars, and that's only my imaginations limit so far... Most of the work is done exe-side and uses less memory than the PRINT opcode -------------------- | CLEO 4.3.22 | A?i?a?o?3D | UI SDK | Black Market Mod 1.0.1 | GInput 0.3 | Cheat Keyboard | Tactile Cheat Activation | Stream Ini Extender 0.7 | SuperVars | ScrDebug | Vigilante Justice: San Andreas | |
Oct 13 2013, 12:45 AM Post #4 | |
The New Guy! Posts: 2 Joined: 8-October 13 | |
Oct 14 2013, 12:39 PM Post #5 | |
Coding like a Rockstar! Posts: 1,468 From: ??? Joined: 28-May 09 | -------------------- | CLEO 4.3.22 | A?i?a?o?3D | UI SDK | Black Market Mod 1.0.1 | GInput 0.3 | Cheat Keyboard | Tactile Cheat Activation | Stream Ini Extender 0.7 | SuperVars | ScrDebug | Vigilante Justice: San Andreas | |
Oct 14 2013, 04:01 PM Post #6 | |
Newbie In Training Posts: 16 From: NYC USA Joined: 29-December 09 | If it is posssible, could you give an example of iterating through an array with a for loop using SuperVars? -------------------- Whoa dude! Mr. Turtle is my father. |
Oct 15 2013, 04:21 PM Post #7 | |
Coding like a Rockstar! Posts: 1,468 From: ??? Joined: 28-May 09 | If it is posssible, could you give an example of iterating through an array with a for loop using SuperVars? QUOTE 31@ contains a memory address - the start of your new variable pool. -1@ is the array index. You may notice how it's actually a negative variable index, well all constant indexes for SuperVars should be negative, going up to -32768@. If you were to use 1@ as the index, SuperVars would read the value of 1@ instead use that value as an index. So it's basically just like iterating through a normal array: SET_BIT_L 38@ 8 IF NOT IS_BIT_SET_L 38@ 9 THEN PRINT_HELP_STRING "This script needs SuperVars to run" TERMINATE_THIS_CUSTOM_SCRIPT END 1@ = @MEM 0006: 1@(1@,4s) = 100 // var1 (use SuperVar for 0-index) 0006: 1@(-1@,4s) = 200 // var2 (use negative for 1+ indexes) 0006: 1@(-2@,4s) = 300 // var3 0006: 1@(-3@,4s) = 400 // var4 FOR 0@ = 0 TO 3 PRINTINT2 "var" 1@(0@,4s) // reads the value of 0@ and uses as the index - e.g. 2 == -2@ END { prints: var 100 var 200 var 300 var 400 } TERMINATE_THIS_CUSTOM_SCRIPT :MEM HEX 00 00 00 00 // var1 00 00 00 00 // var2 00 00 00 00 // var3 00 00 00 00 // var4 END You could change the 4s in the array to a different value to change the multiplier (so it would increment by 8 bytes if you used 8s), just remember that most value operations work with 4 byte values regardless. Aside from a few additional supporting features, that's basically the in and out of SuperVars. You assign a memory location to any var and the variable 'becomes' that memory location. All is explained in the readme as well as methods for making it easier to write. -------------------- | CLEO 4.3.22 | A?i?a?o?3D | UI SDK | Black Market Mod 1.0.1 | GInput 0.3 | Cheat Keyboard | Tactile Cheat Activation | Stream Ini Extender 0.7 | SuperVars | ScrDebug | Vigilante Justice: San Andreas | |