Beiträge: 113
Themen: 0
Registriert seit: Jan 2009
Bewertung:
3
(13.02.2017, 11:33)llm schrieb: Der Fehler kommt wenn dein Segment > 64k ist
Das dachte ich auch und wunderte mich, warum diese Grenze denn schon überschritten sein soll. Inzwischen hab ich gerafft, dass ja schon für die Variable ds fast das ganze Segment belegt wird. Wenn ich die Deklaration von ds rausnehme, passt natürlich wieder alles.
Beiträge: 7
Themen: 0
Registriert seit: Jul 2011
Bewertung:
1
(14.02.2017, 00:11)gaor schrieb: (13.02.2017, 11:33)llm schrieb: Der Fehler kommt wenn dein Segment > 64k ist
Das dachte ich auch und wunderte mich, warum diese Grenze denn schon überschritten sein soll. Inzwischen hab ich gerafft, dass ja schon für die Variable ds fast das ganze Segment belegt wird. Wenn ich die Deklaration von ds rausnehme, passt natürlich wieder alles.
wie machst du jetzt den Umbau im Detail?
Beiträge: 113
Themen: 0
Registriert seit: Jan 2009
Bewertung:
3
14.02.2017, 12:00
(Dieser Beitrag wurde zuletzt bearbeitet: 14.02.2017, 12:04 von gaor.)
Ich hatte ja oben meine Variablendeklarationen verlinkt: http://pastebin.com/sSgNjd13 Die Deklarationen hat mir ein Python-Script aus den Einträgen in der symbols.h erstellt. Da sind aber noch ca. 270 Deklarationen, die als Datentyp ein struct oder einen Pointer haben. Die müssen jetzt per Hand durchgeschaut werden (die meisten structs werden glücklicherweise wenige Probleme bereiten). Danach werde ich mir überlegen, wie ich überprüfe, dass das mit dem Originaldatensegment übereinstimmt. Hauptproblem ist, zu verstehen, welche Teile des Datensegments von BCC automatisch erstellt werden und woher die Lücken kommen, die in der symbols.h nicht beschrieben sind (die Zeilen mit "// ? ...").
Beiträge: 7
Themen: 0
Registriert seit: Jul 2011
Bewertung:
1
Zitat:Die Deklarationen hat mir ein Python-Script aus den Einträgen in der symbols.h erstellt. Da sind aber noch ca. 270 Deklarationen, die als Datentyp ein struct oder einen Pointer haben.
das ist ja schon mal sehr gut
Zitat:Danach werde ich mir überlegen, wie ich überprüfe, dass das mit dem Originaldatensegment übereinstimmt.
wie ich schon geschrieben habe würde sich da einen umgebender struct nutzen - dann kannst du darauf ein sizeof mit Prüfung machen und das Macro offsetof( http://www.cplusplus.com/reference/cstddef/offsetof/) für die Prüfung der lokalen Anordnung in dem struct
und #pragma pack damit dir nicht BCC,VS,gcc-Alignment-Unterschiede Probleme machen - und da du eh schon ein Python-Script hast ist das ja eine paar Zeilen Spielerei
ob du jetzt nachher g_ds.xyz oder g_xyz schreibst ist auch egal weil ihr eh schnell nach vollständiger Portierung beginnen werde aufzuräumen und strukturieren
auch die Inhaltsüberprüfung - wenn du auch komplett auf eigenen Initialisierungscode gehst - kannst du dann leicht mit
einem einzigen memcmp machen
ich würde aus deinem Script automatisch auch Füllbytes oder Unbekannt-Felder aus Bytes generieren - dann kannst du dich auf das Bekannte konzentrieren und machst keine Fehler
Beiträge: 113
Themen: 0
Registriert seit: Jan 2009
Bewertung:
3
15.02.2017, 00:25
(Dieser Beitrag wurde zuletzt bearbeitet: 15.02.2017, 00:27 von gaor.)
Es gibt jetzt eine vollständige Deklaration des Original-Datensegments: https://gist.github.com/tuxor1337/08cdaf...c95d466c18
Diese Deklarationen enthalten aber noch unzählige implizite struct-Datentypen. Außerdem sind Pointer entweder als void-Pointer oder als long-Werte deklariert. Aber von den Byte-Werten her müssten diese Deklarationen letztlich das Original-Datensegment rekonstruieren.
Als nächstes wäre dann wohl das fällig, was llm vorschlägt: Ein struct erzeugen, dass all die globalen Variablen als Felder enthält und die gleiche Größe hat wie das aktuelle Array "ds". Dann macht man einen Check, dass das Datensegment jetzt wirklich mit dem Original übereinstimmt und schließlich castet man die Variable "ds" auf dieses struct und arbeitet damit.
Jemand Lust, das mal zu machen?
Beiträge: 7
Themen: 0
Registriert seit: Jul 2011
Bewertung:
1
Zitat:Jemand Lust, das mal zu machen?
dein Python-Script macht doch schon fast alles
dann musst du ja nur noch die Byte-Addresse jeweils mitführen und kannst damit dann den Startoffset mit Füllbytes exakt auf deine ds:0x.... Angabe legen, die offsetof-Asserts generieren und falls die Daten homogen genug sind sogar daraus die Initalisierungsroutine generieren - würde ich so mache - weniger Fehler und man kann wegen der Prüfungen dann trotzdem noch Hand anlegen
kennst du auch die Größe der jeweiligen Variable? oder lässt sich diese aus der Variablendeklaration ermitteln?
Poste doch mal dein Script
Beiträge: 12.931
Themen: 169
Registriert seit: Jul 2008
Bewertung:
37
Seid ihr sicher, dass ihr damit keine neue Abhängigkeit vom BCC einbaut? Wie kommt man denn vom gecasteten struct zu "ganz normalen" vom Compiler allozierten Variablen auf dem Heap?
Beiträge: 7
Themen: 0
Registriert seit: Jul 2011
Bewertung:
1
(15.02.2017, 08:54)Rabenaas schrieb: Seid ihr sicher, dass ihr damit keine neue Abhängigkeit vom BCC einbaut? Wie kommt man denn vom gecasteten struct zu "ganz normalen" vom Compiler allozierten Variablen auf dem Heap?
ich habe keine Ahnung was du meinst - kannst du die Frage umformulieren?
Code: ...keine neue Abhängigkeit vom BCC einbaut?
wie soll man deswegen eine BCC abhaengigkeit reinbekommen?
das gleiche macht jeder anderen C Kompiler genauso - oder meinst du das offsetof Macro und #pragma - die kann man unter #defines verstecken (weil ja auch nur zur Validierung gebraucht) damit es auf allen Platformen kompiliert - nach der vollständigen Portierung ist das alles sowieso egal und der Code kann komplett umgebaut werden - es geht nur darum so lange wie nötig exakt gleich zu sein - bis alles nur noch auf Symbole statt per Offsets verweist
Zitat:Wie kommt man denn vom gecasteten struct zu "ganz normalen" vom Compiler allozierten Variablen auf dem Heap?
wenn du die ds-Variable auf den struct castest kannst du "ds" weiter als Bytewolke - oder eben über den struct strukturiert zugreifen - und "vom Compiler allozierten Variablen auf dem Heap" gibt es technisch gar nicht - oder was meinst du? und selbst wenn es die geben würde ist es doch egal wo sie liegen - Hauptsache der Zugriff ist identisch
Beiträge: 589
Themen: 3
Registriert seit: Nov 2007
Bewertung:
17
15.02.2017, 11:10
(Dieser Beitrag wurde zuletzt bearbeitet: 15.02.2017, 11:18 von HenneNWH.)
Vielen Dank gaor für das schnelle erstellen der CPP-Datei.
Ich habe sie eben bei mir getestet und soweit funktioniert es prima, nur dass das Datesegment jetzt etwas zu klein ist, wenn ich DS_SIZE auf 1 setzte.
Ich habe allerdings noch ein paar kleine Änderungen, welch ich jetzt committen werde.
Es wäre schön, wenn du dann einen Pull-Request mit den Daten machen kannst.
Eine wichtige Sache noch, die Deklaration von ds muss vor der ersten Variable passieren, da sonst anderer Code erzeugt wird.
Weiteres vorgehen:
Mit etwas Trickserei konnte ich ein Binary erzeugen, in welchem der ganze Code an der richtigen Stelle steht.
Wenn gaors Daten gemerged sind, wird evtl. noch ein Tool benötigt mit dem die Datensegmente aus der SCHICKM.EXE und der neuen
BLADEM.EXE (in temp) verglichen werden können. Zu Not geht auch "dd" und "cmp".
Beiträge: 12.931
Themen: 169
Registriert seit: Jul 2008
Bewertung:
37
15.02.2017, 17:45
(Dieser Beitrag wurde zuletzt bearbeitet: 15.02.2017, 17:54 von Rabenaas.)
(15.02.2017, 09:33)llm schrieb: ich habe keine Ahnung was du meinst - kannst du die Frage umformulieren? Die Frage war echt nicht genial formuliert.
Ich meinte eigentlich gar nicht den BCC selbst, sondern ein identisches Kompilat (durch den BCC) auf Byteebene, für das hier einige Umwege in Kauf genommen werden. Oder meint ihr, die globalen Variablen wurden schon im Original in ein struct gepackt, auf das dann ein Speicherbeich gecastet wurde? Ich meine, das wäre ein ziemlich seltsames Programmierparadigma. Vermutlich wurde das etwas konventioneller gehandhabt.
(15.02.2017, 09:33)llm schrieb: und selbst wenn es die geben würde ist es doch egal wo sie liegen - Hauptsache der Zugriff ist identisch Da bin ich mir eben nicht ganz sicher. Hängt davon ab, ob nur das Kompilat "schön" sein soll, oder auch der Code. Aber ok, das Verfahren mit dem struct ist ein Fortschritt. Mit "vom Compiler allozierten Variablen auf dem Heap" meinte ich globale Variablen a la "struct nlt_timer_t licht_an_timer;" o.ä.
Beiträge: 113
Themen: 0
Registriert seit: Jan 2009
Bewertung:
3
15.02.2017, 22:20
(Dieser Beitrag wurde zuletzt bearbeitet: 15.02.2017, 22:23 von gaor.)
(15.02.2017, 11:10)HenneNWH schrieb: Ich habe allerdings noch ein paar kleine Änderungen, welch ich jetzt committen werde.
Es wäre schön, wenn du dann einen Pull-Request mit den Daten machen kannst.
Eine wichtige Sache noch, die Deklaration von ds muss vor der ersten Variable passieren, da sonst anderer Code erzeugt wird. Okay, ds also vor der ersten Variable deklarieren.
Bevor ich für irgendwas einen PR erstelle: Haben denn die Deklarationen der ganzen globalen Variablen Auswirkungen auf das mit gcc kompilierte Bright-Eyes? Macht das zum jetzigen Zeitpunkt irgendeinen Unterschied, wenn die da alle noch in der datseg.cpp herumfliegen?
Wenn ich aktuell eine DATSEG.OBJ baue und die dort enthaltenen Daten (mittels xxd) mit dem Datensegment der originalen SCHICKM.EXE vergleiche, kommt heraus, dass in der DATSEG.OBJ irgendwelche zusätzlichen Daten rumfliegen, deren Herkunft ich mir nicht erklären kann - allerdings erst ab Offset 0x0400 (gerechnet ab dem Beginn des Datensegments), davor stimmen die Datensegmente überein. Das bedeutet, dass mitten im Array "g_wearable_items_warrior" irgendwelche Daten eingefügt werden, die in der Deklaration gar nicht vorkommen?!
Übrigens gibt es eine neue Version meiner datseg.cpp: https://gist.github.com/tuxor1337/08cdaf...c95d466c18 Ich initialisiere jetzt auch Variablen, die den Wert 0 haben (hatte ich vorher uninitialisiert gelassen, dann sortiert er die aber in der DATSEG.OBJ weg).
Beiträge: 589
Themen: 3
Registriert seit: Nov 2007
Bewertung:
17
Du benutzt doch auch den BCC, stimmts?
Hast Du im Verzeichnis rewrite_m302de/temp/ die Dateien BLADEM.EXE und BLADEM.MAP?
Das Datensegment solltest du am besten aus der BLADEM.EXE extrahieren.
(15.02.2017, 22:20)gaor schrieb: Bevor ich für irgendwas einen PR erstelle: Haben denn die Deklarationen der ganzen globalen Variablen Auswirkungen auf das mit gcc kompilierte Bright-Eyes? Macht das zum jetzigen Zeitpunkt irgendeinen Unterschied, wenn die da alle noch in der datseg.cpp herumfliegen?
Das macht zum jetzigen Zeitpunkt für die GCC-Version tatsächlich keinen nennenswerten Unterschied.
Es wird erst interessant, wenn die ds_*-Makros/Funktionen wirklich durch Zugriffe auf die Variablen ersetzt werden.
Dann wird aber das Skript bc_ready.sh nicht mehr funktionieren,
da die Adressen in den Objektdateien relativ zum Anfang der DATA, bzw. BSS Sektion der Objektdatei angegeben werden.
Ich halte es für die einfachste Lösung, wenn als nächster Schritt das Datensegment in der DOS-Variante von Bright-Eyes
mit dem der SCHICKM.EXE in Übereinstimmung gebracht wird.
Dann reicht es aus nur noch die Binärdateien zu vergleichen.
(15.02.2017, 22:20)gaor schrieb: Wenn ich aktuell eine DATSEG.OBJ baue und die dort enthaltenen Daten (mittels xxd) mit dem Datensegment der originalen SCHICKM.EXE vergleiche, kommt heraus, dass in der DATSEG.OBJ irgendwelche zusätzlichen Daten rumfliegen, deren Herkunft ich mir nicht erklären kann - allerdings erst ab Offset 0x0400 (gerechnet ab dem Beginn des Datensegments), davor stimmen die Datensegmente überein. Das bedeutet, dass mitten im Array "g_wearable_items_warrior" irgendwelche Daten eingefügt werden, die in der Deklaration gar nicht vorkommen?!
Das funktioniert so nicht.
Der Grund dafür ist, dass die Daten- und Codebereiche in den OBJ-Dateien aufgeteilt werden.
Deshalb siehst du Verwaltungsdaten und Programmdaten gemischt.
Genau deswegen gibt es das tool dump_obj, welches die zusammengesetzten Codeteile aus den OBJ-Dateien extrahiert.
Eine datseg.obj gibt es jetzt nicht mehr, da die SCHICKM.EXE auch ein Segment (seg14) enthält,
dessen Größe von der Anzahl der gelinkten Objektdateien abhängt.
Die Datei datseg.cpp habe ich in seg002.cpp per include eingebunden.
(Kein guter Stil aber die Größe von seg14 ändert sich nicht.)
(15.02.2017, 22:20)gaor schrieb: Übrigens gibt es eine neue Version meiner datseg.cpp: https://gist.github.com/tuxor1337/08cdaf...c95d466c18 Ich initialisiere jetzt auch Variablen, die den Wert 0 haben (hatte ich vorher uninitialisiert gelassen, dann sortiert er die aber in der DATSEG.OBJ weg).
Das mag als guter Stil erscheinen, aber initialisierte Daten (DATA) und uninitialisierte Daten (BSS) werden vom Linker an unterschiedlichen Orten im Datensegment abgelegt.
Zuerst die C-Lib-Daten (DATA), z.B. der String "Borland C++"... , dann die DATA Daten der einzelnen Objektdateien,
in der Reihenfolge des Linkens.
Anschließend kommen die BSS-Daten.
Wenn die Variablen jetzt initialisiert werden wechseln sie von der BSS- in die DATA-Section
und die Reihenfolge ist durcheinander.
Ich bleibe bei der alten Datei.
Da fehlen zwar noch die Adressen von den Funktionspointern für Reiseevents, Zaubersprüche, etc.,
welche ich aus der GCC-Variante übernehmen kann.
Ein größerer Aufwand muss dann bei den Beschreibungen der Schatztruhen betrieben werden,
da diese auch Funktionspointer enthalten.
Ja, das ist im Detail nicht so einfach wie gedacht, aber du hast meinen Respekt und Dank,
dass Du dich in dieses Projekt so gut einarbeitest.
Beiträge: 113
Themen: 0
Registriert seit: Jan 2009
Bewertung:
3
16.02.2017, 16:30
(Dieser Beitrag wurde zuletzt bearbeitet: 16.02.2017, 16:32 von gaor.)
Danke für deine Erklärungen! Ja, ich benutze die Skripte bc.sh und bc-ready.sh mit BCC 3.1. Bisher landet in der BLADEM.EXE kein Datensegment, glaube ich. Vielleicht muss ich das aber auch nochmal mit der aktuellsten Revision überprüfen.
(16.02.2017, 10:41)HenneNWH schrieb: Das mag als guter Stil erscheinen, aber initialisierte Daten (DATA) und uninitialisierte Daten (BSS) werden vom Linker an unterschiedlichen Orten im Datensegment abgelegt. Nein, das hat mit Stil nichts zu tun. Das Problem ist, dass du umgekehrt Variablen in BSS kriegst, die eigentlich in DATA sein müssten, wenn du die Initialisierung überall weglässt. Was tust du dagegen? Meiner aktuellen Einschätzung nach, ist das ein größeres Problem - deswegen habe ich mich für die Variante mit Initialisierung entschieden.
(16.02.2017, 10:41)HenneNWH schrieb: Da fehlen zwar noch die Adressen von den Funktionspointern für Reiseevents, Zaubersprüche, etc.,
welche ich aus der GCC-Variante übernehmen kann. Richtig: Die Funktionspointer fehlen noch und werden noch ein bisschen Arbeit abverlangen. Aber es sind nicht so wahnsinnig viele. Außerdem fehlen noch einige Pointer innerhalb des Datensegments.
Beiträge: 589
Themen: 3
Registriert seit: Nov 2007
Bewertung:
17
17.02.2017, 11:09
(Dieser Beitrag wurde zuletzt bearbeitet: 17.02.2017, 11:11 von HenneNWH.)
(16.02.2017, 16:30)gaor schrieb: (16.02.2017, 10:41)HenneNWH schrieb: Das mag als guter Stil erscheinen, aber initialisierte Daten (DATA) und uninitialisierte Daten (BSS) werden vom Linker an unterschiedlichen Orten im Datensegment abgelegt.
Nein, das hat mit Stil nichts zu tun. Das Problem ist, dass du umgekehrt Variablen in BSS kriegst, die eigentlich in DATA sein müssten, wenn du die Initialisierung überall weglässt. Was tust du dagegen? Meiner aktuellen Einschätzung nach, ist das ein größeres Problem - deswegen habe ich mich für die Variante mit Initialisierung entschieden.
Jetzt sehe und verstehe ich was du meinst. Alle Variablen vor Adresse DS:0xbc83 müssen initialisiert werden (auch wenn 0 drin steht),
da das alles DATA ist.
Ab Adresse DS:0xbc83 beginnt die BSS-Sektion, dessen Variablen nicht initialisiert werden dürfen.
Ich habe nach ein paar kleinen Änderungen und Initialisierungen schon einen beachtlichen identischen Bereich von 0x87 - 0x2988.
Das ist bedeutet, dass schon über ein Achtel der Variablen an seinem Platz sind.
Alles was vor Adresse 0x0094 steht kommt vom Compiler und kann verworfen werden.
An Adresse 0x94 habe ich char g_unkn_002 = 2; eingefügt und schon passt es.
(16.02.2017, 16:30)gaor schrieb: (16.02.2017, 10:41)HenneNWH schrieb: Da fehlen zwar noch die Adressen von den Funktionspointern für Reiseevents, Zaubersprüche, etc.,
welche ich aus der GCC-Variante übernehmen kann. Richtig: Die Funktionspointer fehlen noch und werden noch ein bisschen Arbeit abverlangen. Aber es sind nicht so wahnsinnig viele. Außerdem fehlen noch einige Pointer innerhalb des Datensegments.
Die Pointer im Datensegment dürfen richtige Pointer auf Bit8u* (also unsigned char*) sein.
Zumindest diejenigen, die sich nicht im Spielstand befinden.
Diese sollten weiterhin erstmal den Typ RealPt behalten.
Für diese muss dann einzeln entschieden werden wie mit ihnen verfahren wird, damit das Spiel weiterhin funktioniert.
Beiträge: 113
Themen: 0
Registriert seit: Jan 2009
Bewertung:
3
In meinem Pull Request hatte ich mich jetzt übrigens dafür entschieden, gewöhnliche Variablendeklarationen statt ein struct (wie von llm vorgeschlagen) zu verwenden. Das liegt daran, das mit dieser Version das komplette DATA Segment identisch mit dem Original ist. Es scheint mir unnötig, angesichts dessen noch irgendwelche assertions und memcmp Checks einzubauen. Bis auf ein paar Pointer ist das Thema also jetzt durch.
Beiträge: 113
Themen: 0
Registriert seit: Jan 2009
Bewertung:
3
Wie kann ich die Konstanten aus der common.h (z.B. für Items) in der datseg.cpp verwenden? Einfach nur die common.h einbinden geht nicht. Muss ich noch die v302de.h einbinden oder was genau ist da die beste Lösung?
Beiträge: 2.489
Themen: 25
Registriert seit: Aug 2006
Bewertung:
17
Hey. Auf meinem neuen Rechner habe ich gerade wieder die Build-Umgebung für BrightEyes zusammengestellt und einen Test-Build durchgeführt. Leider kommt es zu zu Fehlern. Habe ich da doch noch etwas falsch einstellt? Wobei es für mich als Laien nach einem anderem Problem aussieht. BuildLog im Anhang.
BuildLog.zip (Größe: 34,09 KB / Downloads: 5)
Beiträge: 166
Themen: 3
Registriert seit: Jul 2016
Bewertung:
6
Beiträge: 668
Themen: 71
Registriert seit: Apr 2008
Bewertung:
6
Gibt es überhaupt eine Kampf-ID in Sternenschweif wie bei Schick? *grübel*
"Save early and save often!" - Speichere oft und speichere früh! - Ist eine alte Zockerweisheit.
Beiträge: 2.320
Themen: 52
Registriert seit: Aug 2013
Bewertung:
14
Was genau meinst du mit Kampf-ID? Kämpfe sind ähnlich wie in Schick, ja, einige sind aber auch in der Schweif.exe versteckt, und wir haben noch nicht alle lokalisiert.
Oder meintest du etwas anderes?
Hacke Tau, Kumpels!
Ihr seid Freunde der alten NLT? Freunde des Mikromanagements? Ihr sucht eine neue Herausforderung, weil euch die NLT zu leicht war?
Dann spielt doch mal Schicksalsklinge HD 1.36 von Crafty Studios!
|