Themabewertung:
  • 4 Bewertung(en) - 3.5 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Reverse Engineering der NLT II
(20.11.2025, 13:34)HenneNWH schrieb: Nur zur Info: Der Address-Sanitizer funktioniert bei mir mit GCC auf dem Raspi2 nicht. Da fehlen scheinbar hardwareseitig atomic_load/store und compare_exchange Instruktionen.

x64 ist die Primärplatform, da passiert die meiste weiterentwicklung
Zitieren
hab gerade deinen String-Table Commit gesehen: https://github.com/Henne/BrightEyes/comm...6a30e3ba15

macht es nicht Sinn da mit einem array-typedef zu arbeiten um von den Magic-Values ganz weg zu kommen oder die Pointer-Size Probleme nur auf dem typedef zu haben, oder kann der Borland C++ 3.1 das nicht?

Code:
typedef char* string_table_t[1190]; // sizeof() = 9520

string_table_t* st = (string_table_t*)malloc(sizeof(string_table_t));

ich verstehe nur nicht so ganz warum der Borland C teil nur

Code:
g_global_buffer_ptr = (HugePt)schick_alloc(g_buffersize);

macht?
Zitieren
(20.11.2025, 14:46)NewProggie schrieb: Daneben bin ich einmal die seg-Dateien durch und hätte folgenden Vorschlag für die Umbenennung der Dateien:

Code:
# Core Systems (seg001-seg011)
seg001 -> cdrom
seg002 -> misc
seg003 -> movement
seg004 -> graphics
seg005 -> fight_core
seg006 -> fight_base
seg007 -> random_dice
seg008 -> rasterlib
seg009 -> pp20_decompress
seg010 -> ems
seg011 -> sound_ail

# Game Data & Core Mechanics (seg024-seg032)
seg024 -> diary
seg025 -> locations
seg026 -> save_text
seg027 -> file_loader
seg028 -> resource_loader
seg029 -> playmask
seg030 -> talk_date
seg031 -> tavern_helpers
seg032 -> fight_helpers

# Fight System (seg033-seg050)
seg033 -> fight_menu
seg034 -> fight_system
seg035 -> fight_logic
seg036 -> fight_auto_hero
seg037 -> fight_enemy_attack
seg038 -> fight_actions
seg039 -> fight_mechanics
seg040 -> fight_scenarios
seg041 -> fight_control
seg042 -> fight_hero_action
seg043 -> fight_enemy_action
seg044 -> fight_anim_figures
seg045 -> fight_anim_effects
seg046 -> status_display
seg047 -> heroes_group
seg048 -> status_menu
seg049 -> group_mgmt
seg050 -> level_up

# Locations & Environments (seg051-seg074)
seg051 -> wilderness_camp
seg052 -> area_camp
seg053 -> location_healer
seg054 -> location_inn
seg055 -> merchant_main
seg056 -> merchant_buy
seg057 -> merchant_sell
seg058 -> location_smith
seg059 -> tavern_main
seg060 -> tavern_talk
seg061 -> temple_main
seg062 -> temple_miracle
seg063 -> harbor_main
seg064 -> harbor_helper
seg065 -> special_anims
seg066 -> town_main
seg067 -> city_events
seg068 -> thorwal_buildings1
seg069 -> thorwal_buildings2
seg070 -> phexcaer_buildings1
seg071 -> phexcaer_buildings2
seg072 -> informer_script
seg073 -> tavern_gossip
seg074 -> automap

# Dungeon Systems (seg075-seg092)
seg075 -> dungeon_common1
seg076 -> dungeon_common2
seg077 -> dungeon_ship_death
seg078 -> dungeon_inn
seg079 -> dungeon_spider_cave
seg080 -> dungeon_wolf_cave
seg081 -> dungeon_cave2
seg082 -> dungeon_mageruin
seg083 -> dungeon_orc_lair
seg084 -> dungeon_main
seg085 -> dungeon_cave4
seg086 -> dungeon_pirate_cave
seg087 -> dungeon_thorwal1
seg088 -> dungeon_thorwal2
seg089 -> dungeon_ruined_castle
seg090 -> dungeon_oberorken_mine
seg091 -> dungeon_prem_mine
seg092 -> treasures

# Game Mechanics & Magic (seg093-seg122)
seg093 -> travel_mode1
seg094 -> travel_mode2
seg095 -> npcs
seg096 -> text_output
seg097 -> gui
seg098 -> magic_main
seg099 -> spells1
seg100 -> spells2
seg101 -> spells3
seg102 -> spells_monster
seg103 -> talents
seg104 -> alchemy_cure
seg105 -> inventory_main
seg106 -> inventory_misc
seg107 -> item_use
seg108 -> consume
seg109 -> travel_event1
seg110 -> travel_event2
seg111 -> travel_event3
seg112 -> travel_event4
seg113 -> travel_event5
seg114 -> travel_event6
seg115 -> travel_event7
seg116 -> travel_event8
seg117 -> travel_event9
seg118 -> travel_event10
seg119 -> disease_effect
seg120 -> game_init
seg121 -> poison_effect
seg122 -> dummy_location

Was meint ihr?

Vielen Dank! Die Liste können wir auf Alle Fälle mal aufheben für später. Ein wenig würde ich anpassen, z.B. seg002 -> main, bei seg053 bis 064 sollte entweder überall location dabeistehen oder nirgends, und die Kampf-Benennungen sind teilweise doch recht unspezifisch. Es wäre mir aber sehr recht, wenn die Benennung der Dateien von schick und schick_dos parallel bleibt, und solange der BCC noch im Rennen ist, müssen die Dateinamen vermutlich sowieso das Format 8.3 haben.
Zitieren
wie wollte ihr Unit-Tests machen?

die einfachste Variante wäre wohl eine statische Instanzierung einer Test-Structs welcher dann im ctor irgendwelche Tests macht
also einfach mitten im Code drin

z.B.


Code:
struct test_chr_finding_t
{
  test_chr_finding_t()
  {
    //loads all .chr filenames from /temp
    //assert if something ist wrong
  }
}
#if defined(UNIT_TEST)
static test_chr_finding_t test_chr_finding;
#endif

ganz lokal mit geringer Distanz zum zu testetenden Code

für den Anfang

wird dann vor dem Spiel-Start ausgeführt
Zitieren
Wie seht ihr den Einsatz von der C++/STL im nicht DOS-Teil?

z.B. std::string,std::vector, std::map, eben die ganz einfachen Container

auch std::filesystem?

man könnte einige von diesen globalen Puffern recht schnell unrelevant machen

z.B. 

Code:
signed int copy_chr_names(char* ptr, const signed int temple_id);
signed int menu_enter_delete(char* ptr, const signed int entries, const signed int mode)

durch

Code:
struct name_info_t
{
   std::string name;
   std::string alias;
};
std::vector<name_info_t> copy_chr_names(const signed int temple_id);
signed int menu_enter_delete(const std::vector<name_info_t>& entries, const signed int mode)

ersetzen

ist nur ein Beispiel - aber da kommt schon einiges zusammen

würde natürlich aber auch schon helfen diese char* ptr durch richtige Typen zu ersetzen

Code:
signed int menu_enter_delete(char* ptr, const signed int entries, const signed int mode)
{
  ...
  g_radio_name_list[i] = ((i + i_min) * 32 + ptr + 16);
  ...
}

durch

Code:
struct name_info_t
{
   char name[16];
   char alias[16];
};
signed int menu_enter_delete(name_info_t* names, const signed int entries, const signed int mode)
{
  ...
  g_radio_name_list[i] = names[i + i_min].alias;
  ...
}
Zitieren
Ich habe heute ein wenig an der STAR.DAT herumgerätselt:

Das, was z.B. im Wiki zu den Sternenschweif-Archiven steht (bzw. was nltpack macht), muss unvollständig sein:
https://github.com/shihan42/BrightEyesWi...nenschweif

Zumindest muss ich ziemlich heftige H*cks anwenden, um sie so modifizieren zu können, dass das Spiel sie fehlerfrei einliest. Bzw. ich verstehe aktuell einfach noch nicht, was genau schiefgeht. Vielleicht stehen an anderer Stelle irgendwo hardcodierte Dateilängen, oder das Spiel gleicht HDD- und CD-Variante auf eine mir unbekannte Weise ab.

Im Moment scheint jedoch folgender Ansatz zu funktionieren:
- Entferne alle Dateien aus dem HDD-Archiv und setze CD=0-Flag und Offset=0, außer
  a) für die Datei(en), die modifiziert werden sollen 
  b) für die auf die letzte zu modifizierende Datei folgende Datei: Setze CD=0-Flag, aber setze den Offset auf das Ende der Datei: Dateilänge-(20 × Anzahl Einträge + 2).

Andernfalls ist die allerletzte Datei (CD=1) kaputt.
Hierbei konnte ich verifizieren, dass sowohl die modifizierten als auch die darauf folgende Datei vom Spiel gefunden werden.

Vielleicht ist mein Ansatz auch komplett falsch. Er erklärt nicht, warum die unmodifizierten Spielarchive funktionieren, denn dort wird dieser „Hack“ ja nicht verwendet.
Aber zumindest wäre er (bis wir verstehen, wie der originale Code funktioniert) am ungefährlichsten, da so alle unmodifizierten Dateien von CD gelesen werden.

Ein anderer Ansatz, der in meinen Tests „funktioniert“ hat, war, die „vollständige“ STAR.DAT von der CD auf die HDD zu kopieren und diese zu modifizieren: Damit haben alle existierenden/relevanten Dateien dann CD=1-Flag und müssen daher nicht von CD gelesen werden.
Allerdings verstehe ich auch hier nicht, wieso es funktioniert. Gegebenenfalls ist auch hier die letzte Datei kaputt, nur dass es eben eine andere ist, die in meinen Tests ggf. einfach nicht gelesen wurde.

----
Wollte das einfach mal kurz festhalten. Vielleicht finde ich die Ursache des Problems noch und komme ohne „Hack“ aus.
Fürs Erste ist es für mich schon Erfolg genug, die Stern-Archive überhaupt irgendwie, ohne Absturz im Spiel, modifizieren zu können.

Und: der Porträt-Exporter DSA1/Custom -> [DSA2, DSA3] ist damit fast fertig! Dazu mache ich im Lauf der kommenden Woche ein neues Thema auf. Kleiner Teaser im Anhang.

Ich habe mich übrigens geirrt: Jedes Porträt aus der Schicksalsklinge hat ab DSA2 ein korrespondierendes erhalten, wurde aber teilweise deutlich verändert, z.B. mit anderen Augen- oder Haarfarben.
Über den Exporter wird es dann deutlich einfacher sein, entweder mit den unveränderten Porträts aus DSA1 weiterzuspielen oder ein ganz eigenes Porträt zu importieren.


Angehängte Dateien Thumbnail(s)
   
Zitieren
(24.11.2025, 18:25)cmfrydos schrieb: Und: der Porträt-Exporter DSA1/Custom -> [DSA2, DSA3] ist damit fast fertig! Dazu mache ich im Lauf der kommenden Woche ein neues Thema auf. Kleiner Teaser im Anhang.

Ich habe mich übrigens geirrt: Jedes Porträt aus der Schicksalsklinge hat ab DSA2 ein korrespondierendes erhalten, wurde aber teilweise deutlich verändert, z.B. mit anderen Augen- oder Haarfarben.
Über den Exporter wird es dann deutlich einfacher sein, entweder mit den unveränderten Porträts aus DSA1 weiterzuspielen oder ein ganz eigenes Porträt zu importieren.

Das fänd ich super. Ich hab mich schon immer etwas geärgert, dass meine Truppe von DSA1 -> DSA2 anders aussieht und ich hätte viel lieber die möglichst originalen Köpfe wieder gehabt.
Zitieren
Ja, das sollte damit dann leicht möglich sein, mit den alten Köpfen weiterzuspielen.

Man kann damit auch Köpfe klassen-/typusübergreifend zuweisen, also z.B. einen Krieger mit Thorwalerkopf spielen. Ich überlege gerade, wie ich in der UI am geschicktesten auch intra-DSA2/DSA3-Porträtverschiebungen realisieren kann (vermutlich über einen weiteren Tab neben dem Dateiimport.)

Ich finde manche der Köpfe eher seltener benutzter Klassen nämlich ganz schön, ohne dass sie direkt z.B. „Hexe“, „Streuner“ oder „Thorwaler“ schreien. Nur wenige Porträts sind aufgrund des Outfits (oder spitzer Ohren) klar einer Klasse zuzuordnen.
Zitieren
Das fände ich auch echt gut, wenn man die Heldenportraits auch noch nach DSA 1 nutzen könnte.  :)

Ich habe mir bislang damit beholfen, in jedem Teil die Gesichter auszuwählen (per HEX-Editor) die mir am besten gefallen, aber das funktionierte dann eben nur innerhalb von DSA 1 oder DSA 2 bzw. DSA 3 und nicht übergreifend von 1 nach 2 bzw. 3.

Wäre denn eine Auswahl von DSA 2 / DSA 3 Portraits innerhalb von DSA 1 auch möglich?
"Alrik war durstig und hat getrunken."
Zitieren
(25.11.2025, 19:54)Alrik Alrikson schrieb: Wäre denn eine Auswahl von DSA 2 / DSA 3 Portraits innerhalb von DSA 1 auch möglich?

Ja! Das habe ich gestern noch implementiert, ebenso eine weitere Möglichkeit des Palettenwechsels (mittels Markov-Ketten, um Kantenkontraste zu bewahren), die mir optisch noch besser zusagt! Allerdings gibt es in DSA1 leider weniger Farben zur Auswahl, sodass (noch) nicht alle Farben/Porträts gut funktionieren, aber die allermeisten, sodass man sich dann auch als Arva von Harben, Feylamia, oder Ork Thurazz auf die Suche nach der Schicksalsklinge machen kann! :ok:

Die Tage dazu mehr; es gibt leider noch ein paar (wenige) Bugs von mir zu fixen.


Angehängte Dateien Thumbnail(s)
       
Zitieren
Der Alpha aus dem rechten Bild hat Ähnlichkeit mit Edwin aus Baldurs Gate.
Zitieren
Ah, da hast du wohl die Vorlage für seinen Avatar gefunden!
Ich wollte gestern bloß mal Box-Downsampling ausprobieren und habe dafür ein paar der hier (für diesen Zweck) interessanteren Profilbilder genommen.
Heute habe ich noch einmal etwas recherchiert und noch viele weitere klassische Non-KI-Techniken gefunden, die ich unbedingt ausprobieren, und integrieren möchte.
Vermutlich mache ich den aktuellen Stand erst einmal release-reif und schiebe dann noch ein paar Techniken für den Custom-Bild-Import nach.
Es gibt sicher auch gute Downsampling-Tools für genau diesen Zweck, aber nicht so schön integriert mit passendem Palettenwechsel für die NLT..
Zitieren
(25.11.2025, 22:05)cmfrydos schrieb:
(25.11.2025, 19:54)Alrik Alrikson schrieb: Wäre denn eine Auswahl von DSA 2 / DSA 3 Portraits innerhalb von DSA 1 auch möglich?

Ja! Das habe ich gestern noch implementiert, ebenso eine weitere Möglichkeit des Palettenwechsels (mittels Markov-Ketten, um Kantenkontraste zu bewahren), die mir optisch noch besser zusagt! Allerdings gibt es in DSA1 leider weniger Farben zur Auswahl, sodass (noch) nicht alle Farben/Porträts gut funktionieren, aber die allermeisten, sodass man sich dann auch als Arva von Harben, Feylamia, oder Ork Thurazz auf die Suche nach der Schicksalsklinge machen kann! :ok:

Die Tage dazu mehr; es gibt leider noch ein paar (wenige) Bugs von mir zu fixen.

Ah, sehr cool!  :) Sieht echt gut aus wie die DSA 2 bzw. DSA 3 Helden / NPC da in der Schicksalsklinge sind. 

Ja, die Portraits sehen farblich etwas anders aus, aber das verbinde ich auch mit dem ersten Teil der Trilogie und passt gut zu den anderen (originalen) Portraits.
"Alrik war durstig und hat getrunken."
Zitieren
Eine weitere sinnvolle Ergänzung, die man in der "neuen" Schick einbauen könnte, wäre die Würfelergebnisse anzuzeigen, so wie es derzeit bereits mit
Code:
D1_INFO(...)
auf der Konsole passiert
Zitieren




Benutzer, die gerade dieses Thema anschauen: 3 Gast/Gäste