Dieses Paket macht viele für Modder interessante Engineklassen in Daedalus verfügbar und bietet grundlegende Funktionalität zum Arbeiten mit Engineobjekten, sowie die Möglichkeit, Engine Funktionen aufzurufen.
Desweiteren sind nebem diesem allgemeinen Rahmenwerk auch einige sehr spezielle und unmittelbar nützliche Funktionen Teil dieses Pakets.
Ich möchte hier zunächst eine kurze, unvollständige Übersicht darüber geben, was mit dem Paket möglich ist. Für eine umfassendere Einschätzung möchte ich auf die Doku verweisen.
Grundfunktionalität
Lesen und schreiben von Integern und Strings an beliebigen Speicherstellen.
aus Speicheradresse (int) einen Objektzeiger (instance) gewinnen
aus einem Objektzeiger (instance) seine Speicheradresse (int) gewinnen
Enginefunktionen aufrufen
Unmittelbar nützlich (nur Beispiele!):
Marvinmodus an und ausschalten
Spiel pausieren
Regen kontrollieren
Truhen oder Türen auf oder abschließen
Menüelemente bearbeiten (zum Beispiel "Speichern"-Menüpunkt deaktivieren)
SpawnManager Konstanten bearbeiten
Informationsbeschaffung:
Das vom Spieler fokussierte Objekt finden
Vobs anhand ihres Namens finden
Position der Kamera ermitteln
Waynet analysieren
herausfinden ob eine Taste gedrückt ist
Kommandozeilenparameter auslesen
Vollständig neue Möglichkeiten:
Gothic.ini lesen und schreiben, .ini Datei der Mod lesen
Daedaluscode zur Laufzeit bearbeiten
Speicher allozieren und freigeben (flüchtig bzgl. Laden und Speichern!)
Sonstiges / "Nice to have":
Suchen von Parsersymbolen anhand ihres Namens
Funktionen anhand ihres Namens oder Symbolindex aufrufen
Im Code Labels initialisieren und zu ihnen springen (für elegantere Schleifen)
Stringfunktionen: Zugriff auf einzelne Zeichen, Länge, Vergleich von Strings, String -> Integer Konvertierung
Nicht für jedes der oben genannte Dinge, gibt es eine für sich stehende vorgefertigte Funktion. Was genau und mit welchen Parametern zur Verfügung steht, ist der Doku zu entnehmen. Grundsätzlich gilt: Dieses Paket ist eher als Türöffner zu verstehen, der das nötige Wissen über den Grundaufbau der Objekte und nur grundlegende Funktionen zur Verfügung stellt. Spezielle Anwendungen müssen selbst daraus abgeleitet werden.
Ich biete zum Beispiel keine Funktionen an, die direkt den Marvin Modus abschaltet. Aber durch dieses Paket ist das Abschalten mit nur zwei Zeilen Code möglich, wenn man weiß wie es geht (in MEM_Game die Eigenschaft game_testmode überschreiben).
Es sind weit mehr als die genannten Dinge möglich. Wenn man sich etwas einarbeitet, kann man mit diesem Paket eine große Menge an neuen Features implementieren. Was dieses Skriptpaket aber ausdrücklich nicht kann, ist Enginefunktionalität zu ersetzen. Als Faustregel gilt: Alle Features, die nur darauf angewiesen sind, Lese- und/oder Schreibzugriff auf die richtigen Daten zu haben oder vorhandene Enginefunktionalität an geeigneter Stelle aufzurufen, sind umsetzbar. Features, die ein vollständig neues Verhalten der Engine benötigen, sind dagegen mit großer Wahrscheinlichkeit nicht umsetzbar.
Es ist aber nicht immer offensichtlich, ob ein konkretes Vorhaben mit Ikarus umgesetzt werden kann oder nicht. Im Zweifelsfall: Fragen! Einschätzungen, ob bestimmte, hier nicht genante Features, möglich sind und wenn ja, welche Klassen, Klasseneigenschaften und Enginefunktionen nützlich sein könnten, können hier im Forum gegeben werden.
Ansonsten hilft das Stöbern in der Dokumentation von Ikarus und den dokumentierten Klassen vielleicht, eine Idee davon zu bekommen, wo man rankommt und wo man vermutlich nicht so einfach rankommt.
Damit die Skripte laufen, muss eine Gothic 2 Reportversion oder Gothic 1 in der Version 1.08k_mod zur Verfügung stehen, auch bei den Spielern! Mit anderen Versionen ist dieses Paket inkompatibel, die Offsets stimmen nicht und Klassen sind möglicherweise verschieden.
Wer sich dafür interessiert mehr aus Gothic herauszuholen wird sich vermutlich auch für G2Ext interessieren. Dieses Projekt soll an dieser Stelle nicht unerwähnt bleiben. Für manche Dinge ist G2Ext sicher besser geeignet als Ikarus. Umgekehrt gibt es auch Dinge, die mit Ikarus bequemer sind. Und es spricht auch nichts dagegen beides auf einmal zu benutzen.
Download inklusive Dokumentation
Ein paar Worte zur Dokumentation vorweg: Wer weiß, was Klassen und Zeiger sind, den wird Abschnitt III langweilen, indem ein paar Grundbegriffe geklärt werden. Abschnitt IV verliert ein paar Worte zu allen Klassen, die in diesem Paket herausgeschrieben sind, Abschnitt V eine Übersicht über die zur Verfügung stehenden Funktionen.
Man beachte auch Abschnitt VII; die Beispiele helfen vielleicht zu verstehen, worum es hier geht.
Download Version 1.2
Leider gibt es noch keine Dokumentation für Version 1.2 und ein Changelog fehlt ebenfalls.
Eine veraltete Version mit Doku und Changelog ist hier verfügbar: Download Version 1.1.4
Ich empfehle dringend Version 1.2 zu verwenden.
Ein paar komplexere Anwendungen sind im folgenden Abschnitt gelistet.
Einige auf Ikarus aufbauende Skripte / Anregungen
Ein Umfangreiches auf Ikarus aufbauenes Paket mit einigen schönen Anwendungen ist LeGo.
Eine kleine Mod in der Ikarus intensiv zum Einsatz kommt und deren Quelltext frei verfügbar ist, ist Irrwichtel
Edit: 23.03.10, 18 Uhr: Neue Version, die IntToString benutzt anstatt mein Kürzel i2s. Edit: 23.03.10, 19:30 Uhr: Fix in STR_GetCharAt. Die Funktion hat nicht funktioniert. Außerdem Umwandlung von Tabs in Leerzeichen (für Leute mit anderer Tabsize). Edit: 02.05.10, 22 Uhr: Diverse Fixes am Code und Verbesserungen an der Dokumentation. Edit: 24.05.10, 17 Uhr:MEM_Realloc und Sprünge ergänzt sowie ein Bugfix und Dokuupdate. Edit: 13.06.10, 23 Uhr:
CallByString und CallByID Funktionalität ergänzt durch Funktionen, die Parameter pushen und Rückgabewerte popen. Beispiel 5 in der Dokumentation beschäftigt sich damit.
Alte CallByString und CallByID Derivate herausgenommen (ich hoffe die hat noch keiner benutzt).
In zCParser.d ein paar genauere Kommentare zu den Parsertokens eingefügt.
oCMag_Book Klasse hinzugefügt in Misc.d
Edit: 20.06.10, 1 Uhr:
zCOption dokumentiert und Zugriffsmöglichkeit auf die .ini Dateien geschaffen.
MEM_ArrayInsert hinzugefügt (Nebenprodukt des .ini Zugriffs)
Möglichkeit die Kommandozeilenparameter auszulesen
entsprechendes Dokuupdate, rewrite dieses Posts
Edit: 25.06.10, 16 Uhr: Konstanten in zCTrigger.d korrigiert. Edit: 27.06.10, 11 Uhr: Die Funktion MEM_KeyState hinzugefügt. Edit: 04.08.10, 17 Uhr:
Reimplementierung des Ikarus Kerns und vieler Funktionen (auf elegantere Weise, dadurch auch kompakter)
Auslagerung aller Konstanten (vorwiegend Adressen) in zugehörige Klassendateien bzw. in eine neue Datei Ikarus_Const.d.
Ikarus.d selbst sollte damit unabhängig von der Gothic-Version sein und um Ikarus Gothic 1 tauglich zu machen müssen nur Ikarus_Const.d und evtl. die Klassendateien angepasst werden.
diverse Bugfixes
Konstanten für virtuelle Tastencodes in großem Umfang hinzugefügt (zu finden in Ikarus_Const.d).
Einige zCArray Funktionen (zum Beispiel um in Dingen wie der activeVobList herumzuschmieren oder als temporärer, skriptinterner Speicher).
Neu: MEM_InsertKeyEvent zum fingieren von Tastendrücken (funktioniert nur begrenzt)
Neu: MEM_CopyBytes / MEM_CopyWords zum Kopieren einer vorgegebenen Datenmenge von einer Quelle zu einem Ziel.
Neu: MEM_SearchAllVobsByName: Baut ein zCArray mit Zeigern auf sämtliche Vobs mit bestimmten Namen und liefert Zeiger auf das zCArray zurück.
Neu: STR_SubStr und STR_Prefix zum Abgreifen von Teilstrings.
Version 1.0, 21.09.10:
Versionsnummer eingeführt.
Teilweise Unterstützung von G1.
Es gibt nun die Funktionen MEM_PtrToInst, MEM_InstToPtr, MEM_GetClassDef, MEM_GetClassName, MEM_ReadStatArr, MEM_WriteStatArr, MEM_InitStatArrs, MEM_InitAll, MEM_TriggerVob, MEM_UntriggerVob, MEM_RenameVob, MEM_ReadByte, MEM_WriteByte.
VORSICHT ÄNDERUNG: MEM_GetMenuByString und MEM_GetMenuItemByString geben nun 0 zurück, wenn sie keinen Erfolg haben anstatt -1.
Einige Ausbesserungen und Ergänzungen in zCMenu.d
Version 1.1, 31.12.10:
"ASM_" Funktionen um Maschinencode zu diktieren und auszuführen.
Darauf aufbauend "CALL_" Funktionen, die es erleichtern Engine Funktionen auszuführen.
MEM_MessageBox und MEM_InfoBox hinzugefügt.
MEM_InsertVob hinzugefügt (danke an Gottfried!).
Konstante GOTHIC_BASE_VERSION eingeführt. Sie ist 1 in Ikarus_Const_G1.d und 2 in Ikarus_Const_G2.d. Dies erleichtert es Code zu schreiben, der auf beiden Plattformen läuft.
Version 1.1.1, 03.01.11:
Die Funktionen LoadLibrary, GetProcAddress und FindKernelDllFunction hinzugefügt.
Die Funktion MemoryProtectionOverride hinzugefügt.
Die Funktion CALL__cdecl hinzugefügt.
Version 1.1.2, 25.06.11:
Die Funktionen STR_Split, STR_SplitCount, STR_GetAddress, MEM_SwapBytes, MEM_SwapWords und MEM_PopInstResult hinzugefügt (siehe Doku).
MEM_CallByString / MEM_CallByID funktionieren nun auch mit Externals.
MEM_NullToInst erwartet nun sinnvollerweise keinen Parameter mehr.
Bitmasken oCNpc.d korrigiert (zum Beispiel die für Kopf und Körpertexturnummern waren fehlerhaft)
Diverses.
Version 1.1.2a, 25.06.11:
Die Funktionen STR_IndexOf, MEM_CompareBytes, MEM_CompareWords hinzugefügt.
Bugfix in der Funktion STR_GetAddressInit.
Version 1.1.3, 16.08.11:
Subtiles Problem in MEM_ArrayInsert gelöst, wenn es auf Engine-Arrays angewendet wird. Dies behebt auch Probleme in MEM_RenameVob, MEM_TriggerVob, MEM_UntriggerVob, MEM_InsertKeyEvent und MEM_SetGothOpt.
Internes Problem bzgl. Gothic 1 und ExitSession (Ikarus konnte nicht geparst werden).
MEM_GetKey und MEM_GetSecondaryKey zum Abfragen von Tastenbelegungen.
MEM_GetFuncID und MEM_Call hinzugefügt (geringe Relevanz, siehe Doku).
Floatpaket dem Download beigelegt.
Version 1.1.4, 12.11.11:
Performanz
Die CALL_ Funktionen sind nun etwa 10 mal so schnell wie zuvor.
MEM_ReadInt und MEM_WriteInt sind etwa dreimal so schnell wie zuvor.
Bugfix: STR_Split. Fehlerhafte Rückgabe, falls zweimal hintereinander der selbe String gesplitet werden soll, aber mit einem abweichenden Separator (vermeintlicher Cache-Hit)
Verbesserung: MEM_Call und MEM_GetFuncID sind nun wesentlich allgemeiner anwendbar.
I have finally decided to use Ikarus. Any way I still don't want to leave gothic sourcer so I've decided to port it to be compatible with Gothic Sourcer.
I note that the most of the error that gothic sourcer report are because of its limited possibilities. Anyway I have found a way to bypass them. For example gothic sourcer doesn't support comparison or operation in the return clause. I bypassed them by using if clauses or stored them into variables before returning.
However, I have previous programming experience (Python) and I have been able to find also many logical/syntactic errors, not depending from GS.
func int MEMINT_PopInt() {};
func string MEMINT_PopString() {};
func int MEMINT_StackPopInt() {};
func string MEMINT_StackPopString() {};
These empty functions raise, rightly, an error. The first two or three aren't used either. Should I comment them or let them return 0 or ""?
Now the thing that drove me crazy. Can you explain me this?
Code:
class MEMINT_HelperClass {};
This is the cause of more than half errors. You assigned many variables to this class but you used those variables themselves in functions that need int!!!
Just to quote one:
Code:
func MEMINT_HelperClass MEM_PtrToInst (var int ptr) {
var MEMINT_HelperClass hlp;
const int hlpOffsetPtr = 0;
if (!hlpOffsetPtr) {
hlpOffsetPtr = MEM_ReadIntArray (currSymbolTableAddress, hlp) + zCParSymbol_offset_offset;
};
It is normal that it raises an error here. You passed as argument a MEMINT_HelperClass when it needs a integer. moreover that class is empty so I can't find why you used it.
For now it is enough. Hope you will answer me soon. Bye
You are right, the functions must look flawed to anyone programming in a decent programming language. However, I would not count Daedalus to the decent programming languages and the functions are just as flawed as Daedalus is in itself.
Ikarus is partly built on what could be called security loopholes in Daedalus and Gothic.
As for func int MEMINT_PopInt() {};. I invite you to do the following experiment:
This will print the number 42. Daedalus Code is compiled into a byte code that is executed on a virtual machine (the zCParser). This virtual machine uses a stack based architecture. It is not ensured that values are properly poped from the stack if they are not needed (which is why the 42 returned by getAnswer is not discarded) and it is also possible to use values that are not guaranteed to be there (this is the case when using the return value of a function that does not return anything).
This (and some counterintuitive handling of instances) allows to put references to data at arbitrary addresses on the stack, allowing access to engine data from within Daedalus.
Stuff like this is also required when calling a function that is only available in a var func variable (see MEM_Call).
For example gothi sourcer doesn't support comparison or operation in the return claus.
Calculations in return clauses are needed to avoid a (rare) problem:
This will Print "4". Reason is that when returning variables, the return value will be a reference to the variable. At the point of the addition, the value of number.i will be added to itself which yields (inevitably) an even number. If returning values instead of variables (e.g. "+i" instead of "i") this problem does not occur.
There are some points in Ikarus where I want to allow that a function is used although a call to this function is either still in progress or has a sofar unused return value still on the stack. One example is the float package, people will write stuff like add(mkf(1), mkf(2)).
Now concerning MEMINT_HelperClass: Daedalus has no type security in return values of any class type (allowing you to assign the return value of Hlp_GetNpc to a C_ITEM for example). I make use of this, for example the function _^ converts a pointer to an (untyped) instance value. I could have used C_NPC or any other class interally, but in order to clarify (mostly for myself) that the code works for arbitrary classes, I used a helper class that is empty.
In case you are familiar with C++ think of MEMINT_HelperClass either as a template class or as something like void. Having a variable of type void is arguably pointless but void* can have its uses.
You assigned many variables to this class but you used those variables themselves in functions that need int!!!
This is standard behaviour. The function B_GiveInvItems expect an integer parameter at the position where the type of the item is expected. Every instance (e.g. ITMI_GOLD) can be implicitly converted to its symbol index (of type integer). The symbol index is a constant number that is used internally to identify the chunk of static information associated with that symbol.
In other words: Instances can be used in two ways. They can indentify particular in-game objects (e.g. the instance self points to a particular Npc) but it can also be used to indentify a function that is statically linked to it (e.g. ITMI_GOLD is connected to a function that initialises an Item (name = "Gold"; value = 1; ...).
This is and has always been reason for confusion not only among modders. I am pretty sure a lot of the content-creators at PiranhaBytes also did not fully understand this (evidence can be found in many scripts).
Mmm, yes in fact from what you told me gothic sourcer could be a problem.
Okay you have parsuaded me. I'll use the spacer to compile. The problem is that it raises me errors that, while I compile the scripts via gothic sourcer, there aren't. More over it doesn't even tell me where this errors are. It just says 'error in line 43 ";" ' or something like this. It never says in which file is the problem.
1) Errors can occur (in particular if you have loaded a .zen file)
2) it does not tell you where the error is
3) it shows you more than the first error - subsequent errors might not even be errors (but appear to be errors to the parser because of an earlier error)
Der DLL-Thread hat mich hieran erinnert, da aber gestern der (dieser) Post verloren ging, diesmal weniger ausführlich:
Als Gottfrieds Sklave habe ich die Funktion Log_GetTopicStatus() gebastelt, weil Gothic diese nicht nativ anbietet (Warum auch immer, ist ja eigentlich sehr nützlich).
Code:
func string zString_zString(var int charPtr) {
const int zString__zString = 4198592; //0x4010C0
CALL_PtrParam(charPtr);
var int strPtr; strPtr = MEM_Alloc(20);
CALL__thiscall(strPtr, zString__zString);
return CALL_RetValAszString();
};
func int LogManager_GetLogManager() {
const int LogManager__GetLogManager =6697840; //0x663370
CALL__cdecl(LogManager__GetLogManager);
return CALL_RetValAsInt();
};
func string std2z(var int ptr) {
return zString_zString(MEM_ReadInt(ptr+4));
};
func int Log_GetTopicStatus(var string name) {
var int logMan; logMan = LogManager_GetLogManager();
var int topic;
var int pos; pos = MEM_StackPos.position;
topic = MEM_ReadInt(logMan);
if (topic) {
// Compare 'name' and (next+4)=std::string=(next+4)+4
if (Str_Compare(name, std2z(topic+4))) {
logMan = MEM_ReadInt(logMan+4);
MEM_StackPos.position = pos;
} else {
return MEM_ReadInt(topic+24);
};
} else {
logMan = MEM_ReadInt(logMan+4);
if (logMan) {
MEM_StackPos.position = pos;
};
};
return -1;
};
Das Script enthält auch zString_zString(char*), das wird ja vermutlich nicht mehr nötig sein, zuminst vermute ich, dass es im nächsten Ikarus-Release enthalten sein - meine Version ist allerdings ein wenig eleganter (und langsamer ) implementiert.
Kann ja vielleicht jemand gebrauchen.
Isn't there already the function Mis_GetStatus? I never saw it used but I know there is.
func void StartRain_Time (var int start_hr, var int start_min, var int end_hr, var int end_min){/* Globale Instanzen initialisieren: */ MEM_InitGlobalInst(); /* Hierrunter fällt auch der Skycontroller *//* Gothic Tage sind um 12 Stunden verschoben, 0 = 12 Uhr, 1 = 12 Uhr des nächtes Tags */ start_hr = (start_hr + 12) % 24; end_hr = (end_hr + 12) % 24; if (start_hr > end_hr){ MEM_Warn ("StartRain_Time: Regen um 12 Uhr mittags ist nicht möglich!"); return; }; /* 24 Stunden auf Bereich 0 bis 1 runterskalieren (float) */ var int start_float; var int end_float; start_float = divf(mkf(start_hr*60 + start_min), mkf(24*60)); end_float = divf(mkf(end_hr *60 + end_min) , mkf(24*60)); /* Ich rechne hier zunächst die Uhrzeit in vergangene Minuten und dann als Anteil eines ganzen Tages aus und addiere anschließend noch den Anteil eines halben Tages (1/2), da die Floats für den Regen zwischen 12:00 Uhr = 0 und 12:00 Uhr am nächsten Tag = 1 liegen *//* Start zur Startzeit*/ MEM_SkyController.rainFX_timeStartRain = start_float; /* Ende zur Endzeit */ MEM_SkyController.rainFX_timeStopRain = end_float; MEM_SkyController.rainFX_renderLightning = TRUE; /* Ergebnis: Regen zur gewünschten Zeit! (es sei denn man ist in einer Zone in der es schneit, dann gibt es Schnee) */};
StartRain_Time (6,37,11,22);
Angemerkt sei noch, dass man eigentlich nicht mehr als einmal am Tag Regen haben kann. Man kann aber natürlich nach dem ersten Regen die Zeit für einen zweiten Regen einstellen. Außerdem wird der Regen ein- und ausgeblendet, diese Übergangszeiten sind prozentual von der Gesamtregenzeit.
Zur Funktionsweise: Die Start- und Endzeiten des Regens sind Floats zwischen 0 und 1. Dabei entspricht 0 12:00 Uhr und 1 12:00 Uhr des nächsten Tages (deswegen wird immer noch 12/24 ("ein halber Tag") hinzuaddiert).
Die Funktion lässt sich natürlich auch flexibel einsetzen, indem man den Regen z.B. zum jetzigen Zeitpunkt oder in drei Stunden starten lässt. Funktionen, um an die momentanen Stunden und Minuten zu kommen, gibt es ja bereits mehrfach im Forum zu finden, unter anderem auch bei meinen Zeitskripten: http://forum.worldofplayers.de/forum...4#post11760314
I didn't understand if this function works only once or it is a sort of daily routine. StartRain_Time(3,0,8,0) let it rains only in that day or every day it will rain from 3 to 8?
Isn't there already the function Mis_GetStatus? I never saw it used but I know there is.
There is not. Thats why there typically are dedicated variables that hold the topic status.
I didn't understand if this function works only once or it is a sort of daily routine. StartRain_Time(3,0,8,0) let it rains only in that day or every day it will rain from 3 to 8?
This should affect the current sky-day only. At 11:59am the rain time for the next sky-day is determined from scratch.
gibt es die möglichkeit, den hero zu "fesseln", also dass der spieler ihn nicht mehr bewegen kann und ich ihn allein durch meine skripte steuern lasse? ich meine da mal was gehört zu haben vor ein paar jahren... (achja und wie ließe man ihn danach wieder frei?)
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
versuchen, aber ich weiß nicht, ob du dann noch Animationen abspielen lassen kannst (Das meinst du doch, oder?). Ansonsten: 'Ne Kamerafahrt sollte das auch können.
The problem is exactly what the error message states: an empty/null pointer. Try to create your items first (ie CreateInvItems(hero, instance)) so you actually have a pointer to work on
Besides: The difference you're calculating is nonsense, it will be zero, because all oCItems share the same zCClassDef (That's basically the whole point of it).
The problem is exactly what the error message states: an empty/null pointer. Try to create your items first (ie CreateInvItems(hero, instance)) so you actually have a pointer to work on
Besides: The difference you're calculating is nonsense, it will be zero, because all oCItems share the same zCClassDef (That's basically the whole point of it).
Well I was just trying, I thought I could have gained some numerical differences between couples of weapons. Moreover I probably misunderstood you. I didn't understand how can I iterate on a class. I saw that there is this
Code:
var int hashTable; //zCObject** //Hashtabelle der Größe 1024. Objekte sind mit zCObject.hashNext verknüpft, falls mehrere auf den selben Wert hashen.
//zCArray<zCObject*> objectList; //alle benannten (!) Objekte von genau (!) dieser Klasse (!) //Ausrufezeichenanmerkungen: 1.) unbenannte sind nicht drin 2.) Objekte von Unterklassen sind nicht drin 3.) diese Eigenschaft kann sehr nützlich sein.
var int objectList_array; //zCObject**
var int objectList_numAlloc; //int
var int objectList_numInArray; //int
linked to an array, but how can I iterate on it? zCClassDef.objectlist?
Also you should be able to iterate through all existing oCItems, there is a hashtable for those in the zCClassDef
I have always iterated on iterable instances (like string, lists, tuples, dictionary, sets) but never on classes. In python for example it hasn't got much sense to do this:
Code:
for token in list:
but this does:
Code:
for token in [1,2,3]:
Now in deadalus these iterable classes don't exist either, so it returns my first perplexity that I probably misunderstood you or I haven't understood how zcclassdef works.
Wäre es möglich zur Laufzeit einen bestimmten Filter aufs Bild zu klatschen bzw. z.b. die Sättigung runterzustellen? Damit dann eine Szene einfach nur noch schwarz-weiß dargestellt wird, ohne die entsprechend zu texturieren.
Wäre es möglich zur Laufzeit einen bestimmten Filter aufs Bild zu klatschen bzw. z.b. die Sättigung runterzustellen? Damit dann eine Szene einfach nur noch schwarz-weiß dargestellt wird, ohne die entsprechend zu texturieren.
Viel Spaß, dich mit dem Render-Code auseinander zu setzen
Frag am besten mal Thunderhawk, der dürfte sich mit dem Gothic Renderer auskennen.
Wäre es möglich zur Laufzeit einen bestimmten Filter aufs Bild zu klatschen bzw. z.b. die Sättigung runterzustellen? Damit dann eine Szene einfach nur noch schwarz-weiß dargestellt wird, ohne die entsprechend zu texturieren.
Es gibt in den VFX die Möglichkeit Screenblenden zu bauen. Dabei gibt es verschieden Rendermodi, z.B. BLEND, ADD und MUL. Mit BLEND macht man die eigentlichen Blenden, mit MUL kannst du zum Beispiel die Farbe mit 0 1 0 multiplizieren und blendest damit den roten und blauen Kanal aus. Du hast dann also grün-weiß statt schwarz-weiß.
Was anderes, was in die Richtung geht kenne ich nicht.
Dem Download von Ikarus 1.2 habe ich nun eine verbesserte Floatbibliothek beigelegt, die auf Ikarus aufbaut. Dadurch werden die Floatrechnungen nicht innerhalb von Daedalus mit Integer Arithmetik emuliert sondern die nativen Floatinstruktionen des Prozessors werden benutzt. Dies macht Floatrechnungen deutlich schneller (etwa Faktor 8) und vermutlich auch genauer.