Themabewertung:
  • 5 Bewertung(en) - 5 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Reverse Engineering der NLT
(01.01.2017, 20:35)Wetzer schrieb: Mh. Die Größe der Zip-Datei vom 24.12.16 scheint, was ihre Größe betrifft, etwas aus der Reihe zu fallen. Ist mir nur so aufgefallen.

Leichte Schwankungen von 200KB würde ich jetzt noch nicht auffällig nennen. Normalerweise erstelle ich die ZIP-Dateien mit WinRar, am 24.12. mit der Standard-Kompression von Windows 10. Daher kommt der Unterschied, wie ich gerade ausprobiert habe.

Ansonsten ist aber schön zu sehen, wie die ZIP-Dateien, bzw. die enthaltende dosbox.exe, immer größer werden.
--------
Warnung! Geschichte kann zu Einsichten führen und verursacht Bewusstsein!
Avatar by: Keven Law (CC BY-SA 2.0)
Es gibt ja das Tool nltpack, mit dem die Dateien in der SCHICK.DAT entpackt werden können. Gibt es auch ein Tool, mit dem man die Dialog- und Text-Dateien (TLK bzw. DTX/LTX) effizient auslesen kann?

Die Text-Dateien scheinen ja lediglich NULL-separierte Strings zu enthalten. Trotzdem wäre es gut, schnell zwischen denen springen zu können, etwa: Zeige den 45ten String in der Datei TEXT.LTX! So wird nämlich auch im Code darauf zugegriffen. Die Dialog-Dateien enthalten nach einem kurzen Header auch wieder nur NULL-separierte Strings. Hier wäre es aber noch viel wichtiger, im Sinne der Dialog-Logik des Spiels zugreifen zu können.

Ganz rudimentär habe ich mir beides momentan als Shell-Scripte erstellt. Wenn noch Bedarf an solchen Tools existiert, dann könnte ich die Scripte etwas einfacher bedienbar gestalten und der Allgemeinheit zur Verfügung stellen.
Ich habe mal das hier aus seg073.cpp extrahiert.
Code:
0x3da2 CAMP_BREIDA_SERSKE_1
0x3da3 CAMP_BREIDA_SERSKE_2
0x3da4 CAMP_BREIDA_TJOILA
0x3da5 CAMP_BREIDA_PEILINEN
0x3da6 CAMP_PEILINEN_ROVAMUND
0x3da7 CAMP_NORDVEST_ROVAMUND
0x3daa CAMP_KRAVIK_NORDVEST
0x3dac CAMP_KRAVIK_SKELELLEN
0x3dc2 CAMP_OTTARJE_SKJAL_1
0x3dc3 CAMP_OTTARJE_SKJAL_2
0x3dc6 CAMP_OTTARJE_SKJAL_3
0x3dcb CAMP_ORVIL_OVERTHORN
0x3dcd CAMP_ORVIL_THOSS_1
0x3dce CAMP_ORVIL_THOSS_2
0x3dcf CAMP_ORVIL_THOSS_3
0x3dd5 CAMP_AUPLOG_VARNHEIM
0x3dd8 CAMP_KORD_PREM
0x3dd9 CAMP_PREM_SKJAL
0x3ddd CAMP_FELSTEYN_OBERORKEN
0x3de0 CAMP_FELSTEYN_ORKANGER
0x3de3 CAMP_CLANEGH_ORKANGER
0x3de6 CAMP_CLANEGH_TYLDON
0x3df0 CAMP_PHEXCAER_SKELELLEN
0x3df1 CAMP_RYBON_THOSS
0x3dfe CAMP_MERSKE_ROVAMUND_1
0x3dff CAMP_MERSKE_ROVAMUND_2
0x3e11 CAMP_OVERTHORN_SKJAL_1
0x3e12 CAMP_OVERTHORN_SKJAL_2
0x3e13 CAMP_HJALSINGOR_OVERTHORN
0x3e14 CAMP_BRENDHIL_MANRIN
(08.01.2017, 17:10)Rabenaas schrieb: Ich habe mal das hier aus seg073.cpp extrahiert.
Oh, daran habe ich die letzten Tage gearbeitet und werde dazu demnächst einen Pull Request machen. Wir müssen mal gucken, wie wir das dann machen.

Wichtig: Die Einträge in symbols.h habe ich in den vergangenen Tagen fast komplett vervollständigt! Bitte nicht daran arbeiten, bevor ich nicht den Pull Request gemacht habe (für heute Abend geplant).
Schau doch bei Gelegenheit einfach, ob wir zu dem gleichen Ergebnis kommen.
So, hier ist mein angekündigter Pull Request: https://github.com/Henne/Bright-Eyes/pull/32

Alle übrigen "magic numbers" (sind nur noch etwa 50) könnt ihr jetzt gerne studieren. Ich beschäftige mich in nächster Zeit erstmal nicht mehr direkt damit.

@Rabenaas:
Hier meine Version des entsprechenden Abschnitts:
Code:
#define TEVENT004_FLAG    (0x3da2)    /* unsigned char {0,1} */
#define TEVENT005_FLAG    (0x3da3)    /* unsigned char {0,1} */
#define TEVENT008_FLAG    (0x3da4)    /* unsigned char {0,1} */
#define TEVENT009_FLAG    (0x3da5)    /* unsigned char {0,1} */
#define TEVENT011_FLAG    (0x3da6)    /* unsigned char {0,1} */
#define TEVENT013_FLAG    (0x3da7)    /* unsigned char {0,1} */
#define TEVENT014_FLAG    (0x3da8)    /* unsigned char {0,1} */
#define TEVENT016_FLAG    (0x3da9)    /* unsigned char {0,1} */
#define TEVENT017_FLAG    (0x3daa)    /* unsigned char {0,1} */
#define TEVENT020_FLAG    (0x3dab)    /* unsigned char {0,1} */
#define TEVENT021_FLAG    (0x3dac)    /* unsigned char {0,1} */
#define TEVENT022_FLAG    (0x3dad)    /* unsigned char {0,1} */
#define TEVENT022_TRACK_FLAG    (0x3dae)    /* unsigned char {0,1} */
#define TEVENT024_FLAG    (0x3daf)    /* unsigned char {0,1} */
#define TEVENT025_FLAG    (0x3db0)    /* unsigned char {0,1} */
#define TEVENT028_FLAG    (0x3db1)    /* unsigned char {0,1} */
#define TEVENT030_FLAG    (0x3db2)    /* unsigned char {0,1} */
#define TEVENT031_FLAG    (0x3db3)    /* unsigned char {0,1} */
#define TEVENT032_FLAG    (0x3db4)    /* unsigned char {0,1} */
#define TEVENT032_HERB_FLAG    (0x3db5)    /* unsigned char {0,1} */
#define TEVENT034_FLAG    (0x3db6)    /* unsigned char {0,1} */
#define TEVENT035_FLAG    (0x3db7)    /* unsigned char {0,1} */
#define TEVENT036_FLAG    (0x3db8)    /* unsigned char {0,1} */
#define TEVENT036_HERB_FLAG    (0x3db9)    /* unsigned char {0,1} */
#define TEVENT037_FLAG    (0x3dba)    /* unsigned char {0,1} */
#define TEVENT039_FLAG    (0x3dbb)    /* unsigned char {0,1} */
#define TEVENT040_FLAG    (0x3dbc)    /* unsigned char {0,1} */
#define TEVENT041_FLAG    (0x3dbd)    /* unsigned char {0,1} */
#define TEVENT042_FLAG    (0x3dbe)    /* unsigned char {0,1} */
#define TEVENT043_FLAG    (0x3dbf)    /* unsigned char {0,1} */
#define TEVENT048_FLAG    (0x3dc0)    /* unsigned char {0,1} */
#define TEVENT048_TRACK_FLAG    (0x3dc1)    /* unsigned char {0,1} */
#define TEVENT049_FLAG    (0x3dc2)    /* unsigned char {0,1} */
#define TEVENT050_FLAG    (0x3dc3)    /* unsigned char {0,1} */
#define TEVENT050_HERB_FLAG    (0x3dc4)    /* unsigned char {0,1} */
#define TEVENT051_FLAG    (0x3dc5)    /* unsigned char {0,1} */
#define TEVENT053_FLAG    (0x3dc6)    /* unsigned char {0,1} */
#define TEVENT058_FLAG    (0x3dc7)    /* unsigned char {0,1} */
#define TEVENT061_FLAG    (0x3dc8)    /* unsigned char {0,1} */
#define TEVENT064_FLAG    (0x3dc9)    /* unsigned char {0,1} */
#define TEVENT066_FLAG    (0x3dca)    /* unsigned char {0,1} */
#define TEVENT066_TRACK_FLAG    (0x3dcb)    /* unsigned char {0,1} */
#define TEVENT067_FLAG    (0x3dcc)    /* unsigned char {0,1} */
#define TEVENT069_FLAG    (0x3dcd)    /* unsigned char {0,1} */
#define TEVENT070_FLAG    (0x3dce)    /* unsigned char {0,1} */
#define TEVENT070_HERB_FLAG    (0x3dcf)    /* unsigned char {0,1} */
#define TEVENT070_TRAIL_FLAG    (0x3dd0)    /* unsigned char {0,1} */
#define TEVENT071_FLAG    (0x3dd1)    /* unsigned char {0,1} */
#define TEVENTU01_FLAG    (0x3dd2)    /* unsigned char {0,1} */
#define TEVENT064_SILENT_FLAG    (0x3dd3)    /* unsigned char {0,1} */
#define TEVENTU02_FLAG    (0x3dd5)    /* unsigned char {0,1} */
#define TEVENTU03_FLAG    (0x3dd6)    /* unsigned char {0,1} */
#define TEVENTU04_FLAG    (0x3dd7)    /* unsigned char {0,1} */
#define TEVENTU05_FLAG    (0x3dd8)    /* unsigned char {0,1} */
#define TEVENTU06_FLAG    (0x3dd9)    /* unsigned char {0,1} */
#define TEVENT071_ORCSTATUE    (0x3dda)    /* unsigned char {0,1} */
#define TEVENT072_FLAG    (0x3ddd)    /* unsigned char {0,1} */
#define TEVENT073_FLAG    (0x3dde)    /* unsigned char {0,1} */
#define TEVENT074_FLAG    (0x3ddf)    /* unsigned char {0,1} */
#define TEVENT075_FLAG    (0x3de0)    /* unsigned char {0,1} */
#define TEVENT076_FLAG    (0x3de1)    /* unsigned char {0,1} */
#define TEVENT077_FLAG    (0x3de2)    /* unsigned char {0,1} */
#define TEVENT079_FLAG    (0x3de3)    /* unsigned char {0,1} */
#define TEVENT080_FLAG    (0x3de4)    /* unsigned char {0,1} */
#define TEVENT080_TATZELWURM    (0x3de5)    /* unsigned char {0, 1, 2} */
#define TEVENT081_FLAG    (0x3de6)    /* unsigned char {0,1} */
#define TEVENT083_FLAG    (0x3de7)    /* unsigned char {0,1} */
#define TEVENT084_FLAG    (0x3de8)    /* unsigned char {0,1} */
#define TEVENT085_FLAG    (0x3de9)    /* unsigned char {0,1} */
#define TEVENT085_HERB_FLAG    (0x3dea)    /* unsigned char {0,1} */
#define TEVENT086_FLAG    (0x3deb)    /* unsigned char {0,5,15} */
#define TEVENT088_FLAG    (0x3dec)    /* unsigned char {0,1} */
#define TEVENT091_FLAG    (0x3ded)    /* unsigned char {0,1} */
#define TEVENT093_FLAG    (0x3dee)    /* unsigned char {0,1} */
#define TEVENT094_FLAG    (0x3def)    /* unsigned char {0,1} */
#define TEVENTU07_FLAG    (0x3df0)    /* unsigned char {0,1} */
#define TEVENTU08_FLAG    (0x3df1)    /* unsigned char {0,1} */
#define TEVENT099_FLAG    (0x3df2)    /* unsigned char {0,1} */
#define TEVENT100_FLAG    (0x3df3)    /* unsigned char {0,1} */
#define TEVENT101_FLAG    (0x3df4)    /* unsigned char {0,1} */
#define TEVENT106_FLAG    (0x3df5)    /* unsigned char {0,1} */
#define TEVENT108_FLAG    (0x3df6)    /* unsigned char {0,1} */
#define TEVENT109_FLAG    (0x3df7)    /* unsigned char {0,1} */
#define TEVENT111_FLAG    (0x3df8)    /* unsigned char {0,1} */
#define TEVENT112_FLAG    (0x3df9)    /* unsigned char {0,1} */
#define TEVENT112_HERB_FLAG    (0x3dfa)    /* unsigned char {0,1} */
#define TEVENT115_FLAG    (0x3dfb)    /* unsigned char {0,1} */
#define TEVENT116_FLAG    (0x3dfc)    /* unsigned char {0,1} */
#define TEVENT118_FLAG    (0x3dfd)    /* unsigned char {0,1} */
#define TEVENT119_FLAG    (0x3dfe)    /* unsigned char {0,1} */
#define TEVENT120_FLAG    (0x3dff)    /* unsigned char {0,1} */
#define TEVENT122_FLAG    (0x3e00)    /* unsigned char {0,1} */
#define TEVENT128_FLAG    (0x3e02)    /* unsigned char {0,1} */
#define TEVENT128_REPLEN_FLAG    (0x3e03)    /* unsigned char {0,1} */
#define TEVENT129_FLAG    (0x3e04)    /* unsigned char {0,1} */
#define TEVENT131_FLAG    (0x3e05)    /* unsigned char {0,1} */
#define TEVENT132_FLAG    (0x3e06)    /* unsigned char {0,1} */
#define TEVENT132_HERB_FLAG    (0x3e07)    /* unsigned char {0,1} */
#define TEVENT134_FLAG    (0x3e08)    /* unsigned char {0,1} */
#define TEVENT137_FLAG    (0x3e09)    /* unsigned char {0,1} */
#define TEVENT138_FLAG    (0x3e0a)    /* unsigned char {0,1} */
#define TEVENTU09_FLAG    (0x3e0b)    /* unsigned char {0,1} */
#define TEVENT140_FLAG    (0x3e0c)    /* unsigned char {0,1} */
#define TEVENT140_HERB_FLAG    (0x3e0d)    /* unsigned char {0,1} */
#define TEVENT141_FLAG    (0x3e0e)    /* unsigned char {0,1} */
#define TEVENT142_FLAG    (0x3e0f)    /* unsigned char {0,1} */
#define TEVENTU10_FLAG    (0x3e11)    /* unsigned char {0,1} */
#define TEVENTU11_FLAG    (0x3e12)    /* unsigned char {0,1} */
#define TEVENTU12_FLAG    (0x3e13)    /* unsigned char {0,1} */
#define TEVENTU13_FLAG    (0x3e14)    /* unsigned char {0,1} */
Ich habe mich dafür entschieden, die interne Nummerierung der Reiseereignisse zu verwenden. Ich hatte anfangs auch mal angedacht, in den Variablennamen mehr Informationen zu verstecken. Aber das wurde mir immer entweder zu lang oder zu unsystematisch.

Ich sehe, dass du in deinen Variablennamen die Reiseroute eingeflochten hast, auf der das jeweilige Reiseereignis auftritt. Die Zuordnung der Reiseereignisnummern zur Route, auf der das Ereignis eintritt, ist wirklich eine Interessante Information, die im Wiki bestimmt gut aufgehoben wäre. Im Spiel ist diese Information intern in TEVENTS_TAB, gespeichert. Das ist ein Array von Structs der Form (route_id, place, tevent_id). Eine Route kann man mit ihrer route_id in ROUTES_TAB nachschlagen. Dort steht dann, von wo nach wo die Route geht usw.
Was jetzt echt cool wäre, wäre ein tiefgehenderes Verständnis des Grafik-Renderings und der Animationen im Kampf.

Bis jetzt hat zum Beispiel noch niemand das Struct FIG_LIST_ELEM (bzw. die Einträge in der Liste, auf die FIGHT_LIST_HEAD zeigt) irgendwo verständlich dokumentiert. Hier sind meine bisherigen Erkenntnisse:
Code:
enum {
    FIGHTER_FIGURE      = 0x00,
    FIGHTER_NVF_NO      = 0x02,
    FIGHTER_CBX         = 0x03,
    FIGHTER_CBY         = 0x04,
    FIGHTER_OFFSETX     = 0x05,
    FIGHTER_OFFSETY     = 0x06,
    FIGHTER_HEIGHT      = 0x07,
    FIGHTER_WIDTH       = 0x08,
    FIGHTER_X1          = 0x09,
    FIGHTER_Y1          = 0x0a,
    FIGHTER_X2          = 0x0b,
    FIGHTER_Y2          = 0x0c,
    FIGHTER_RELOAD      = 0x0d, /* {0, -1 = update gfx data } */
    FIGHTER_SHEET       = 0x0e, /* see FIG_set_0e */
    FIGHTER_UNKN1       = 0x0f, /* see FIG_set_0f */
    FIGHTER_ID          = 0x10, /* position in FIG_LIST_ARRAY */
    FIGHTER_Z           = 0x11,
    FIGHTER_VISIBLE     = 0x12, /* {0,1,2 = ?} */
    FIGHTER_UNKN2       = 0x13, /* for two-fielded sprites...? */
    FIGHTER_OBJ_ID      = 0x14,
    FIGHTER_MONSTER     = 0x15, /* {0 = hero, 1 = monster} */
    FIGHTER_SPRITE_NO   = 0x16,
    FIGHTER_GFXBUF      = 0x17, /* RealPt */
    FIGHTER_NEXT        = 0x1b, /* RealPt */
    FIGHTER_PREV        = 0x1f, /* RealPt */
};

#define SIZEOF_FIGHTER (0x23)

Außerdem werden immer mal irgendwelche Paletten nachgeladen. Da wäre es natürlich gut, eine Übersicht zu haben, welche Palette da genau welchen Zweck erfüllt.

Ein anderer Datentyp sind die Structs in 0xd8ce (habe den Namen FIGHTANI_SHEETS vorgeschlagen), die irgendwie mit den Animationen zusammenhängen. Und die Einträge des Arrays in 0xbd6e sind für mich weiterhin total rätselhaft (siehe auch seg075.cpp).

Abgesehen davon bin ich immer noch voller Hochachtung für Henne, der hier echt eine wahnsinnige Arbeit geleistet hat. Ich bin schwer beeindruckt. Vielen Dank nochmal!
(08.01.2017, 20:14)gaor schrieb: Ich sehe, dass du in deinen Variablennamen die Reiseroute eingeflochten hast, auf der das jeweilige Reiseereignis auftritt. Die Zuordnung der Reiseereignisnummern zur Route, auf der das Ereignis eintritt, ist wirklich eine Interessante Information, die im Wiki bestimmt gut aufgehoben wäre.
Noch interessanter ist, finde ich, die Art des Events. Es handelt sich um Rastplätze. Ob das in den Namen, als Kommentar in den Header oder das Wiki kommt, kann ja noch später geschaut werden.
Ja, genau. Bei den Events gibt's oft auch kurze Dialoge. Im Wiki könnte man wunderbar eine Liste aller Reiseereignisse einrichten und zu jedem angeben, wo es stattfindet, was die interne Bezeichnung ist (Nummerierung) und was genau da passiert (spezieller Rastplatz usw.). Bin momentan mit anderen Dingen beschäftigt, deswegen lasse ich es jetzt erstmal bei diesem "könnte" ;-)
Ich habe kein Problem damit, das ins Wiki zu schreiben, wenn es jemand da haben möchte. Im Sourcecode wäre es allerdings bequemer erreichbar imo.
Ja, da hast du Recht. Wie wäre es, wenn man die Information in einen Kommentarbereich vor den travel event handlers einbaut? Etwa so:
Code:
/* Handler for a travel event between Breida and Serske (hunting opportunity). */
void tevent_004(void)
{
    // ...
}
Außerdem könnte man die Kommentare in seg073.cpp noch um ähnliche Informationen ergänzen.

Siehst du, ich will die Information über das Reiseereignis nicht in den Variablennamen hineinschreiben, weil ich möchte, dass der Variablenname die Variable selbst beschreibt und nicht das Reiseereignis, bei dem die Variable auftaucht. Ich behaupte nicht, dass ich schon die optimale Nomenklatur für die globalen Variablen gefunden habe. Ich glaube sogar, dass viele der aktuell gewählten Namen in symbols.h ungünstig gewählt sind. Aber die Route, die zu einem Reiseereignis gehört, sowie die Art des Reiseereignisses in den Namen der "visited flag" der Reisevariable zu schreiben, empfinde ich als irritierend.

Die Rastplätze, die du aus seg073.cpp extrahiert hast, sind übrigens nicht allesamt Rastplätze im gleichen Sinne. An manchen Plätzen wird man nur gefragt, ob man die Gelegenheit für eine Jagd oder fürs Kräuter sammeln nutzen möchte.
(13.01.2017, 11:30)gaor schrieb: Ja, da hast du Recht. Wie wäre es, wenn man die Information in einen Kommentarbereich vor den travel event handlers einbaut? Etwa so:
Code:
/* Handler for a travel event between Breida and Serske (hunting opportunity). */
void tevent_004(void)
{
    // ...
}

Da das ganze Projekt ja der Dokumentation des Quellcodes dient, wäre es auch an der Zeit, über Einsatz von Doxygen nachzudenken.
Was haltet ihr davon?
Ich bin klar dafür.
Ja, also auf jeden Fall. Das ist längst angedacht. Bei einzelnen Funktionen hat Henne auch schon entsprechende docstrings eingefügt. Für den obigen Fall der Reiseereignisse würde das ja im Wesentlichen bedeuten, noch ein \brief vor die Beschreibung zu setzen.

Nachtrag: Seite November 2014 gibt es eine Doxygen-Datei unter https://github.com/Henne/Bright-Eyes/blo...c/Doxyfile
Wenn man den Quellcode von Bright-Eyes verstehen will, hilft es ungemein, wenn man schnellen Zugriff auf Dateien in der SCHICK.DAT und auf die Startwerte der globalen Variablen in der SCHICKM.EXE hat. Deswegen habe ich mir in den letzten Tagen dieses Tool zusammengeschustert: https://github.com/tuxor1337/schick-data-gui

Hier zwei Screenshots (noch unbekannt Variablen in der SCHICKM.EXE sind farbig markiert; die Farben der Dateien in der SCHICK.DAT sollen den Datentyp anzeigen):

[Bild: screenshot2.png]

[Bild: screenshot.png]

Mangels einer Windows-Installation konnte ich das Tool bisher nur unter Linux testen. Weil die grafische Oberfläche auf Tkinter basiert, sollte es aber eigentlich auch unter Windows lauffähig sein, solange Python 3.x (mit tkinter, numpy und pillow) installiert ist. Ich kann aber nichts versprechen.
Das sieht doch schick aus :D (pun intended)

Habe es mal auf Windows getestet (Win10-64, Python 3.6.0). Dabei kommt folgendes raus:

Code:
D:\schick-data-gui-master>py schick-data-gui.py
0x0095 != 0x0000
Traceback (most recent call last):
  File "schick-data-gui.py", line 36, in <module>
    schick_reader = SchickReader(schickm_exe, schick_dat, symbols_h)
  File "D:\schick-data-gui-master\schick\reader.py", line 46, in __init__
    self.init_vars()
  File "D:\schick-data-gui-master\schick\reader.py", line 56, in init_vars
    data = self.parse_symbols_h_line(line)
  File "D:\schick-data-gui-master\schick\reader.py", line 89, in parse_symbols_h_line
    self.v_offset += sizeof(var["type"])
  File "D:\schick-data-gui-master\schick\reader.py", line 33, in sizeof
    varsize = varsize_tab[varstr]
KeyError: 'short {0,1}'

Leider habe ich gerade überhaupt keine Zeit, sonst würde ich mir Deinen Python-Code mal ansehen. Aber vielleicht kannst Du da schon was zu sagen.
Nutze übrigens die aktuellste GOG-Version von Schick. Wahrscheinlich liegt es daran, oder?
Vielen Dank fürs Testen! Tut mir Leid, ich bin vielleicht ein Kamel... folgendes Problem:

Das vorgestellte Programm braucht die von mir aktualisierte Datei symbols.h, aber der Pull Request ist ja noch gar nicht im Bright-Eyes-Repository drin: https://github.com/Henne/Bright-Eyes/pull/34

Das hier ist die symbols.h, die gebraucht wird: https://raw.githubusercontent.com/tuxor1.../symbols.h

Sobald Henne den pull request akzeptiert hat, stimmt dann auch die Anleitung in der README :pfeif:

Achso und zur GOG-Version: Ist die Englisch? Dann wird es sicher Probleme geben - aber das vorgestellte Tool sollte in jedem Fall funktionieren. Es zeigt dann eben nur falsche Daten an, weil die Offsets in der `symbols.h` nicht stimmen.
Danke, mit der neuen Symbols-Datei geht's wunderbar :ok:

Sieht so aus:
[Bild: 2017_01_21_14_35_55_schick.png]
(Nicht über die Qualität wundern, habe es runterskaliert; meine Auflösung liegt bei 2736x1824, da wäre das Original zu groß gewesen; Qualität im Original ist top).


Die GOG-Version gibt's auch auf Deutsch, daher klappt das Einlesen gut.
Danke für das Tool!
Top, du bist aber auch ein dankbarer Tester! :) Du hattest entweder schon numpy installiert oder du bist selbst auf die Idee gekommen, es zu installieren. Ich hatte nämlich ganz vergessen numpy als Abhängigkeit anzugeben.
Sieht toll aus! :)
--------
Warnung! Geschichte kann zu Einsichten führen und verursacht Bewusstsein!
Avatar by: Keven Law (CC BY-SA 2.0)




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