[C/C++|CLEO|SCM|SA|VC|3]Opcodes maken voor gebruik in CLEO scripts
Featured Replies
Recently Browsing 0
- No registered users viewing this page.
A better way to browse. Learn more.
A full-screen app on your home screen with push notifications, badges and more.
Opcodes maken voor gebruik in CLEO scripts
Inhoud
1. Inleiding
2. Benodigdheden
3. Voorbereidingen
4. Informatie omtrent CLEO opcodes
5. Project template maken
6. Cleo specifieke code
7. Een opcode maken
8. Sannybuilder compiler
9. Gebruiken in een CLEO script
10. Testen
11. Tot slot
Inleiding
In deze tutorial ga ik uitleggen hoe je nieuwe opcodes kan maken voor in je CLEO scripts. Deze tutorial is gemaakt omdat er weinig informatie over te vinden is, en kennis moet je delen.Deze tutorial is gericht op mensen met kennis van programmeren en die van GTA modden houden
.
Benodigdheden
Voorbereidingen
Zorg ervoor dat je:
Informatie omtrent CLEO opcodes
CLEO opcodes verschillen van de standaard opcodes die het spel zelf gebruikt. De standaard opcodes van het spel die kan je zowel vanuit SCM scripts en CLEO scripts aanroepen, CLEO opcodes daarentegen kan je enkel aanroepen wanneer je CLEO geïnstalleerd hebt, en deze dus beschikbaar is.CLEO opcodes die roepen een functie aan in een externe bibliotheek, deze externe bibliotheken kan je vinden in je CLEO folder, deze hebben de extensie .CLEO. De .CLEO bestanden zijn in feite gewone dll’s en bevatten de code die uitgevoerd wordt wanneer de desbetreffende opcode in een script aangeroepen wordt.
Project template maken
We gaan nu het project voor de opcode maken, hier komt de code te staan die bij je zelfgemaakte opcode hoort.
New project
Als eerste gaan we Visual Studio opstarten. Hierin gaan we naar: File > new > Project. In het linker deelvenster kies je: Templates > Visual C++ > Win32 Project. Vul onder een naam voor het project en voor de solution in.In deze tutorial hanteer ik de projectnaam: cleo_opcode_tutorial en de soluction naam: cleoOpcodes. Druk op Ok, een venster verschijnt, druk hier op next. Selecteer nu onder Application type: DLL. Onder Additional options vink je het vakje Empty project aan en druk op Finish.
Project properties
Voordat we met het project aan de slag gaan, moeten we eerst enkele zaken instellen. Druk met de rechtermuisknop op het project (dus niet de solution) en selecteer Properties. Ga nu naar onderstaande en pas aan:
We zijn nu klaar met de project properties instellen.
Default files
Voor elk CLEO plugin project wat je maakt zijn er enkele bestanden vereist, ook is het handig is je gewoon elke keer dezelfde structuur gebruikt:
#include "stdafx.h" #include "opcodes.h" BOOL APIENTRY DllMain(HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: return InitOpcodes(); case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }#include "stdafx.h" #include "CLEO.h" BOOL InitOpcodes() { BOOL result = FALSE; return result; }Zoals je misschien al ziet in dllmain.cpp, wordt initOpcodes() in opcodes.cpp aangeroepen wanneer de dll succesvol aan het proces verbonden zit.In de initOpcodes kunnen we nu onze eigen opcode registreren.
CLEO Specifieke code
Voordat we onze eigen opcode kunnen registreren, is het van belang om te weten welke types we moeten gebruiken, en hoe een opcode geregistreerd wordt. Ook zou het reuze handig zijn als we weten hoe je code communiceert met de variabelen in je CLEO script.
Registreren van een opcode
Elke opcode heeft een indentifier. De indentifier voor eigengemaakte cleo opcodes heeft een bereik van 0AF0 t/m 7FFF.Elke opcode die je maakt moet een unieke indentifier hebben. Ook heeft elke opcode een callback nodig, de callback is de functie in de dll die bij je opcode hoort, deze declareren we op de volgende manier:
Nu we een callback hebben kunnen we de opcode indentifier hieraan koppelen, dit doen we met:
Met bovenstaand is je opcode geregistreerd en kan je beginnen met je eigen code te schrijven.
Communiceren met het script
Een belangrijk, en onmisbaar onderdeel is het verkrijgen en verzenden van waardes van variabelen tussen je plugin en een CLEO script. Hiervoor zijn enkele CLEO specifieke functies:
Er is een mogelijkheid om alle variabelen die in huidig opcode gebruikt worden in een keer op te halen, dit kan tot maximaal 32 variabelen.
Overige CLEO functies
CLEO kent naast de register en lees/schrijf functies ook nog enkele andere, deze staan hieronder beschreven.
Een opcode maken
Met alle bovenstaande informatie kunnen we nu beginnen aan het maken van onze eigen opcode.Om het in deze tutorial kort en simpel te houden, zal ik een simpele rekensom doen en deze terugschrijven naar de parameter.Voordat we nu echt de opcode kunnen gaan declareren, moeten we eerst bedenken welke indentifier hij krijgt. Als indentifier kies ik voor de waarde: 0B30.
Opcode declareren en registeren
Wat ikzelf fijn vind om te doen is in opcodes.cpp na de includes de indentifiers van de variabelen neer te zetten:
Onder de opcode indentifiers is het makkelijk om de callback(s) te definiëren.
Nu de indentifiers en callback(s) bekend zijn, is het tijd om deze te registreren.
BOOL InitOpcodes() { BOOL result = FALSE; if (CLEO_RegisterOpcode(OPCODE_TUTORIAL, &Script_Tutorial_opcode)) { result = TRUE; } return result; }Callback implementatie: parameters
Nu de opcode(s) geregistreerd zijn kunnen we in de callback van elke opcode alles doen wat we willen. Zet het volgende onder de functie InitOpcodes():
OpcodeResult WINAPI Script_Tutorial_opcode(CScriptThread* thread) { }Nu moeten we gaan verzinnen wat voor parameters deze opcode heeft, welke parameters zijn om uit te lezen, en welke om naar toe te schrijven, en wat voor type is die parameter?Als voorbeeld ga ik een opcode maken waar je een getal opgeeft, deze wordt vermenigvuldigd met het tweede getal en het resultaat hiervan wordt weggeschreven naar het script. Nu moeten we gaan nadenken over de volgorde hoe we alles in willen gaan lezen.Ik wil dat mijn opcode straks op de volgende manier in een cleo script gebruikt wordt:
Als we bovenstaande nemen dan weten we het resultaat van 0@ pas als we eerst 1@ en 2@ hebben ingelezen, dat is dus ook precies de volgorde hoe we dat gaan doen.Als we wiskundige berekeningen op een variabel willen loslaten, dan is het van belang dat we zeker weten dat de variabel geldig is. Laten we bovenstaande dus gaan implementeren:
OpcodeResult WINAPI Script_Tutorial_opcode(CScriptThread* thread) { BOOL result = FALSE; int varA = 0, varB = 0, varC = 0; //Lees 1e parameter uit switch (CLEO_GetOperandType(thread)) { case globalVar: case localVar: case globalArr: case localArr: case imm8: case imm16: case imm32: varA = CLEO_GetIntOpcodeParam(thread); result = TRUE; break; default: CLEO_SkipOpcodeParams(thread, 1); result = FALSE; } //Lees 2e parameter uit switch (CLEO_GetOperandType(thread)) { case globalVar: case localVar: case globalArr: case localArr: case imm8: case imm16: case imm32: varB = CLEO_GetIntOpcodeParam(thread); result = TRUE; break; default: CLEO_SkipOpcodeParams(thread, 1); result = FALSE; } //Kloppen beide? if (result) { varC = (varA * varB); CLEO_SetIntOpcodeParam(thread, varC); //Schrijf de waarde naar de 3e parameter } else { CLEO_SetIntOpcodeParam(thread, -1); //Schrijf de waarde naar de 3e parameter } return OR_CONTINUE; }Bovenstaande code is inefficiënt (dubbele switch), maar het gaat erom dat het idee duidelijk is.Wanneer je bovenstaande hebt gevolgd, kan je nu je plugin compilen.Wanneer je plugin gecompiled is, moet je deze in de CLEO map van je GTA zetten.
Sannybuilder compiler
De volgorde van op welke manier de parameters ingelezen/geschreven worden wordt bepaald door de compiler van Sannybuilder. De compiler beslist dit aan de hand van de configuratiebestanden.
Navigeer naar de map waar je Sannybuilder geïnstalleerd hebt. In deze map vind je een map: data.In de map data staat voor elke GTA die Sannybuilder ondersteund een map. In mijn geval is het SanAndreas, de map sa dus.De bestanden die aangepast moeten worden zijn:
opcodes.txt
Het bestand opcodes.txt is simpelweg het bestand waarin de opcodes staan zoals je ze in een SCM/CLEO script zou gebruiken. Het formaat van een opcode in dit bestand is:
Ik heb besloten dat mijn opcode er op de volgende manier uit wilt laten zien:
Hier hoeven we enkel nog de indentifier voor te zetten met een dubbelepunt, het volgende komt dus onderaan in opcodes.txt te staan:
SCM.ini
De SCM.ini bestanden zijn de configuratiebestanden waarin de opcodes gedefinieerd staan zoals Sannybuilder ze toepast. Het formaat om een opcode te declareren is:
De parameters kan je gewoon tussen de tekst door zetten op welke plek wat je maar wilt.Waar je wel op moet letten is de index van de parameter, deze bepaald de volgorde van hoe de parameters afgehandeld worden. De index geef je aan met %[index] (natuurlijk zonder de [ ]).Daarnaast moet je ook het type aangeven, deze komt direct achter de index.
De volgende types zijn er:
Open het bestand SASCM.ini, en scrol volledig naar onder.We kunnen bijna hetzelfde erin zetten, als in opcodes.txtAls eerste zetten we dus de indentifier neer: 0B30 (zie bovenstaande code)Zoals ik al aangaf, wil ik dat mijn opcode er op de volgende manier uit komt te zien:
De parameters zijn allemaal integers, deze worden dus vervangen met een type d%.Omdat we willen dat 1@ het eerste uitgelezen wordt, 2@ als tweede en 0@ als derde, moeten we de index hiervan correct aangeven.
In het formaat wat ik aangaf, zou mijn opcode in het SCM.ini bestand er zo uit zien:
Voer bovenstaande uit en sla opcodes.txt en de SCM.ini op. Indien je Sannybuilder had opgestart, moet je deze opnieuw opstarten.
Gebruiken in een CLEO script
Om de opcode te gebruiken in een CLEO script, hoeven we simpelweg enkel een script te maken en de opcode hierin te gebruiken zoals wel met elke andere opcode zouden doen:
{$CLEO .cs} thread 'OPCODE_TUT' :INIT 1@ = 8 2@ = 5 3@ = 0 :OPCODE_TUT wait 50 if 0AB0: key_pressed 0x4F // Toets O then if 0AB0: key_pressed 0x11 // Toets Ctrl then gosub @EXECUTE_NEW_OPCODE end end jump @OPCODE_TUT :EXECUTE_NEW_OPCODE wait 0 0B30: 3@ = tutorial_opcode_1_vermenigvuldig 1@ met 2@ 0ACE: show_formatted_text_box "Opcode resultaat: %d" 3@ wait 1000 return 0A93: end_custom_threadZoals je ziet: wanneer er op de knoppen: CTRL + O gedrukt wordt, springt het script naar label :EXECUTE_NEW_OPCODE, hier staat de gloednieuwe opcode die uitgevoerd wordt.
Testen
En als laatste stap, starten we het spel op en gaan we het testen.
Tot slot
Bovenstaande informatie kan mogelijk enkele fouten bevatten, wanneer je een fout ziet, meld het dan a.u.b. zodat ik het kan aanpassen. Als je opmerkingen of vragen hebt, post ze gewoon
Bijlage: source bestanden
Edited by Crypteq