• Jump To … +
    00-opening.c.md 01-makefile.mk.md 02-records.c.md 03-game.c.md 04-world.c.md 05-turn.c.md 06-battle.c.md 07-save.c.md
  • §

    2. Shared game records

    Complete file: src/CIV.H.

    Before reading the larger C files, we can read one complete header. CIV.H declares records used for terrain types, unit types, cities and individual units.

    The field names are inferred. Their widths and signed types preserve the DOS representation. Some names elsewhere in the source are awkward because identifier spelling can affect the old compiler’s allocation of variables and the linker’s order of global storage.

    Lines 1–11.

    /* Shared game records. Field names are inferred; sizes and signedness
     * preserve the DOS representation. */
    
    /* DGROUP 0282: 12 terrain types, 19 bytes each. */
    struct terrain_type {
        char name[12];
        unsigned char move_cost;
        signed char defense;        /* defense multiplier, in halves */
        unsigned char food, shields, trade, f5, f6;
    };
  • §

    Unit types

    A unit type contains properties shared by every unit of that type: its name, movement allowance, attack and defence strengths, cost and other values. Under the period compiler, each int occupies two bytes. The twelve-byte name and eleven integers therefore occupy 34 bytes.

    An individual unit stores a type index rather than repeating this record. We will see BATTLE.C use that index to obtain the attacker’s and defender’s strengths.

    Lines 12–27.

    /* DGROUP 112A: 28 unit types, 34 bytes each. */
    struct unit_type {
        char name[12];
        int obsolete_by;
        int domain;                 /* 0 land, 1 air, 2 sea */
        int moves;
        int fuel;
        int attack;
        int defense;
        int cost;
        int sight;
        int capacity;
        int role;
        int prereq;
    };
  • §

    Cities

    The city declaration accounts for all 28 bytes. food_box and shield_box hold accumulated food and production. workers combines the worked-tile mask with a specialist count, while the separate specialists word stores eight two-bit specialist types.

    name_id selects a city name, and routes holds three destination city indices. The two garrison bytes store unit types and veteran flags for units packed into the city record. Empty route and garrison slots use -1.

    name_id is stored as a char, with explicit unsigned casts when used as an index. Those casts matter on a compiler with signed plain characters.

    buildings is a bit mask stored in a long. The masks below identify a palace, city walls and SDI defence. Battle code can test a particular improvement without searching a list.

    Lines 28–51.

    /* DGROUP 70EC: 128 cities, 28 bytes each. */
    struct city {
        long buildings;             /* bit (n-1) set: improvement n is built */
        unsigned char x, y;
        char status;
        signed char size;
        char visible_size;
        char production;
        char trade;
        signed char owner;
        int food_box;               /* accumulated food */
        int shield_box;             /* accumulated production */
        long workers;               /* worked tiles 0..20, specialist count 26..31 */
        int specialists;            /* eight two-bit specialist types */
        char name_id;               /* unsigned index into place_name */
        char routes[3];             /* destination city indices, -1 if empty */
        char garrison[2];           /* unit type plus veteran bit 0x40, -1 if empty */
    };
    
    /* City improvement bits (improvement number minus one). */
    #define HAS_PALACE      0x00000001L
    #define HAS_CITY_WALLS  0x00000080L
    #define HAS_SDI         0x00010000L
  • §

    Individual units

    The twelve-byte unit record contains its location, type, remaining movement, status and other state. Movement uses thirds of a movement point. Fortified and veteran status occupy separate bits in the same byte.

    The signed next field links units in a stack and uses -1 as a sentinel. Its complete interpretation depends on the stack routines, which we will read in BATTLE.C. A declaration establishes the representation; those routines establish how the program changes it.

    Lines 52–68.

    /* DGROUP 81D4: 128 units per civilization, 12 bytes each. */
    struct unit {
        char status;                /* 0x08 fortified, 0x20 veteran */
        unsigned char x, y;
        signed char type;
        signed char moves;          /* remaining moves, in thirds */
        char fuel;
        char goto_x;
        char goto_y;
        char f8;
        signed char visibility;     /* one bit per civilization */
        signed char next;           /* next unit in the same stack, or -1 */
        char home_city;
    };
    
    #define UNIT_FORTIFIED  0x08
    #define UNIT_VETERAN    0x20
  • §

    ← Previous · Contents · Next →