Darklands executable

Files with this format: "darkland.exe".

This is the main executable for Darklands.

Because this is a compiled binary executable, not much of the file is comprehensible without disassembling it. Still, many of the strings can be found, and quite possibly some arrays that indicate game flow logic (ie, movement between cards).

Many of the "arrays of pointers to X" appear to be for a segmented architecture, with segment:offset pointers (the high two bytes being the segment). Such arrays are simply described as "Segmented pointers, with segment=0x????", with the segment translated from big-endian.

Oftentimes, one array contains offsets into a number of semantically different string tables; in these cases the string tables will all be listed separately, but offsets will always be relative to the first entry of the first table.

Table of Contents

Offsets

from 0x17d0b0 to 0x17eb17
from 0x17eb18 to 0x17f66b
from 0x17f66c to 0x1872cf
from 0x1872d0 to 0x187626
from 0x187627 to 0x187cff
from 0x187d00 to 0x18a60e
from 0x18a60f to 0x18a863

Offsets

Offset: from 0x17d0b0 to 0x17eb17

0x17d0b0: unknown array[ 60 ] of dword
  • Segmented pointers, with segment=0x286b.
  • (TODO: verify) Offsets start at 0x355 and decrease linearly by 0x4 to 0x269, no exceptions.
0x17d1a0: unknown array[ 404 ] of dword
  • Segmented pointers, with segment=0x290e.
  • Offsets jump around in the approximate range of 0x1500 to 0x2aff.
0x17dfc0: unknown array[ 360 ] of dword
  • Segmented pointers, with segment=0x2caf.
  • This might correspond to a (TODO) set of .pic image filenames in a string table later on; maybe it's a copy?
  • Offsets are in blocks which decrease linearly by 0x4 each time.
    The first block runs from 0xb19 to 0xa49; the next from 0xd6d to 0xb1d; the next from 0xfc1 to 0xd71; the last from 0xfe5 to 0xfc5;
  • The four different blocks might indicate that there are four arrays, and the segments just happen to be the same.
0x17e560: unknown array[ 366 ] of dword
  • Segmented pointers, with segment=0x2dae.
  • Offsets jump around, but are generally in the range 0-0x5ff.

Offset: from 0x17eb18 to 0x17f66b

0x17eb18: unknown array[ 9 ] of dword
  • Segmented pointers, with segment=0x321e.
0x17eb3c: unknown array[ 2 ] of dword
  • Segmented pointers, with segment=0x39e8.
  • Offsets are: 0x18, 0x16.
0x17eb44: unknown array[ 2 ] of dword
  • Segmented pointers, with segment=0x39ea.
  • Offsets are: 0x0a, 0x0e.
0x17eb4c: unknown array[ 712 ] of dword
  • Segmented pointers, with segment=0x39eb.
  • Offsets jump around, but are generally in the range 0-0x5ff.

Offset: from 0x17f66c to 0x1872cf

[next]: array[ 30100 ] of byte [constant: 0x00]
Empty space.
[next]: unknown (1744 bytes)
  • There's some stuff near the top of this that looks like data.
  • TODO: look into this area.

Offset: from 0x1872d0 to 0x187626

0x1872d0: cardinals: array[ 4 ] of string (null-delimited)
The first four cardinal numbers.
  • "first", "second", "third", and "fourth"
0x1872ea: equippable_items: array[ 56 ] of string (null-delimited)
Equippable items.
  • Melee weapons, then ranged weapons, then "Potions", then vitals armour, then leg armour.
0x1874e2: array[ 3 ] of string (null-delimited)
Messages.
  • "You can't view ", " at this time.", and "Single file order is invalid. Will use default order."
  • The first two strings look like part of the same string; no idea why a null is there.
0x187537: array[ 60 ] of dword
Offsets into the above string tables, from to .
  • Segmented pointers, with segment=0x286b.
  • Although there are two string tables involved, all offsets are relative to the start of the first (cardinals).

Offset: from 0x187627 to 0x187cff

0x187627: debug_labels: array[ 35 ] of string (null-delimited)
Labels for debugging output
  • These are like "SmallGuySp[0]: " and "DyingBuf[0]: ". They look familiar: temporary battle files?
0x18781b: unknown (5 bytes) [constant: 0x00]
0x187820: unknown array[ 10 ] of word
  • These steadily increase, but the last is 0xffff (-1).
  • 0, 0x14, 0x7a, 0xe0, 0x146, 0x1ac, 0x212, 0x278, 0x2de, 0xffff.
0x187834: unknown (1228 bytes) [constant: 0x00]

Offset: from 0x187d00 to 0x18a60e

0x187d00: months: array[ 12 ] of string (null-delimited)
Months (full names).
0x187d56: copy_protection_words: array[ 20 ] of string (null-delimited)
Terms for the copy protection questions.
0x187e12: alchemy_submenu_items: array[ 4 ] of string (null-delimited)
Options given once an alchemical formula is chosen for mixing during a rest period.
  • All the "options" strings have a particular format: 0x8c, 0x20 (a space), the first letter, 0xff, the rest of the text, then 0x00 (null).
  • The 0xff is not a marker indicating "previous letter is the keyboard shortcut", but instead indicates where the program should stop highlighting the shortcut: moving the byte two more positions to the right in highlights an additional two characters.
0x187e5f: saved_game_submenu_items: array[ 3 ] of string (null-delimited)
Options given when on the list of saved games.
0x187e9e: unknown array[ 34 ] of string (null-delimited)
  • These do not reflect a single menu in its entirety, so may not actually be used.
  • Many of these are options given when creating a party or a character.
  • Others are phrases like "Only high Virtue can subdue the dragon", "Latin and Religious Training", and "You need a missile weapon".
  • Quite possibly these were just leftovers in one huge string table?
0x1881d9: attributes: array[ 7 ] of string (null-delimited)
Attributes.
0x188222: skill_abbrs: array[ 19 ] of string (null-delimited)
Skills (abbreviated to 14 characters).
0x1882f0: unknown array[ 5 ] of string (null-delimited)
  • The first is a standard "Return to main menu" option; the other three are for selecting colours and heraldry during character creation.
0x18833a: unknown string
  • "It is closed at night"
0x188350: occupations: array[ 37 ] of string (null-delimited)
Occupations available while creating a new character.
0x1884d3: global_reps: array[ 11 ] of string (null-delimited)
Descriptions of global reputation.
  • Goes from lowest ("Unknown") to highest ("Legendary Heroes").
0x188573: unknown array[ 16 ] of string (null-delimited)
  • Perhaps the names of demons?
  • "Enitharmon", "Sarcopteryx", "Odonanga vexans", "Eru damnosum" are some examples.
0x18862c: unknown array[ 36 ] of string (null-delimited)
  • Names of something?
  • "Alveig", "Gulveig", "Mimingus", "Thviti" are some examples.
  • Perhaps these are names of dwarves? "Gymer" sounds familiar...
0x18872c: unknown array[ 12 ] of string (null-delimited)
  • These seem to be city locations ("Blacksmith", "Armorer"), but contain some extra ones ("Jeweler", "Hospital"). Although jeweler was in the plans, I recall no hospitals in 15th century Germany...
0x18879a: family_backgrounds: array[ 37 ] of string (null-delimited)
Family backgrounds for a new character.
  • Ranges from wealthiest ("Nobility") to poorest ("Rural Commoners").
0x188801: monastic_hours: array[ 8 ] of string (null-delimited)
Latin names for the times of the day.
  • Starts with "Latins", ends with "Compline", as expected.
0x188838: compass directions: array[ 8 ] of string (null-delimited)
Compass directions.
  • Clockwise, from "North" to "Northeast", eventually to "Northwest".
0x188876: quest_givers: array[ 13 ] of string (null-delimited)
Places or individuals who may give quests.
  • This array is oddly "-1"-based; "Medici" (quest_givers[7]) is stored as 0x06 in event (found in dksaveXX.sav).
  • Possibly the first entry ("error") is just an extra string put in the right place, and memory was allocated starting with all bits on (so "-1" would translate to "error")?
  • TODO: update event structure to allow direct access to the byte involved, then update the above to point to it!
0x1888f2: skills: array[ 19 ] of string (null-delimited)
Skills (full text).
0x1889b4: local_reps: array[ 6 ] of string (null-delimited)
Descriptions of local reputation.
  • Goes from highest ("a local hero") to lowest ("hunted").
0x1889eb: jobs: array[ 25 ] of string (null-delimited)
Jobs a character can take while staying in a city inn.
  • Not all of these may be used; some such as "Fortune Teller" and "Canon's Aide" have never been seen. Of course, it is possible that very particular skills and attributes are required for those professions.
0x188af4: variables: array[ 67 ] of string (null-delimited)
Variables used in cards.
  • These are just the names; in files that use them, a "$" is prefixed to indicate that it is a variable.
  • Some of these may not be variables, or may not work when used. "ChosenOneName" is definitely used as a variable. "citySquare", "CityLocation", and "MonthName" are plausible. "whorehouse" and "imperialMint" are unlikely to even work.
  • See msgfiles for examples of the use of variables.
0x188dd2: titles: array[ 15 ] of string (null-delimited)
Titles for nobility.
  • TODO: confirm this is what it is?
  • These include "Vogt", "alte Herr", and "Schultheiss", and sound like titles.
0x188e71: male_first_names: array[ 110 ] of string (null-delimited)
First names for males.
  • Mostly in alphabetical order (at least the first letter is).
  • This table is used not only for suggested first names when creating a new character, but also for all other names in Darklands (raubritters, alchemists, quest givers, etc).
0x1891a0: female_first_names: array[ 90 ] of string (null-delimited)
First names for females.
  • Starts out in alphabetical order, but degenerates half way through, then starts back over with 'A' after 70 names. Possibly the developers ran out of names, and had to add some later?
0x18945f: surnames: array[ 107 ] of string (null-delimited)
Last names.
0x1897e6: designations: array[ 37 ] of string (null-delimited)
Designations (postfix titles).
  • Either clan names ("of Zollern") or descriptors ("the fat").
0x189993: unknown array[ 18 ] of string (null-delimited)
  • Regions, or lords, perhaps?
  • Examples include "Hoffman", "Stromer", "Muffel", "Wagner", "Welser".
0x189a20: faction_politics: array[ 3 ] of string (null-delimited)
Political opinions.
  • "oppose", "are undecided about", "support"
  • As the rebellion isn't part of the finished product, these are unused.
0x189a43: array[ 755 ] of dword
Offsets into the above string tables, from up to (but not including) .
  • Segmented pointers, with segment=0x290e.
  • Although there are many, many string tables involved, all offsets are relative to the start of the first (months).

Offset: from 0x18a60f to 0x18a863

0x18a60f: unknown array[ 146 ] of dword
  • Segmented pointers, with segment=0x09c0.
  • Offsets jump around in the approximate range of 0x1e2d to 0x2657.
0x18a857: unknown array[ 3 ] of dword
  • Segmented pointers, with segment=0x290e.
  • This (and above) might just be part of the preceding array: a global pointer index to all strings? Seems a bit long, but it's even stranger to have a table with just three entries...