summaryrefslogtreecommitdiff
path: root/doc/devel
diff options
context:
space:
mode:
Diffstat (limited to 'doc/devel')
-rw-r--r--doc/devel/aniformat37
-rw-r--r--doc/devel/battleinput13
-rw-r--r--doc/devel/blue-gas-giant-pal.pngbin0 -> 1980 bytes
-rw-r--r--doc/devel/checklist52
-rw-r--r--doc/devel/contentfiles28
-rw-r--r--doc/devel/debug74
-rw-r--r--doc/devel/dialogs74
-rw-r--r--doc/devel/files115
-rw-r--r--doc/devel/fontres75
-rw-r--r--doc/devel/generate155
-rw-r--r--doc/devel/gfxlib328
-rw-r--r--doc/devel/gfxres64
-rw-r--r--doc/devel/gfxversions60
-rw-r--r--doc/devel/glossary6
-rw-r--r--doc/devel/historical39
-rw-r--r--doc/devel/input126
-rw-r--r--doc/devel/livecd80
-rw-r--r--doc/devel/meleeteams56
-rw-r--r--doc/devel/musicres18
-rw-r--r--doc/devel/netplay/notes21
-rw-r--r--doc/devel/netplay/protocol336
-rw-r--r--doc/devel/netplay/states178
-rw-r--r--doc/devel/netplay/todo120
-rw-r--r--doc/devel/orggenerate133
-rw-r--r--doc/devel/pkgformat174
-rw-r--r--doc/devel/planetrender54
-rw-r--r--doc/devel/planetrotate31
-rw-r--r--doc/devel/planettopo92
-rw-r--r--doc/devel/plugins129
-rw-r--r--doc/devel/queues62
-rw-r--r--doc/devel/racestrings45
-rw-r--r--doc/devel/resources196
-rw-r--r--doc/devel/savefile149
-rw-r--r--doc/devel/sc1186
-rw-r--r--doc/devel/script117
-rw-r--r--doc/devel/sfx202
-rw-r--r--doc/devel/statefiles123
-rw-r--r--doc/devel/strtab76
-rw-r--r--doc/devel/threads165
-rw-r--r--doc/devel/timing66
-rw-r--r--doc/devel/versions42
-rw-r--r--doc/devel/voiceeffects20
42 files changed, 4117 insertions, 0 deletions
diff --git a/doc/devel/aniformat b/doc/devel/aniformat
new file mode 100644
index 0000000..65703a5
--- /dev/null
+++ b/doc/devel/aniformat
@@ -0,0 +1,37 @@
+For *.ani, *.sml, *.med, *.big files, each line is in following format:
+
+filename transparent_color colormap_index hotspot_x hotspot_y
+
+Filename is string, all others are int.
+
+filename
+ relative to the directory that .ani file is in.
+
+transparent_color
+ -2 : use PNG tRNS chunk transparency specification
+ -1 : transparent color is not used; not transparency in the image
+ (this behavior is enforced, even when tRNS is present)
+ 0 : for paletted images, transparent color index 0;
+ special for truecolor images, makes RGB (0,0,0) transparent
+ N>0 : for paletted images, transparent color index N;
+ meaningless for truecolor images
+
+colormap_index
+ -1 : colormaps are not used for the image
+ for paletted images, the palette from the image itself
+ will be used
+ N : for paletted images, the palette from the colormap N will
+ be used (so some .ct file somewhere defines the palette);
+ meaningless for truecolor images
+
+hotspot_x, hotspot_y
+ can both be positive of negative (or 0)
+ the position of the image on the screen will be
+ (draw_x - hotspot_x, draw_y - hotspot_y)
+ so a positive hotspot *usually* defines the logical center of
+ an image, and a negative hotspot *usually* defines the position
+ of an image within some larger compound image; there are of course
+ exceptions to this general rule
+
+This information is parsed in libs/graphics/sdl/3do_getbody.c
+
diff --git a/doc/devel/battleinput b/doc/devel/battleinput
new file mode 100644
index 0000000..19eea87
--- /dev/null
+++ b/doc/devel/battleinput
@@ -0,0 +1,13 @@
+The UQM source now has a concept of input context for melee control.
+
+A base InputContext structure is defined in battlecontrols.h. It defines
+the common fields of all the specific structures for each control method.
+
+Among these fields is a BattleInputHandlers structure, which defines the
+functions which handle various input actions for melee, such as frame input,
+selecting the next ship, and querying readiness at the end of a battle.
+
+Structures ComputerInputContext, HumanInputContext, and NetworkInputContext
+are "derived" from InputContext and can contain additional fields for the
+specific control method.
+
diff --git a/doc/devel/blue-gas-giant-pal.png b/doc/devel/blue-gas-giant-pal.png
new file mode 100644
index 0000000..0142f21
--- /dev/null
+++ b/doc/devel/blue-gas-giant-pal.png
Binary files differ
diff --git a/doc/devel/checklist b/doc/devel/checklist
new file mode 100644
index 0000000..23eed02
--- /dev/null
+++ b/doc/devel/checklist
@@ -0,0 +1,52 @@
+ -== Checklist for releases ==-
+
+
+Preparing for the release:
+- update the 'version' file in the content dir
+- update 'uqmversion.h'
+- update uqm.lsm (needs to be done after the content packages are generated)
+- test on all relevant platforms
+- make sure the documentation files are up-to-date
+ - Clean up the ChangeLog file
+ - generate Whatsnew from the ChangeLog
+ - doc/users/manual.txt
+ - doc/users/unixinstall
+ - Contributing
+ - AUTHORS
+ - INSTALL (and platform variants)
+ - unix man pages (in the future)
+
+
+Building the release:
+- make a final build in release mode
+- for the source archive:
+ - use a clean subversion checkout.
+ Just using 'svn update' and watching the output will not be
+ enough, as the files not in repository will be ignored.
+ - be sure to include content/version
+- Building the content packages:
+ - make sure the permissions in the .zip files are ok (0644 for data files
+ and 0755 for executables and dirs)
+ - don't compress .ogg files
+
+
+Announcing the release:
+- provide md5 sums for the released files
+- add a new entry for the release in the bugs database
+- update the home page
+ - http://sc2.sourceforge.net/index.php (News item)
+ - http://sc2.sourceforge.net/downloads.php
+ - http://sc2.sourceforge.net/info.php
+ - http://sc2.sourceforge.net/WhatsNew
+ - http://sc2.sourceforge.net/screenshots.php
+- send a mail to sc2-announce
+- set the forum 'news'
+- set the #sc2 irc channel topic
+- update the version number in http://uqm.stack.nl/wiki/Template:Uqmversion
+
+
+Moving on to the next version:
+- update the snapshots page so that content diffs are generated to the
+ most recent release
+- update doc/devel/versions with the release revision
+
diff --git a/doc/devel/contentfiles b/doc/devel/contentfiles
new file mode 100644
index 0000000..fdcd478
--- /dev/null
+++ b/doc/devel/contentfiles
@@ -0,0 +1,28 @@
+<race>/*icons.0.png
+ small (16x16) icon, used for
+ - picking the next ship for combat in Supermelee
+ - picking the next ship for combat in the full game
+ - the selection grid in the Supermelee fleet editor
+ - the escorts in the status window in the full game when not in
+ battle
+ - loading a game
+ - loading a melee fleet
+ - (others?)
+
+<race>/*icons.0.png
+ large icon with shadow, used for
+ - current selection in the right middle of the Supermelee fleet editor
+ - ship status window in battle
+ - (others?)
+
+<race>/*micon.0.png
+ large icon without shadow, used for
+ - images in the fleet when in the Supermelee fleet editor
+ - images in the fleet when in the shipyard
+ - current selection in the bottom right in the shipyard
+ - (others?)
+
+<race>/*micon.1.png
+ small icon, used for
+ - representing a battle group in a solarsystem
+
diff --git a/doc/devel/debug b/doc/devel/debug
new file mode 100644
index 0000000..22be628
--- /dev/null
+++ b/doc/devel/debug
@@ -0,0 +1,74 @@
+The file src/sc2code/uqmdebug.c and src/sc2code/uqmdebug.h contain various
+debugging functions, which are included in the binary when the game
+is built in debug mode.
+These functions can be called from anywhere in the code, though some
+require the game to be in a specific state.
+The function debugKeyPressed() in uqmdebug.c is called when the debug key
+is pressed. This function is a suitable place to put various debugging
+calls.
+There are also global variables 'debugHook' and 'doInputDebugHook',
+which can be set to a function to be called from the Starcon2Main thread.
+If if is set, 'debugHook' is called the next iteration of the main game loop
+(which will occur when the current activity (IP, HyperSpace, Communication,
+Battle) changes. The game will be in a well defined state here.
+If 'doInputDebugHook' is set, the function it is set to is called from
+doInput(), which is called all throughout the game.
+By setting one of these hooks, a function can be called from the Starcon2Main
+thread, thereby eliminating threading issues that may otherwise arrise.
+The debug key can be specified in user's override.cfg by adding a line
+with a text similar to "debug.1 = STRING:key F12".
+An interactive way to access various debugging code, similar to
+the uio debug mode (see below) is in the works.
+
+The most interesting debugging functionality available at the moment is
+listed below:
+- the function equipShip()
+ When this function is called, the SIS is equiped with various useful
+ modules (a possible Precursor Bomb is left in place), all
+ fuel tanks and crew pods are filled to the maximum, you are given
+ the maximum number of landers, and all possible lander shields are
+ installed.
+- the boolean variable instantMove
+ When this variable is set to TRUE, you can select a location on the
+ star map, and your HyperSpace/Quasispace coordinates will immediately
+ be set to them. Your realspace coordinates are not changed, so if you
+ are exploring a solar system, you'll only notice it when you leave to
+ HyperSpace.
+- the function showSpheres()
+ When this function is called, all spheres of influence of the active
+ races will be shown.
+- the function activateAllShips()
+ When this function is called, it will make all ships available for
+ purchase in the shipyard.
+- the function forwardToNextEvent()
+ Fast forwards the clock until the next event. If TRUE is given as an
+ argument, the HYPERSPACE_ENCOUNTER_EVENTs, which normally happen every
+ day, are skipped.
+- the function dumpEvents()
+ Outputs information on all scheduled events to a FILE.
+- the function dumpPlanetTypes()
+ Outputs information on all planet types to a FILE.
+- the function dumpUniverseToFile()
+ Outputs information on the universe to "./PlanetInfo". This function
+ should only be called from debugHook, as threading issues would otherwise
+ arrise.
+- the functions resetCrewBattle() and resetEnergyBattle()
+ This function, when called in melee, sets the current crew or energy
+ level of the bottom player's ship to its maximum. This works both in
+ Supermelee and in the full game.
+- the function uio_debugInteractive()
+ This function is not defined in sc2code/uqmdebug.h, but in libs/uio.h.
+ This function can interactively (tty-based) display information on
+ the state of the uio file system, and modifications can be made.
+- the function dumpStrings()
+ This function prints all the game strings, and is useful to check whether
+ the various string bases, as defined in gamestr.h, are correct.
+- the function debugContexts()
+ Prints and visually displays the various graphics contexts.
+ This function should only be called from doInputDebugHook(), as threading
+ issues would otherwise arrise.
+
+
+The first version of this document was created by Serge van den Boom,
+on 2004-05-15.
+
diff --git a/doc/devel/dialogs b/doc/devel/dialogs
new file mode 100644
index 0000000..91ca306
--- /dev/null
+++ b/doc/devel/dialogs
@@ -0,0 +1,74 @@
+This file describes how the conversation system works.
+
+Functions:
+
+DoResponsePhrase(RESPONSE_REF R, RESPONSE_FUNC response_func,
+ UNICODE *ConstructStr)
+ Adds a line to the list of remarks the player may choose from.
+ R - The index for the line in the .txt dialog file.
+ response_func - the function where to continue the dialog if this
+ remark was chosen.
+ ConstructStr - A user-constructed string to display. If it is 0,
+ the string from R is used; if it is 0, the string identified
+ by R is not displayed, but R is still used to report what choice
+ a player made.
+ In practice ConstructStr is always the result of a call
+ to construct_response() and R is set to the first part of
+ the constructed phrase.
+ Note: ConstructStr must still be valid after the function calling
+ DoResponsePhrase() returns, so it can't be on the stack.
+ Also, if there are multiple constructed responses at one
+ point in the dialog, they will need separate buffers.
+ In practice, a global buffer shared_phrase_buf is used when
+ only one buffer is required.
+ Note: In practice, when R is 0, the call is always made through the
+ macro Response()
+
+Response(RESPONSE_REF R, RESPONSE_FUNC response_func)
+ Macro that calls DoResponsePhrase() with 0 for ConstructStr.
+
+construct_response(UNICODE *buf, int R, ...)
+ Concatenates strings from a dialog .txt file with strings from
+ the source. The arguments after *buf are alternatingly an int R,
+ and a UNICODE * str, until either R is -1, or str is NULL.
+ buf - the destination
+ R - The index for the line in the .txt dialog file.
+ str - A UNICODE * string.
+
+NPCPhrase_cb(int index, TFB_TrackCB cb)
+ Display the NPC speech with identifier 'index' (and play the
+ associated sample). The callback function 'cb' is called when
+ the displaying is done (usually when the sample ends).
+ index - The index for the line in the .txt dialog file.
+ cb - the callback function to called when the line is over.
+ NULL indicates no callback function.
+
+NPCPhrase(int index)
+ Display the NPC speech with identifier 'index'.
+ This is a macro to NPCPrhase_cb().
+ index - The index for the line in the .txt dialog file, or
+ GLOBAL_PLAYER_NAME for the name of the captain,
+ GLOBAL_SHIP_NAME for the name of the flagship,
+ GLOBAL_PLAYER_LOCATION, for the player's hyperspace coordinates,
+ GLOBAL_ALLIANCE_NAME, for the name of the new alliance, or
+ a negative number for the absolute number as speech
+
+DISABLE_PHRASE(int index)
+ Mark a player line as not to be offered as a choice anymore. Not in
+ this conversion, nor in any future conversations.
+ index - The index for the line in the .txt dialog file.
+
+PHRASE_ENABLED(int index)
+ Check if a player phrase was formerly marked as not to be offered anymore
+ (by call to DISABLE_PHRASE).
+ index - The index for the line in the .txt dialog file.
+
+PLAYER_SAID(RESPONSE_REF said, RESPONSE_REF test)
+ Test whether a player the player reply 'said' is equal to the reply
+ 'test'.
+ said - the response that the player selected
+ test - a response to test 'said' against
+
+
+Initial version by Serge van den Boom, 2005-01-10
+
diff --git a/doc/devel/files b/doc/devel/files
new file mode 100644
index 0000000..ea4df38
--- /dev/null
+++ b/doc/devel/files
@@ -0,0 +1,115 @@
+battle.c
+border.c Draws the screen borders.
+build.c
+cleanup.c Cleanup routines for when the game is done.
+clock.c Manages the game clock.
+collide.c Process a collision of objects in combat.
+comm.c Handles communication with aliens.
+commglue.c Helper functions for communication with aliens.
+confirm.c Asks for confirmation on exit.
+credits.c Shows the credits after a victory.
+cyborg.c Handles combat AI.
+debug.c Debugging functions.
+demo.c Code for demo mode and game journal.
+displist.c Generic doubly linked list, which can keep its own pool
+ of preallocated link structures.
+ This generic list is used in various places throughout
+ the game source, but without preallocaded link structures.
+dummy.c
+encount.c Handles what to do when a player encounters an alien.
+fmv.c Handles video sequences.
+galaxy.c Starmap? Hyperspace background?
+gameinp.c
+gameopt.c Game options menu, including save and load selection.
+gendef.c Defines functions to be called for generating star systems.
+getchar.c Routines for entering characters with the joystick.
+globdata.c Sets up global data, creates the main ship, and the radar.
+gravity.c Maths regarding gravity in combat.
+gravwell.c Handles objects that generate gravity in combat.
+grpinfo.c Handles battle groups.
+hyper.c Handles hyperspace movement and actions.
+init.c Initialization of various game data.
+intel.c Passes input of computer or player along (?)
+intro.c Alternative functions for beginning and ending sequences
+ to those in fmv, unused. (PC version?)
+ipdisp.c Something with spheres of influence?
+load.c Loading a saved game.
+loadship.c Loading of ship resource data.
+master.c Preloading of all ships?
+melee.c All supermelee menu related code.
+misc.c Miscelaneous routines related to combat but not directly to
+ the fighting.
+oscill.c Code for the oscilloscope and speech sample progress slider.
+ (during communication with aliens)
+outfit.c Things related to outfiting the starship.
+pickmele.c Ship selection in Supermelee (not in Full Game)
+pickship.c Ship selection in Full Game (not in Supermelee)
+plandata.c Some const data relating stars and planets.
+process.c Some combat calculations.
+restart.c Main menu (start new, load, supermelee).
+save.c Saving of a game.
+settings.c The back end of the game options.
+setup.c Initialisations for key config, and loading of various
+ resources.
+ship.c Ship movement in combat.
+shipstat.c Routines for showing information about ships in combat
+ (name, crew, energy). (also status.c)
+shipyard.c Things related to selection of your companion ships.
+sis.c Drawing various game state information (ship, ship name,
+ captains name, hyperspace coordinates, date, melnorme credits,
+ landers, storage bays, crew, fuel, game menu)
+starbase.c Code for the Earth starbase.
+starcon.c Code for various events (Arilou portal, Kohr-Ah genocide,
+ Pkunk exodus, Thraddash attack Kohr-Ah, Ilwrath attack
+ Thraddash, Utwig+Supox attack Kohr-Ah, Mycon colonization
+ attempt, hyperspace ship spawned, zoqfot signal, zoqfot under
+ attack, Shofixti return, Spathi build shield, Arilou give
+ the Dnyarri to the Umgah, Yehat rebellion, Slylandro plague
+ worsening)
+starmap.c Code to find a star by it's coordinates and compose star names.
+state.c Saving and loading the temporary planet information,
+ like resource information.
+status.c Maintain and draw some information like the captain picture,
+ crew, energy. (also shipstat.c)
+tactrans.c Code for some additional combat events (explosions, dying,
+ new ship, ion trail, escape).
+trans.c Integer variant of atan2().
+utils.c Various auxiliary utils, code for pausing.
+velocity.c Velocity computation routines.
+weapon.c Routines for weapons fire in combat.
+
+
+build.h
+clock.h
+coderes.h
+collide.h
+commglue.h
+demo.h
+displist.h
+element.h
+encount.h
+globdata.h
+hyper.h
+ifontres.h
+igfxres.h
+ikey_con.h
+imusicre.h
+intel.h
+ires_ind.h
+isndres.h
+istrtab.h
+melee.h
+nameref.h
+races.h
+resinst.h
+respkg.h
+restypes.h
+sis.h
+sounds.h
+starbase.h
+starcon.h
+state.h
+units.h
+velocity.h
+weapon.h
+
diff --git a/doc/devel/fontres b/doc/devel/fontres
new file mode 100644
index 0000000..c70cb6c
--- /dev/null
+++ b/doc/devel/fontres
@@ -0,0 +1,75 @@
+This is the format for resources of type GFXRES (font variantion -- these
+have the extension .fon in the original source).
+
+All fonts have exactly 96 character descriptors starting with ASCII
+code 32 (space).
+
+Everything is stored MSB first unless otherwise specified.
+
+position length meaning
+ 4 0xffffffff if the file is uncompressed.
+ Otherwise, the file is compressed. When uncompressed, the
+ file complies with the rest of the format as described
+ below.
+ 4 Unused in file, always 0x00000000
+ 1 Font leading: the vertical distance between lines of text
+ in pixels.
+ 1 Max ascender: the maximum extent of the font upwards from
+ the baseline in pixels.
+ 1 Max descender: the maximum extent of the font downwards
+ from the baseline in pixels.
+ 1 Char spacing: the number of pixels in between the
+ successive characters.
+ 1 Kern amount: the number of pixels (out of char spacing)
+ that are used for kerning (explained later). Cannot be
+ more than char spacing.
+ 96 Kerning table: each byte corresponds to a character:
+ bits 0-1: right-hand side kerning mask
+ bits 2-3: left-hand side kerning mask
+ For each pair of chars printed the code figures out whether
+ the kerning should be used by taking the right mask of a
+ preceeding char and ANDing it with the left mask of a
+ succeeding char. If the result is 0, the Kern amount is
+ subtracted from Char spacing.
+ 3 alignment padding: aligns the following char descriptors
+ on 8-byte boundary.
+
+
+Then for all 96 chars:
+Char descriptors (these are frame descriptors from .ani format and some
+bits are most likely never used):
+ 4 Type index and flags (TypeIndexAndFlags)
+ Low 2 bytes:
+ bits 0-11 is the index of this frame
+ bits 12-15 are the type flags:
+ - bit 12-13:
+ - 0: (ROM_DRAWABLE)
+ - 1: Direct drawable (RAM_DRAWABLE)
+ - 2: (SCREEN_DRAWABLE)
+ - 3: (OVERLAY_DRAWABLE)
+ High 2 bytes (frame flags):
+ - bits 0-7: global PLUT to use (probably unused)
+ - bit 12: Frame is in cel format (DATA_HARDWARE)
+ - bit 13: (DATA_COPY aka DATA_SCREEN)
+ - bit 14: (DATA_PACKED)
+ - bit 15: (X_FLIP)
+ 4 Hot spot information (definition of (0, 0) in the image):
+ - low 2 bytes: x location of hot spot
+ (probably never used)
+ - high 2 bytes: y location of hot spot
+ This is the baseline of a character. The hotspot Y aligns
+ with the baseline of the text.
+ 4 Image bounds:
+ - low 2 bytes: Image width
+ - low 2 bytes: Image height
+ 4 Offset from beginning of the char descriptor for this
+ char to the beginning of the frame data.
+
+Frames:
+Then for all frames:
+ See "Frames" in gfxres.
+
+
+Initial version 2003-09-02, by Alex Volkov
+Frame descriptors and data from gfxres by Serge van den Boom
+
diff --git a/doc/devel/generate b/doc/devel/generate
new file mode 100644
index 0000000..a7108bb
--- /dev/null
+++ b/doc/devel/generate
@@ -0,0 +1,155 @@
+Note: this file (still) describes the way in which various things were
+generated in the original source. It is still useful, but there are some
+changes:
+- all of this functionality used to be handled through a single function,
+ either the function returned by GenerateIP(), or GenerateRandomIP().
+ Now, there is a structure GenerateFunctions, which contains a function
+ for each of the type of generation. See generate.h.
+- most functions don't use the global variables pSolarSysState, pOrbitalDesc,
+ and pPlanetDesc anymore. Instead, where these are needed, they are passed
+ along through a parameter.
+
+Files related to this system:
+- planets/generate.h
+ Defines GenerateFunctions.
+- planets/generate/gendefault.c
+ Default generation functions for when no specific one is specified.
+- planets/generate/gen*.c
+ Specific generation functions.
+- gendef.c
+ Glue code.
+
+This file should eventually be updated to reflect the new system.
+See the file 'orggenerate' for a description on how the system originally
+worked.
+
+============================================================================
+
+The various universe related game data is generated through a call
+to a solar system dependant generation function.
+This function is of type PLAN_GEN_FUNC, which is a typedef to
+ void (*PLAN_GEN_FUNC) (BYTE control)
+, where the 'control' argument specifies what type of data needs to be
+generated (one of GENERATE_PLANETS, GENERATE_MOONS, GENERATE_ORBITAL,
+INIT_NPCS, REINIT_NPCS, UNINIT_NPCS, GENERATE_MINERAL, GENERATE_ENERGY,
+GENERATE_LIFE, or GENERATE_NAME).
+
+The generation function for a solar system is kept in the 'GenFunc'
+field of the SOLARSYS_STATE structure.
+The SOLARSYS_STATE structure contains the data for a solar system.
+Currently, only one SOLARSYS_STATE structure is used at once, and
+the global variable pSolarSysState points to the current one.
+The GenFunc field is initialised in ExploreSolarSys(), to the value
+returned by GenerateIP() in sc2code/gendef.c. Usually, this will be
+'GenerateRandomIP', but for some specific solar systems a (pointer to a)
+custom generation function is returned. This depends on the value of
+CurStarDescPtr->Index, which contains values such as SOL_DEFINED,
+MELNORME0_DEFINED, AQUA_HELIX_DEFINED, etc (see sc2code/encount.h
+for the complete list).
+The starmap_array in sc2code/plandata.c specifies Index for all
+the solar systems in the game.
+
+Following are the possible values of the 'control' argument to the
+generation function, with the description of how the generation function
+acts on this. As the custom generation functions often only need to
+change one specific aspect of this game data generation, they will
+often call GenerateRandomIP() for the rest.
+StarBases are handled as if they were moons.
+
+GENERATE_PLANETS
+Pre: the global variable pSolarSysState points to the relevant solar system.
+Pre: the RNG is initialised with a seed to be used for the generation.
+ In practice, this seed is generated from the HyperSpace coordinates
+ of the solar system (which are hardcoded in sc2code/plandata.c),
+ followed by exactly one call to TFB_Random().
+Post: the RNG is in an undefined state.
+This function determines how many planets the system has, and fills in
+pSolarSysState->PlanetDesc[] for all planets, including the NumPlanets
+field, which determines how many moons the planet will have.
+It also sets the random seed that is used for data generated for this planet
+(including the number of moons), based on its coordinates (which are in the
+general case randomly determined themselves).
+
+GENERATE_MOONS
+Pre: the global variable pSolarSysState points to the relevant solar system,
+ which is initialised by a GENERATE_PLANETS call.
+Pre: the RNG is initialised with a seed to be used for the generation.
+ In practice, this seed is the seed stored by GENERATE_PLANETS
+ in the rand_seed field for the planet around which the moon(s) orbit.
+Pre: pSolarSysState->pBaseDesc points to the the relevant planet
+ of pSolarSysState->PlanetDesc[].
+Post: The RNG is in an undefined state.
+This function fills in pSolarSysState->MoonDesc[] for all moons around
+the planet pointed to by pSolarSysState->pBaseDesc.
+It also sets the random seed that is used for data generated for the moon
+based on its coordinates (which are in the general case randomly determined
+themselves).
+
+GENERATE_ORBITAL
+Pre: the global variable pSolarSysState points to the relevant solar system,
+ which is initialised by a GENERATE_PLANETS call.
+Pre: pSolarSysState->pOrbitalDesc points to the relevant planet or moon from
+ pSolarSysState->PlanetDesc[] or pSolarSysState->moonDesc[]
+Pre: the planet or moon that pSolarSysState->pOrbitalDesc points to
+ is initialised by a GENERATE_PLANETS or GENERATE_MOONS call.
+This function fills in pSolarSysState->SysInfo with the characteristics
+of the planet or moon, as seen from orbit.
+It also initialises the random seeds used for the generation of bio,
+minerals, and energy nodes on the surface.
+It also sets the discovery report string (if appropriate), initialises
+the surface graphics, and start the planet music.
+For specific planets, it may initiate race communication and possibly combat,
+and will only return once these are over.
+NB. The GENERATE_ORBITAL code should be split up into separate calculation
+and activation (graphics and music) parts.
+
+GENERATE_MINERAL, GENERATE_ENERGY, GENERATE_LIFE
+Pre: the global variable pSolarSysState points to the relevant solar system,
+ which is initialised by a GENERATE_PLANETS call.
+Pre: pSolarSysState->pOrbitalDesc points to the relevant planet or moon from
+ pSolarSysState->PlanetDesc[] or pSolarSysState->moonDesc[]
+Pre: the planet or moon that pSolarSysState->pOrbitalDesc points to
+ is initialised by a GENERATE_PLANETS or GENERATE_MOONS call.
+Pre: pSolarSysState->SysInfo is filled in by a GENERATE_ORBITAL call
+This function determines the properties of one mineral deposit, energy node,
+or life form on a planet or moon. On entry the caller sets
+pSolarSysState->CurNode to the index of the requested item. This function
+will then fill in pSolarSysState->SysInfo.PlanetInfo.CurPt,
+pSolarSysState->SysInfo.PlanetInfo.CurType, and in the case of minerals also
+pSolarSysState->SysInfo.PlanetInfo.CurDensity.
+In case pSolarSysState->CurNode is set to a value larger than or equal to
+the number of items of the requested kind ((COUNT) ~0 in practice), it is
+set to the real number of nodes. In this case the CurXXX fields of
+pSolarSysState->SysInfo.PlanetInfo are set to the values corresponding to
+the largest valid CurNode index, but should probably be considered to be
+undefined.
+These functions may also change the game state, cause the lander
+to take off (by setting InTransit to true in the active PLANETSIDE_DESC
+structure), or mark an energy node as not retrieved, usually in response
+to an item having been picked up since the last call. The game makes
+a GENERATE_MINERAL, GENERATE_ENERGY or GENERATE_LIFE call (whatever
+is relevant) for each item right after it is picked up.
+
+GENERATE_NAME
+Pre: pSolarSysState is set to the relevant solar system.
+Pre: The planet is initialised by GENERATE_PLANETS.
+Pre: pSolarSysState->pBaseDesc points to the relevant planet, which should
+ be in the system.
+This function fills GLOBAL_SIS (PlanetName) with the name of the planet
+pointed to by pSolarSysState->pBaseDesc.
+It also sets the GAME_STATE flag BATTLE_PLANET to the type of this planet,
+so that it will be shown appropriately in melee if combat follows.
+There is no generate function for the names of moons. The few moons that
+are named (those in the Sol system), are handled as a special case of
+the routines that prints these names (PrintCoarseScan3DO and
+PrintCoarseScanPC).
+
+INIT_NPCS
+REINIT_NPCS
+UNINIT_NPCS
+[TODO]
+
+
+Initial version of this document created by Serge van den Boom, on 2005-07-11.
+
+
diff --git a/doc/devel/gfxlib b/doc/devel/gfxlib
new file mode 100644
index 0000000..82ce6b7
--- /dev/null
+++ b/doc/devel/gfxlib
@@ -0,0 +1,328 @@
+ The TFB Graphics Libraries
+
+ Initial documentation by Michael Martin, 4 Feb 2003
+
+The graphics system in UQM has three major subsystems:
+
+- The "legacy" system, which most of the core code uses. This
+ involves the foo_blt () routines in 3do_blt.c, and the data
+ types CONTEXT, FRAME, DRAWABLE, and possibly others. I'm
+ less familiar with this code, and want to eradicate as much of it as
+ I can, but for now, its lowest level has been rewritten as direct
+ calls to:
+
+- The TFB_Draw* commands, documented below in great detail. These
+ routines deal with the datatype TFB_Image, and the more primitive
+ TFB_Canvas. They also support drawing to one of several 'screens',
+ but since only one thread should be allowed to touch the screen,
+ the TFB_DrawScreen routines end up constructing inputs to:
+
+- The DCQ/DrawCommand library. This is a ring queue with commands for
+ rendering graphics on the actual screen. It interacts to some
+ degree with the CONTEXT datatype, but otherwise is defined entirely
+ in terms of TFB_Images and TFB_Canvases.
+
+ THE LEGACY LIBRARY
+ --------------------
+
+The datatypes the code uses directly are CONTEXT, FRAME, and FONT, all
+of which are really pointers to void. Pointers to those are PCONTEXT,
+PFRAME, and PFONT. Then there's DRAWABLE, which is a DWORD, and its
+pointer type PDRAWABLE. (These are defined in sc2code/libs/gfxlib.h.)
+I'm not sure how DRAWABLE values are transformed into actual drawable
+entities.
+
+The full structures for these are in various files in
+sc2code/libs/graphics.
+
+context.h: defines CONTEXT_DESC and PCONTEXT_DESC (and the equivalent
+ CONTEXTPTR -- insert various sorts of incomprenshible
+ muttering here),
+
+display.h: defines a DISPLAY_INTERFACE and PDISPLAY_INTERFACE type (as
+ well as a global _pCurDisplay).
+
+drawable.h: defines FRAME_DESC and DRAWABLE_DESC, and the pointer
+ types PFRAME_DESC and PDRAWABLE_DESC. FRAME_DESC has a
+ TFB_Image pointer as a member. DRAWABLE_DESC currently
+ still uses a rather annoying technique where the last
+ member of a struct is a 1-element array, more memory than
+ that is actually allocated, and the array's bounds are
+ deliberately overflowed to get at multiple frames.
+
+font.h: defines FONT_DESC and PFONT_DESC.
+
+(Details on how all these data types work is forthcoming.)
+
+ THE TFB_DRAW LIBRARY
+ ----------------------
+
+The TFB_Draw commands have a single header file:
+sc2code/libs/graphics/tfb_draw.h. This file declares the following
+data types:
+
+SCREEN: This is an enum, naming the various screens that the DrawCmd
+ library can draw to. Valid values at present are
+ TFB_SCREEN_MAIN, TFB_SCREEN_EXTRA, and TFB_SCREEN_TRANSITION.
+ These correspond to various objects that are of type TFB_Canvas.
+
+ (The maximal number of screens is provided by a bogus last
+ element, TFB_GFX_NUMSCREENS. Keep that as the last element
+ and the allocators will operate properly regardless of any
+ screens you may later want to add.)
+
+TFB_Canvas: This is, for the purposes of most of the code, a void
+ pointer. The implementations of TFB_DrawCanvas commands
+ cast them to the appropriate type. (The only
+ implementation of these commands casts them to
+ SDL_Surface*.)
+
+TFB_Palette: Four UBYTES, r, g, b, and 'unused'. This is designed at
+ present to be directly castable to SDL_Color, which most
+ things do. We should probably do something about that at
+ some point.
+
+TFB_Image: The most important image structure. This has two
+ TFB_Canvases (one for the 'core' image, one for a scaled
+ version of it), a pointer to a TFB_Palette array, a
+ colormap index, a scaling constant, a Mutex from the
+ threading library (to ensure internal consistency if
+ multiple threads are doing stuff), and a 'dirty bit' which
+ means that, if the image is scaled, the ScaledImg needs to
+ be recomputed.
+
+TFB_DrawScreen
+--------------
+
+When you wish to draw graphics directly on the screen, you call these
+routines, which enqueue the DrawCommands:
+
+----
+
+void TFB_DrawScreen_Line (int x1, int y1, int x2, int y2,
+ int r, int g, int b,
+ SCREEN dest);
+
+Draws a line from (x1, y1)-(x2, y2) of a color specified by r, g, and
+b on the specified screen.
+
+We have a known bug here in that if a corner of one of these lines is
+outside of the context's clipping rectangle, the slope of the line may
+change.
+
+----
+
+void TFB_DrawScreen_Rect (PRECT rect,
+ int r, int g, int b,
+ SCREEN dest);
+
+Draws a (filled) rectangle with the specified color on the destination
+screen. PRECT is part of the legacy library.
+
+void TFB_DrawScreen_Copy (PRECT r, SCREEN src, SCREEN dest);
+
+Copies data between screens. The PRECT defines the region to copy.
+This can be handy in saving and restoring background information.
+
+----
+
+void TFB_DrawScreen_Image (TFB_Image *img,
+ int x, int y,
+ BOOLEAN scaled,
+ TFB_Palette *palette,
+ SCREEN dest);
+
+void TFB_DrawScreen_FilledImage (TFB_Image *img,
+ int x, int y,
+ BOOLEAN scaled,
+ int r, int g, int b,
+ SCREEN dest);
+
+These two routines draw images. img, x, and y are all straightforward
+(x and y refer to the upper left of the image), and scaled indicates
+whether or not the NormalImg or ScaledImg should be used, and dest
+names the target screen.
+
+For TFB_DrawScreen_Image, the 'palette' argument refers to a
+256-element array of TFB_Palette that describes the palette to use.
+(The default is cached in TFB_Image itself.) Various techniques are
+used to cache the palette values to keep spurious palette-switch
+commands from flooding the DrawCmd queue. However, switching the
+palette many times per frame is likely to seriously degrade
+performance.
+
+TFB_DrawScreen_FilledImage draws every non-transparent pixel in img in
+the color specified by r, g, b. (Fonts and some menus do this.)
+
+----
+
+void TFB_DrawScreen_WaitForSignal (void);
+
+Puts this thread to sleep until all commands queued to this point are
+executed. Mostly used to keep from spamming the DrawCmd queue, and to
+ensure proper operation of the next two routines.
+
+----
+
+void TFB_DrawScreen_CopyToImage (TFB_Image *img,
+ PRECT lpRect,
+ SCREEN src);
+
+Load the pixels from the rectangle lpRect in screen src into img. If
+you're actually working with the pixels directly, you'll want to do a
+TFB_DrawScreen_WaitForSignal () to ensure the image has actually been
+updated. (If you're just passing it to other TFB_DrawScreen commands,
+that's unnecessary, because ordering within a thread is guaranteed.)
+
+----
+
+void TFB_DrawScreen_DeleteImage (TFB_Image *img);
+
+Deallocates all memory associated with img. This REALLY doesn't
+belong here. It should be a TFB_DrawImage command, with a requirement
+that you WaitForSignal lfirst.
+
+----
+
+TFB_DrawImage
+-------------
+
+These routines are similar to a subset of the TFB_DrawScreen commands,
+except that instead of drawing on the screen at some later time, they
+draw directly and immediately onto a TFB_Image. The arguments all
+mean the same things as they did for TFB_DrawScreen.
+
+----
+
+void TFB_DrawImage_Line (int x1, int y1, int x2, int y2,
+ int r, int g, int b,
+ TFB_Image *dest);
+
+void TFB_DrawImage_Rect (PRECT rect,
+ int r, int g, int b,
+ TFB_Image *image);
+
+void TFB_DrawImage_Image (TFB_Image *img,
+ int x, int y,
+ BOOLEAN scaled,
+ TFB_Palette *palette,
+ TFB_Image *target);
+
+void TFB_DrawImage_FilledImage (TFB_Image *img,
+ int x, int y,
+ BOOLEAN scaled,
+ int r, int g, int b,
+ TFB_Image *target);
+
+----
+
+TFB_DrawCanvas
+--------------
+
+These routines are, quite literally, identical in every way to the
+TFB_DrawImage routines, except that they draw on TFB_Canvases instead.
+They are defined in graphics-library-specific locations. There is, at
+present, only one implementation of these, in
+libs/graphics/sdl/canvas.c.
+
+void TFB_DrawCanvas_Line (int x1, int y1, int x2, int y2,
+ int r, int g, int b,
+ TFB_Canvas dest);
+
+void TFB_DrawCanvas_Rect (PRECT rect,
+ int r, int g, int b,
+ TFB_Canvas image);
+
+void TFB_DrawCanvas_Image (TFB_Image *img,
+ int x, int y,
+ BOOLEAN scaled,
+ TFB_Palette *palette,
+ TFB_Canvas target);
+
+void TFB_DrawCanvas_FilledImage (TFB_Image *img,
+ int x, int y,
+ BOOLEAN scaled,
+ int r, int g, int b,
+ TFB_Canvas target);
+
+----
+
+Creation and Destruction of TFB_Images, TFB_Canvases, and TFB_Palettes
+----------------------------------------------------------------------
+
+Various commands exist for creating and destroying the TFB_Draw data
+types. The concept of "ownership" is critical here. If a data object
+owns a pointer inside of it, that pointer's referent is deallocated
+when the data object is deallocated. If a pointer variable owns its
+referent, it's permissible to delete it.
+
+TFB_Canvas and TFB_Palette are primitives. TFB_Image owns NormalImg,
+ScaledImg, and Palette, and will delete them when it is itself
+deleted.
+
+That said, here are the routines:
+
+---
+
+TFB_Image *TFB_DrawImage_New (TFB_Canvas canvas)
+
+Creates a new TFB_Image, which the caller then owns. The caller must
+own the canvas, and transfers ownership of that canvas to the image.
+The Palette value is automatically created (and the image owns it);
+ScaledImg will be NULL until you scale the image and draw it to the
+screen.
+
+---
+
+void TFB_DrawImage_Delete (TFB_Image *image)
+
+Deletes the image, and all non-NULL components. You must own the
+image you delete.
+
+---
+
+TFB_Canvas TFB_DrawCanvas_New_TrueColor (int w, int h, BOOLEAN has_alpha);
+
+TFB_Canvas TFB_DrawCanvas_New_Paletted (int w, int h,
+ TFB_Palette *palette,
+ int transparent_index);
+
+These create new TFB_Canvases, which the caller will then own. Width
+and height are straightforward. The TrueColor variant produces Canvases
+with the same color depth and pixel format as the screen. The
+has_alpha flag indicates whether or not the canvas has an alpha
+channel.
+
+The Paletted variant produces 8-bit paletted canvases. The palette
+argument is optional (it can be NULL, in which case you'll need to set
+it later - TFB_Images tend to do this when drawn), as is the
+transparent_index (if -1, there is no transparency; otherwise, it's
+the index of the transparent color).
+
+---
+
+TFB_Canvas TFB_DrawCanvas_ToScreenFormat (TFB_Canvas canvas);
+
+Returns a canvas that, if possible, matches the graphics configuration
+of the screen. You must own the source canvas. If the conversion is
+possible, it makes the conversion, deletes its argument, and returns
+the converted version; if conversion is not possible, the canvas is
+returned intact.
+
+Regardless of success or failure, the caller owns the result.
+
+---
+
+TFB_Palette *TFB_DrawCanvas_ExtractPalette (TFB_Canvas canvas);
+
+Allocates and returns a 256-entry TFB_Palette array that describes the
+palette of the canvas, or returns NULL if the canvas is true-color.
+If the result is non-NULL, the caller owns the result. The caller
+need not own canvas.
+
+
+ DRAWCMD LIBRARY
+ -----------------
+
+Documentation yet to be written. UQM code shouldn't really mess with
+the DrawCmd library directly.
diff --git a/doc/devel/gfxres b/doc/devel/gfxres
new file mode 100644
index 0000000..d0b30bb
--- /dev/null
+++ b/doc/devel/gfxres
@@ -0,0 +1,64 @@
+This is the format for resources of type GFXRES (these have the extension
+.ani in the original source).
+
+Everything is stored MSB first unless otherwise specified.
+
+position length meaning
+ 4 0xffffffff if the file is uncompressed.
+ Otherwise, the file is compressed. When uncompressed, the
+ file complies with the rest of the format as described
+ below.
+ 4 Unused in file, always 0x00000000
+ 4 FlagsAndIndex:
+ bits 0-11: 1 less than the number of frames in this
+ graphics resource
+ bits 12-15: flags:
+ - bit 0: (WANT_MASK)
+ - bit 1: (WANT_PIXMAP)
+ - bit 2: (WANT_COMPRESSED)
+ - bit 3: (DOUBLE_RES)
+ bits 16-31: unknown (0x0000)
+
+Frame descriptions:
+Then for all frames:
+ 4 Type index and flags (TypeIndexAndFlags)
+ Low 2 bytes:
+ bits 0-11 is the index of this frame
+ bits 12-15 are the type flags:
+ - bit 12-13:
+ - 0: (ROM_DRAWABLE)
+ - 1: Direct drawable (RAM_DRAWABLE)
+ - 2: (SCREEN_DRAWABLE)
+ - 3: (OVERLAY_DRAWABLE)
+ High 2 bytes (frame flags):
+ - bits 0-7: global PLUT to use
+ - bit 12: Frame is in cel format (DATA_HARDWARE)
+ - bit 13: (DATA_COPY aka DATA_SCREEN)
+ - bit 14: (DATA_PACKED)
+ - bit 15: (X_FLIP)
+ 4 Hot spot information (definition of (0, 0) in the image):
+ - low 2 bytes: x location of hot spot
+ - high 2 bytes: y location of hot spot
+ 4 Image bounds:
+ - low 2 bytes: Image width
+ - low 2 bytes: Image height
+ 4 Offset from beginning of the frame description for this
+ frame to the beginning of the frame.
+
+Frames:
+Then for all frames:
+ If DATA_HARDWARE is set in the flags for this frame:
+ 4 Size of image data
+ ? .cel image data
+ If DATA_PACKED is set in the flags for this frame: (from 3do/imageint.c)
+ for every line in the image (bounds.height lines):
+ 2 number of bytes used to encode this line
+ The actual number of bytes is computed like so:
+ (number-of-bytes + 2) * 4
+ a number of packets of this format:
+
+
+
+Initial version 2002-10-22, by Serge van den Boom
+
+
diff --git a/doc/devel/gfxversions b/doc/devel/gfxversions
new file mode 100644
index 0000000..d82706e
--- /dev/null
+++ b/doc/devel/gfxversions
@@ -0,0 +1,60 @@
+Chnages between DOS and 3DO graphics.
+[Unless stated otherwise, UQM does things 3DO way]
+
+----------------------------------------------------------------------
+Melee
+----------------------------------------------------------------------
+1. Minor ship small icon changes
+Icon offset horz by 1 pixel: VUX, ZoqFot, Melnorme, Supox
+Facelifted: Utwig
+
+2. Ship/weapon rendering changes
+*Yehat*
+On DOS, Yehat shield was a set of separate shield-only images which
+were composited with the ship; on 3DO, the shield images already include
+the ship.
+*Umgah*
+On DOS, Umgah cone was a composite of a cone mask + spritz images;
+on 3DO, cone images multiplied 3x and are already a combination of
+cone + spritz.
+*Blackurq* [Kohr-Ah]
+Ship images were regenerated for 3DO with a light source
+at a different position (so the angle is diff). This improved the overall look
+of the ship, especially frame 14, which was simply ugly on DOS.
+And, of course, the FRIED is blue on 3DO and was yellow on DOS.
+*Chenjesu*
+Not really a change, med.14 frame has bad transparency info on DOS.
+*Utwig*
+DOS has apparently derelict ship frames (16-18).
+HYPOTHESIS: ship special was originally intended to be some entirely
+different.
+*Sa-Matra*
+The captain portrait is bigger in UQM (same size on DOS and 3DO).
+
+4. Misc
+lbm/stars has an extra frame (2) in 3DO, afaik, it is not used.
+
+5. Planet images
+On DOS, planet images were paletted, and there were 14 topographical types
+(2 were identical) with ~60 palettes; on 3DO, images are truecolor (except
+for Shielded planet), and the 2 identical topographies have been fixed (so
+they are different now).
+
+----------------------------------------------------------------------
+Inter-planetary (IP)
+----------------------------------------------------------------------
+1. Planets
+On DOS, IP planets were all pre-generated (all phases, colors, sizes);
+On 3DO, planet phases and size are pre-generated and rendered using colormaps
+that define planet color.
+
+2. Many changes in Planet Rotation (scan view)
+
+3. Suns
+On DOS, suns have different colors; on 3DO, they are all yellow; UQM has
+been patched to render suns in different colors like DOS.
+
+----------------------------------------------------------------------
+Misc
+----------------------------------------------------------------------
+1. SIS engine color was green-yellow on DOS and is red on 3DO
diff --git a/doc/devel/glossary b/doc/devel/glossary
new file mode 100644
index 0000000..2ecbba5
--- /dev/null
+++ b/doc/devel/glossary
@@ -0,0 +1,6 @@
+Abbreviations used in the code:
+
+IP interplanetary
+NPC non-player character
+SIS Super-Integrated-Starship (the flagship)
+
diff --git a/doc/devel/historical b/doc/devel/historical
new file mode 100644
index 0000000..63697ff
--- /dev/null
+++ b/doc/devel/historical
@@ -0,0 +1,39 @@
+This file is intended as a place to document historically interesting
+curiosities in the UQM source and content, which have been deleted from
+the current source/content tree.
+
+This file is probably not complete.
+
+
+== .res files ===
+
+The Star Control source code contained files with the extension .res, which
+contained a description of the packages (.pkg or .ndx) files to be generated.
+
+There were .res files for each ship and each race which you can communicate
+with. These files 'included' the file 'star3do.res', which itself included
+'star3do.typ'.
+
+There were also header files icode.h, igfxres.h, imusicre.h, isndres.h,
+istrtab.h, resinst.h, respkg.h and restypes.h in each of the ship and comm
+directories, which defined a few resource constants, which were presumably also
+generated from these .res files.
+
+
+== Outtake not taken out ==
+
+There was an outtake accidentally left in the original speech for the Druuge.
+It can still be found at
+ http://sc2.svn.sourceforge.net/viewvc/*checkout*/sc2/trunk/sc2/content/comm/druuge/druug011.ogg?revision=133&pathrev=1113
+
+
+== Original title screen and menu ==
+
+The original title screen -- which included the text 'Star Control' and
+'Accolade' and could hence not be used in UQM -- can be found at
+ http://sc2.svn.sourceforge.net/viewvc/sc2/trunk/sc2/content/lbm/title.tga?revision=6&pathrev=6
+The original main menu (which did not include 'setup' or 'quit' options)
+can be found at
+ http://sc2.svn.sourceforge.net/viewvc/sc2/trunk/sc2/content/lbm/newgame0.tga?revision=6&pathrev=6
+
+
diff --git a/doc/devel/input b/doc/devel/input
new file mode 100644
index 0000000..ca48e00
--- /dev/null
+++ b/doc/devel/input
@@ -0,0 +1,126 @@
+Input system notes
+
+Code that reads the input state defines a routine that goes through
+the DoInput routine. This is handled in a pseudo-OOP style.
+
+An "INPUT_STATE_DESC" has the following members:
+
+BOOLEAN (*InputFunc) (PVOID pInputState);
+COUNT MenuRepeatDelay;
+
+Although a "PVOID", pInputState has to be safely castable to
+INPUT_STATE_DESC. There are various "subclasses" that are used for
+this purpose throughout the code. They are also pased to the first
+argument of DoInput.
+
+The InputFunc returns TRUE if it still will be keeping control next
+frame.
+
+MenuRepeatDelay is an "internal" variable for making keyrepeat work
+right.
+
+"Subclasses":
+
+MENU_STATE - in starbase.h. The "pMenuState" global is usually the
+element referenced. This is used by:
+
+ encount.c: DoSelectAction
+ gameopt.c: DoGameOptions, DoSettings, DoTextEntry, DoNaming,
+ DoQuitMenu, DoPickGame
+ outfit.c: DoOutfit
+ pickship.c: DoPickBattleShip
+ restart.c: DoRestart
+ shipyard.c: DoModifyShips, DoShipYard
+ starbase.c: DoStarBase
+
+ cargo.c: DoDiscardCargo
+ devices.c: DoManipulateDevices
+ lander.c: DoPlanetSide
+ pstarmap.c: DoMoveCursor, DoFlagshipCommands
+ roster.c: DoModifyRoster
+ scan.c: DoScan, PickPlanetSide
+
+VIDEO_INPUT_STATE - in vidplayer.c. Used by TFB_DoVideoInput.
+
+ENCOUNTER_STATE - in comm.c. Used by DoCommunication.
+
+MELEE_STATE - in melee.h. Used by DoPickShip, DoLoadTeam, DoEdit, DoMelee.
+
+The game logic itself that uses DoInput treats it as a stack of state
+machines. The "current state" is in the InputFunc field of the
+argument.
+
+The state machines are (with the calls that initialize and allocate them):
+
+InitCommunication: DoCommunication
+DoMenuOptions, ExploreSolarSys: DoFlagshipCommands <-> DoDiscardCargo
+ <-> DoManipulateDevices
+Roster: DoModifyRoster
+DoMelee <-> DoEdit <-> DoLoadTeam <-> DoPickShip
+VisitStarBase: DoStarBase <-> DoOutfit <-> DoInstallModule
+ <-> DoShipyard <-> DoModifyShips
+DoStarMap: DoMoveCursor
+GameOptions: DoGameOptions <-> DoNaming <-> DoSettings <-> DoQuitMenu
+ <-> DoPickGame
+GetArmadaStarShip: DoPickBattleShip
+StartGame: DoRestart
+ScanSystem: DoScan <-> PickPlanetSide <-> DoPlanetSide
+InitEncounter: DoSelectAction
+TFB_VideoInput: TFB_DoVideoInput
+
+These are called from the following points:
+
+InitCommunication: Called by the outtakes, the starbase, and the gen*
+ files; generally anywhere where you need to
+ transfer over to a conversation sequence.
+ RaceCommunication () is the toplevel call for
+ starcon.c.
+
+DoMenuOptions: Called by the postprocess operation for the sis_ship.
+
+ExploreSolarSys: Called by Starcon2Main.
+
+VisitStarBase: Called by Starcon2Main.
+
+DoStarMap: Called internally by DoFlagshipCommands.
+
+GameOptions: Called internally by DoOutfit, DoShipyard,
+ DoSelectAction, and DoFlagshipCommands. Basically
+ handles the GAME menu wherever it appears.
+
+GetArmadaStarShip: Called internally by
+ GetEncounterStarShip. UninitShips calls
+ GetEncounterStarShip, apparently to do cleanup.
+ Everyone else calls GetNextStarShip. This is done
+ by the Battle() routine, and by the new_ship
+ function, which is assigned as a "death_func" for
+ normal ships, and a "preprocess_func" for dead
+ ships.
+
+StartGame: Called by Starcon2Main.
+
+ScanSystem: Called by DoFlagshipCommands
+
+InitEncounter: Called by InitCommunication when the player has an option.
+
+TFB_VideoInput: UQM's game logic will reach it by calling DoFMV.
+
+Starcon2Main
+------------
+
+This is a loop for the game. Right now I just have a list of
+top-level calls, and a list of checks made against
+GLOBAL(CurrentActivity). The actual significance of these things
+comes later.
+
+Activities: CHECK_LOAD, START_ENCOUNTER, CHECK_ABORT,
+ IN_INTERPLANETARY, START_INTERPLANETARY, WON_LAST_BATTLE,
+ CHECK_RESTART, IN_HYPERSPACE
+
+Game states: CHMMR_BOMB_STATE, GLOBAL_FLAGS_AND_DATA, KOHR_AH_KILLED_ALL
+
+Functions: Logo(), StartGame(), VisitStarBase(), RaceCommunication(),
+ ExploreSolarSys(), Battle(). Note that Battle() here is
+ actually for hyperspace travel. Super Melee combat is
+ handled in DoMelee, and full-game combat is handled by
+ EncounterBattle, called by InitCommunication.
diff --git a/doc/devel/livecd b/doc/devel/livecd
new file mode 100644
index 0000000..a3e3bb9
--- /dev/null
+++ b/doc/devel/livecd
@@ -0,0 +1,80 @@
+This file contains notes about considerations for developing a live CD
+for UQM.
+
+
+Information on creating boot CD's:
+- http://www.geocities.com/potato.geo/bootlinuxcd.html
+- man mkisofs
+- http://linuxfromscratch.org/~jhuntwork/livecd/
+- http://www.tldp.org/HOWTO/Bootdisk-HOWTO/
+
+
+Desirable features:
+- Both Linux native mode (when booting directly from the CD),
+ an MS Windows autorun. And perhaps even MacOS boot.
+- install from the CD (for Windows)
+- Support saving
+
+
+- Needed software:
+ - boot loader
+ syslinux: ftp://ftp.kernel.org/pub/linux/utils/boot/syslinux/
+ - init (simpleinit?)
+ - libc (including libpthread) (uClibc)?
+ - libSDL
+ - libSDL_image
+ - libpng (needed for libSDL_image)
+ - libvorbisfile
+ - libvorbis (for libvorbisfile)
+ - libogg (for libvorbis)
+ - libmikmod
+ - libm (for libvorbis)
+ - libz (for zipped content)
+ - syslogd+klogd?
+
+ Some audio library:
+ - libasound (prefered)
+
+ Some graphics output: one of
+ - x11 (larger than necessary)
+ - nanox
+ - fbcon (may be the best solution)
+ - directfb
+ - svgalib (directly accesses the VGA card. No acceleration support)
+ (may be the most portable)
+ Having hardware acceleration support may be useful.
+
+ For basic debugging:
+ - sulogin
+ - sash or busybox (minimal features)
+
+ For hardware detection:
+ - udev
+ - ...
+
+- Other needed files:
+ - boot scripts
+ - /etc/ld.so.conf
+ - ...
+
+- Sources
+ Sources must be provided in some way (check the licenses of the
+ dependencies).
+
+- Warranty disclaimer on boot
+
+
+For saving:
+- USB memory stick and other memory devices
+- Windows hard drive (where to put the files?)
+- Linux hard drive (where to put the files?)
+- Floppies? Probably not worth it.
+
+
+
+Tools for testing before burning:
+- vmware
+- QEMU (http://fabrice.bellard.free.fr/qemu/)
+
+
+
diff --git a/doc/devel/meleeteams b/doc/devel/meleeteams
new file mode 100644
index 0000000..524f2cf
--- /dev/null
+++ b/doc/devel/meleeteams
@@ -0,0 +1,56 @@
+This file describes the binary file format for SuperMelee teams.
+The saving and loading is handled in sc2code/loadmele.c.
+
+This file format will be replaced by a human-readable format in the future.
+
+A SuperMelee team consists of the following data:
+ struct TEAM_IMAGE {
+ 0 - 13 uint8_t ShipList[MELEE_FLEET_SIZE];
+ /* Originally 6*2 ships, now 7*2 */
+14 - 68 char TeamName[MAX_TEAM_CHARS + 1 + 24];
+ /* \0-terminated */
+ };
+
+The file melee.cfg contains:
+ 0 - 0 Player Control for the bottom player
+ One of:
+ 1 - Human controlled
+ 6 - Computer controlled
+ 8 - Network controlled (added later)
+ or'ed with one of:
+ 16 - Standard computer control rating (was 8 originally)
+ 32 - Good computer control rating (was 16 originally)
+ 64 - Awesome computer control rating (was 32 originally)
+ 1 - 69 TEAM_IMAGE for the top player, as described above
+70 - 70 Player Control for the top player, as byte 0
+71 - 139 TEAM_IMAGE for the bottom player, as described above
+Note the mixed up order for top and bottom player.
+
+The entries in ShipList are:
+ 0 - Androsynth Guardian
+ 1 - Arilou Skiff
+ 2 - Chenjesu Broodhome
+ 3 - Chmmr Avatar
+ 4 - Druuge Mauler
+ 5 - Human Earthling
+ 6 - Ilwrath Avenger
+ 7 - Kohr-Ah Marauder
+ 8 - Melnorme Trader
+ 9 - Mmrnmhrm X-Form
+ 10 - Mycon Podship
+ 11 - Orz Nemesis
+ 12 - Pkunk Fury
+ 13 - Shofixti Scout
+ 14 - Slylandro Probe
+ 15 - Spathi Eluder
+ 16 - Supox Blade
+ 17 - Syreen Penetrator
+ 18 - Thraddash Torch
+ 19 - Umgah Drone
+ 20 - Ur-Quan Dreadnought
+ 21 - Utwig Jugger
+ 22 - VUX Intruder
+ 23 - Yehat Terminator
+ 24 - Zoq Fot Pik Stinger
+255 - Unused slot
+
diff --git a/doc/devel/musicres b/doc/devel/musicres
new file mode 100644
index 0000000..780ee2b
--- /dev/null
+++ b/doc/devel/musicres
@@ -0,0 +1,18 @@
+This is the format for resources of type MUSICRES (these have the extension
+.mod in the original source).
+
+If the first 3 characters are 'CDA', from the next character to the first
+nul char, or 3 characters after the first period (whatever comes first) is
+used as a filename with aif audio data to play. (CDA stands for CD-audio.
+The source code mentions 'red book', but it's not (red book is the standard
+for audio CD's)). The rest of the file (just a few more chars) seems to be
+garbage.
+
+If the first 3 characters are something else, the entire file (including the
+first 3 characters) are used as a MOD file. (As the mod file uses those char
+as the title of the song, a mod file with the title beginning with 'CDA'
+will go wrong).
+
+
+Initial version of this file 2002-10-26 by Serge van den Boom.
+
diff --git a/doc/devel/netplay/notes b/doc/devel/netplay/notes
new file mode 100644
index 0000000..afac628
--- /dev/null
+++ b/doc/devel/netplay/notes
@@ -0,0 +1,21 @@
+As the game currently unfortunately works with polling, this is how
+to integrate network handling with the game.
+
+In the function called periodically by DoInput(), there should be a call
+to netInput() somewhere at the beginning, and a call to flushPacketQueues()
+somewhere at the end.
+
+netInput() checks all connections for incoming packets, and calls
+the appropriate packet handlers.
+
+flushPacketQueues() sends all pending packets on their way, for all
+connections.
+
+In between, you can call functions that enqueue packets.
+You would also check the network state here to determine whether you need to
+act on some packet that has been delivered to the local party.
+
+
+
+
+
diff --git a/doc/devel/netplay/protocol b/doc/devel/netplay/protocol
new file mode 100644
index 0000000..5b82a1f
--- /dev/null
+++ b/doc/devel/netplay/protocol
@@ -0,0 +1,336 @@
+There are several types of negotiations used to synchronised the parties
+of a network connection.
+
+- Continue when we know the other is ready ("Ready")
+ This is used when both parties need to sending information to the
+ other side, but what each party is doing does not interfere with
+ what the other party is doing.
+- Agree on changes ("Update")
+ This is used when the parties have changes to make to common data.
+- Mutual agreement on an action ("Confirm")
+ This is used to end a state where both parties are modifying
+ common data. Both parties have to agree with the data for either
+ party to continue.
+- Reset a connection. This is used to abort a game in progress and return
+ to the fleet setup menu.
+
+============================================================================
+
+"Ready" negotiation.
+
+Sometimes the parties need to notify eachother of their local state,
+and then go on when both are ready. For this purpose both parties signify
+that they are ready by sending the READY message. When a party is ready
+and has received notice that the other party is ready, it can go on.
+
+States:
+0. notReady - send nor received READY
+ !localReady && !remoteReady
+1. localReady - sent READY, not yet received READY
+ localReady && !remoteReady
+2. remoteReady - received READY, not yet sent READY
+ !localReady && remoteReady
+3. ready - sent and received READY
+
+Messages:
+- READY - "I have nothing further to send at this point"
+
+
+From state 0 (notReady):
+local decision -> Send READY, goto 1
+received READY -> goto 2
+
+From state 1 (localReady):
+received READY -> goto 3
+
+From state 2 (remoteReady):
+local decision -> Send READY goto 3
+
+
+============================================================================
+
+"Update" negotiation.
+
+During configuration, both sides may change the same properties. So that the
+two sides don't have to take turns, the changes are made locally, and then
+the changes are synchronised.
+
+To this end, each side has a state containing two copies of each property:
+ 1. The value of the property as it is locally
+ 2. The last value which it sent to the other side (until it is no longer
+ relevant for the protocol)
+
+The basic idea of the Update protocol is:
+- both sides each send and receive one packet before being allowed to
+ send another one (we'll call this a "turn" here)
+- when a packet has been sent and one has been received in a turn,
+ and the sent and received values are the same, then that value is the
+ agreed upon value. If the sent and received values differ, then a
+ tie breaker determines which one prevails.
+- when the first local change of a turn is made, the change is sent to
+ the other side
+- when a local change has been made while a packet has already been
+ sent this turn, the change will be made locally, but communicating the
+ change will be postponed
+- when a turn ends while a change has been postponed, and this change isn't
+ negated by a remote change, then the change will be sent
+- when a remote change arrives, and a packet has not been sent this turn,
+ the local state is updated with the change, and the same packet is sent
+ to the other side to confirm the change
+
+The tie breaker is required to always let one side win, and the other
+side lose, given the same property.
+Any function satisfying this requirement is usable, but the currently
+used one will return true for the side which 'owns' the property, and
+false on the other side.
+Another tie breaker could be one which always lets the same side win,
+regardless of the property.
+
+
+The protocol:
+
+From state 1, {own=x0, sent=--}:
+1a Local change x1 -> send(x1); state=2:{own=x1,sent=x1}
+1b Received UPDATE(x1) -> send(x1); state=1:{own=x1,sent=--}
+
+From state 2, {own=x0, sent=x0}:
+2a Local change x1 -> state=3:{own=x1,sent=x0}
+2b Received UPDATE(x0) -> state=1:{own=x0,sent=--}
+2c+ Received UPDATE(x1) -> state=1:{own=x0,sent=--} if winTieBreak
+2c- Received UPDATE(x1) -> state=1:{own=x1,sent=--} if !winTieBreak
+
+From state 3, {own=x1, sent=x0}:
+3a Local change x0 -> state=2:{own=x0,sent=x0}
+3b Local change !x0 -> state=3:{own=xN,sent=x0}
+3c Received UPDATE(x0) -> send(x1); state=2:{own=x1,sent=x1}
+3d+ Received UPDATE(!x0) -> send(x1); state=2:{own=x1,sent=x1} if winTieBreak
+3d- Received UPDATE(!x0) -> state=1:{own=x?,sent=--} if !winTieBreak
+
+
+Explanation:
+We keep track of the local value ('own'), and whether or not we sent a packet
+in this turn ('sent' != '--'), and if we did, the last packet which we sent
+('sent'). When we proceed to the next turn, 'sent' is set to '--'.
+
+State 1: We have not yet sent a packet this turn (which implies that we
+haven't made a local change this turn).
+1a. A local change is made. We update our local value, and send this to
+ the remote side.
+1b. A remote change arrives. We don't have any local change ourselves,
+ so we accept the remote change, and sent it back to confirm.
+ With both a packet sent and one received, the turn ends, and 'sent'
+ is set back to '--'.
+
+State 2: We have sent a packet this turn (after making a local change), and
+have not changed our local value since (or we have changed it and changed
+it back).
+2a. A local change is made. We update our local value, but we have already
+ sent a packet this turn, so we can't report it until the next turn.
+2b. A remote change arrives, and it is equal to both our local value and
+ the value which we sent to the other side this turn.
+ This remote notification may be a confirmation of our update, or a
+ coincidental identical remote change.
+ Either way, the packet acts as a confirmation, and we do not need
+ to change anything. With both a packet sent and received, the turn ends
+ and so 'sent' is set back to '--'.
+2c. A remote change arrives, and it is not equal to our local value (which
+ is the same as the value which we sent).
+ The tie breaker decides which value prevails. The same value will
+ prevail on the remote side, so there is no need to send any confirmation
+ packets. The turn ends, and 'sent' is set back to '--'.
+
+State 3: We have sent a packet this turn, and have made a local change since.
+3a. A local change is made back to the value which we sent. No action
+ is required.
+3b. A local change is made. We update our local value, but we have already
+ sent a packet this turn, so we can't report it until the next turn.
+3c. A remote change arrives, and it is equal to the value which we sent
+ (which isn't equal to the current local value).
+ The sent/received value is the accepted value and the turn ends.
+ But we have changed our value since already, so as the next turn
+ starts, we immediately send an update.
+3d. A remote change arrives, and it is not equal to the value which we sent
+ this turn.
+ + We win the tie break, so the value which we sent prevails.
+ But we have changed our value since already, so as the next turn
+ starts, we immediately send an update.
+ - We lose the tie break, so the value which the remote value sent
+ prevails. We accept the value and the turn ends.
+ (An alternative would be to consider the local change(s) which
+ we made after our change was sent as made in the following turn,
+ in which case we would send our current local value in the next turn.
+ The advantage would be that 3d- would become equal to 3d+,
+ so these could be joined (with 3c too), which saves a few
+ if-statements in the code, but this requires another packet to be sent
+ and replied to in what currently is 3d-.)
+
+
+Proof outline that this works:
+- The states can never get out of sync:
+ After both a packet has been sent and received, both sides (temporarilly)
+ have accepted the same value
+- There can be no indefinite loop without ongoing local changes.
+ Once there are no more local changes:
+ from state 3 we always go to state 2 or 1,
+ from state 2 we always go to state 1
+ from state 1 we can only go back to state 1, and only when a packet
+ has been received.
+ So eventually, both sides are in states 1. With both sides in state 1,
+ no packets have been sent in the current turn, so no more packets are
+ there to be received.
+- Both sides can make changes, as long as the side which wins the tie breaks
+ stops making changes now and then:
+ Without making local changes, a side will go to state 1 eventually.
+ If a side makes a local change, and this is received by the other side
+ while it is in state 1, then that other side will accept the change.
+
+
+The Confirm negatiation is used to finish the Update negotiation.
+This works because local changes triggered by the reception of remote changes
+are treated as local modifications for the purpose of the Confirm negotiation.
+And this can be done because whenever the Confirm negotiation is in a state
+where remote changes may be expected, local modifications are still allowed
+(possily after sending a CANCEL packet).
+
+
+============================================================================
+
+"Confirm" negotiation.
+
+Some actions (like agreeing on a configuration) require confirmation
+from both parties. This section documents the handshaking protocol involved.
+
+Each player must manually confirm the action.
+After a player has confirmed an action, he may cancel it as long as
+he hasn't received a confirmation from the other party.
+
+All messages arrive in the order sent.
+
+
+States:
+0. waiting
+ !handshake.canceling && !handshake.localOk && !handshake.remoteOk
+1. localOk (cancelable) - sent CONFIRM1 (since last CANCEL)
+ !handshake.canceling && handshake.localOk && !handshake.remoteOk
+2. remoteOk (cancelable) - received CONFIRM1
+ !handshake.canceling && !handshake.localOk && handshake.remoteOk
+3. committed - sent CONFIRM1 (since last CANCEL,
+ received CONFIRM1,
+ sent CONFIRM2 (since last CANCEL)
+ !handshake.canceling && handshake.localOk && handshake.remoteOk
+4. cancelWaiting - sent CANCEL
+ handshake.canceling && !handshake.localOk && !handshake.remoteOk
+5. cancelLocalOk - sent CANCEL and ready to send CONFIRM1,
+ but received no CANCELACK
+ handshake.canceling && handshake.localOk && !handshake.remoteOk
+6. cancelRemoteOk - sent CANCEL and received CONFIRM1,
+ but received no CANCELACK
+ handshake.canceling && !handshake.localOk && handshake.remoteOk
+7. cancelCommitted - sent CANCEL and ready to send CONFIRM2,
+ received CONFIRM1,
+ but received no CANCELACK
+ handshake.canceling && handshake.localOk && handshake.remoteOk
+8. done - sent and received CONFIRM1 and CONFIRM2
+ (since last CANCEL)
+
+
+Handshake messages:
+- CONFIRM1 - "the current local configuration is OK for me"
+- CONFIRM2 - "acknowledging your CONFIRM1; my own configuration is unchanged
+ since I sent CONFIRM1 (after the last CANCEL)"
+- CANCEL - "forget about my earlier CONFIRM1"
+- CANCELACK - "received your CANCEL"
+MESSAGE(x) indicates any other message.
+
+
+From state 0: (waiting)
+local confirmation -> Send CONFIRM1, goto 1
+local changes -> Send MESSAGE(changes) (goto 0)
+received CONFIRM1 -> goto 2
+received MESSAGE(changes) -> Process(changes) (goto 0)
+
+From state 1: (localOk)
+local cancel -> Send CANCEL, goto 4
+received CONFIRM1 -> Send CONFIRM2, goto 3
+received CONFIRM2 -> Send CONFIRM2, goto 8
+received MESSAGE(changes) -> Send CANCEL, Process(changes), goto 4
+
+From state 2: (remoteOk)
+local confirmation -> Send CONFIRM2, goto 3
+local changes -> Send MESSAGE(changes), (goto 2)
+received CANCEL -> Send CANCELACK, goto 0
+
+From state 3: (committed)
+received CONFIRM2 -> goto 8
+received CANCEL -> Send CANCELACK, goto 1
+
+From state 4: (cancelWaiting)
+local changes -> Send MESSAGE(changes), (goto 4)
+local confirmation -> goto 5
+received CONFIRM1 -> goto 6
+received CONFIRM2 -> goto 6
+received CANCELACK -> goto 0
+received MESSAGE(changes) -> Process(changes), (goto 4)
+
+From state 5: (cancelLocalOk)
+local cancel -> goto 4
+received CONFIRM1 -> goto 7
+received CONFIRM2 -> goto 7
+received CANCELACK -> SEND CONFIRM1 goto 1
+received MESSAGE(changes) -> Process(changes), goto 4
+
+From state 6: (cancelRemoteOk)
+local confirmation -> goto 7
+local changes -> Send MESSAGE(changes), (goto 6)
+received CONFIRM2 -> (goto 6)
+received CANCEL -> Send CANCELACK, goto 4
+received CANCELACK -> goto 2
+
+From state 7: (cancelCommitted)
+received CONFIRM2 -> (goto 7)
+received CANCEL -> Send CANCELACK, goto 5
+received CANCELACK -> Send CONFIRM2, goto 3
+
+On receiving local confirmation, sending CONFIRM2 is a shortcut for
+sending CONFIRM1 followed by CONFIRM2. Receiving CONFIRM2 from localOk
+and cancelLocalOk is accepted just for this shortcut.
+
+
+To prove there are no race conditions, I examine all the combinations
+of states and messages that are underway. Whenever the order of actions
+isn't fixed, the result should be the same (eg. recv(CONFIRM1) followed
+by send(CANCEL) should leave the party in the same state as when
+the send(CANCEL) preceded the recv(CONFIRM1)).
+I also check whether it is possible for packets to arrive that
+aren't expected.
+
+
+============================================================================
+
+"Reset" negotiation.
+
+See src/sc2code/netplay/proto/reset.c
+
+
+============================================================================
+
+Battle ending negotiation.
+
+This negotation consists of:
+1. a 'Ready' negotiation, before stopping sending frame data
+2. communication of each sides current battle frame count
+3. the side running behind processes more frames to catch up
+
+
+States:
+
+0. Playing
+1. localReady
+2. remoteReady
+3. countSent
+4. catchingUp
+5. awaitingCatchup
+
+// Unfinished... partially described in readyForBattleEndPlayer()
+
+
diff --git a/doc/devel/netplay/states b/doc/devel/netplay/states
new file mode 100644
index 0000000..9727172
--- /dev/null
+++ b/doc/devel/netplay/states
@@ -0,0 +1,178 @@
+== Any connected state ==
+Some packets may be sent and received in any state except
+NetState_unconnected.
+These are: PING, ACK, ABORT, RESET
+These are not listed below at each individual state.
+
+Whenever a connection is aborted, the state is returned to
+NetState_unconnected. This state transition is not listed below at each
+individual state.
+
+
+== NetState_unconnected ==
+NetState_unconnected is the initial state.
+
+NetConnection.state: NULL
+
+Packets ok to send: none
+Packets ok to receive: none
+
+Next state:
+ NetState_connecting -- connection attempt in progress
+
+
+== NetState_connecting ==
+NetState_connecting indicates that a connection is in progress.
+
+When the connection is established, the state is changed to NetState_init
+and InputFunc is set to DoNetworkInit.
+
+NetConnection.state: instance of ConnectStateData
+
+Packets ok to send: none
+Packets ok to receive: none
+
+Next state:
+ NetState_init -- connection established
+
+
+== NetState_init ==
+NetState_init is for initialising the connection before actual game
+information is sent.
+
+As this state is entered, an INIT packet is sent. When an INIT packet
+has also been received, the state is set to NetState_inSetup and
+InputFunc is set to DoMelee.
+
+NetConnection.state: instance of BattleStateData
+
+Packets ok to send: INIT
+Packets ok to receive: INIT
+
+Next state:
+ NetState_inSetup -- received an INIT packet
+
+
+== NetState_inSetup ==
+NetState_inSetup is the state in which the fleet configuration is negotiated.
+
+This does not necessarilly mean that the fleet setup screen is visible;
+this state is also held after a battle when the battle outcome is still
+displayed.
+
+Each side may send fleet configuration changes to the other side, by means of
+FLEET and TEAMNAME packets. Agreement on configuration settings is provided
+through the Update negotiation.
+The Confirm negotiation is used to end this state and go to
+NetState_preBattle. At this time InputFunc is set to DoPreMelee.
+
+NetConnection.state: instance of BattleStateData
+
+Packets ok to send: FLEET, TEAMNAME, HANDSHAKE0, HANDSHAKE1,
+ HANDSHAKECANCEL, HANDSHAKECANCELACK
+Packets ok to receive: FLEET, TEAMNAME, HANDSHAKE0, HANDSHAKE1,
+ HANDSHAKECANCEL, HANDSHAKECANCELACK
+
+Next state:
+ NetState_preBattle -- configuration has been confirmed
+
+
+== NetState_preBattle ==
+NetState_preBattle is used for non-interactive battle negotiations.
+
+One side sends the random seed; the other receives it.
+Both sides send their input delay value.
+The Ready negotiation is used to end this state and go to
+NetState_interBattle.
+
+NetConnection.state: instance of BattleStateData
+
+Packets ok to send: SEEDRANDOM, INPUTDELAY, READY
+Packets ok to receive: SEEDRANDOM, INPUTDELAY, READY
+
+Next state:
+ NetState_interBattle -- ready to continue
+
+
+== NetState_interBattle ==
+NetState_interBattle is used to allow each side to do some local
+initialisations before moving on.
+The Ready negotiation is used to end this state and go to
+NetState_selectShip, or if all sides have selected a ship, to
+NetState_inBattle, or if there are no more ships in a fleet,
+to NetState_inSetup.
+
+If there are no more ships, the the Ready negotiation is used to
+enter NetState_inSetup.
+
+NetConnection.state: instance of BattleStateData
+
+Packets ok to send: READY
+Packets ok to receive: READY
+
+Next state:
+ NetState_selectShip -- ready to select the next ship
+ NetState_inBattle -- ready to start the battle
+ NetState_inSetup -- no more ships; game over
+
+
+== NetState_selectShip ==
+NetState_selectShip is where a side may select their ship. The other
+side is waiting for notice of this selection.
+As soon as the selection has been sent or received, the state is changed
+back to NetState_interBattle.
+
+NetConnection.state: instance of BattleStateData
+
+Packets ok to send: SELECTSHIP
+Packets ok to receive: SELECTSHIP
+
+Next state:
+ NetState_interBattle -- a selection has been made
+
+
+== NetState_inBattle ==
+NetState_inBattle is where the actual melee takes place.
+Both sides send their input until the game is over, at which point
+the Ready negotiation is used to end this state and go to
+the NetState_endingBattle state. Until the Ready negotiation has been
+completed, the simulation is continuing.
+
+NetConnection.state: instance of BattleStateData
+
+Packets ok to send: BATTLEINPUT, READY
+Packets ok to receive: BATTLEINPUT, READY
+
+Next state:
+ NetState_endingBattle -- ready to end the battle
+
+
+== NetState_endingBattle ==
+NetState_endingBattle is where the local side waits for the remote
+battle frame count, after it has sent its own. When it arrives,
+the state changes to NetState_endingBattle2.
+
+NetConnection.state: instance of BattleStateData
+
+Packets ok to send: BATTLEINPUT, FRAMECOUNT
+Packets ok to receive: BATTLEINPUT, FRAMECOUNT
+
+Next state:
+ NetState_endingBattle2 -- we know when to end the battle
+
+
+== NetState_endingBattle2 ==
+NetState_endingBattle2 is where the side with the lowest battle frame count
+catches up with the other other side, while the other side waits.
+The Ready negotiation is used to signal that each side is ready,
+and the state changes to NetState_interBattle.
+
+NetConnection.state: instance of BattleStateData
+
+Packets ok to send: BATTLEINPUT, READY
+Packets ok to receive: BATTLEINPUT, READY
+
+Next state:
+ NetState_interBattle -- get ready for the next ship
+
+
diff --git a/doc/devel/netplay/todo b/doc/devel/netplay/todo
new file mode 100644
index 0000000..33102c7
--- /dev/null
+++ b/doc/devel/netplay/todo
@@ -0,0 +1,120 @@
+High priority items:
+
+
+Medium-priority:
+- For the battle ending synchronisation, set the end at at least
+ getBattleInputDelay() + 1 frames in the future (instead of just 1),
+ so that there will be no hickup during the end synchronisation.
+ Also check this value for incoming packets.
+- If a player only moves away from 'Battle!' there's no need for the other
+ to have to reconfirm.
+- decent pause handling
+- make compilation of crc.c and checksum.c conditional.
+- negotiate checksum interval
+- Closing and destroying of NetConnections is a terrible mess.
+- Checks allConnected() shouldn't be needed if CHECK_ABORT is set
+ on disconnect.
+- Shorten or lengthen the time between frames depending on how full the input
+ buffer is, to prevent one side constantly stalling when the connection in
+ one direction is slower than in the other direction.
+
+
+Low-priority:
+- Some difference in pictures to indicated confirmed/unconfirmed.
+ A check mark perhaps.
+- Check whether the random seed and frame delay have been agreed before
+ continuing (in doConfirmSettings).
+- Replacement for TOS. It is IPv4 only.
+- Integrate network check functions with doInput
+ It will be easy to get rid of the separate threads then too.
+- The state changes from interBattle to interBattle. That shouldn't happen,
+ but it doesn't seem to cause any problems. Need to investigate.
+ Addition: negotiateReadyConnections() is called again just to make sure
+ all sides pass this checkpoint. This is not a problem. It should be
+ documented in STATES though.
+- More files define NETCONNECTION_INTERNAL than they should.
+- voice transmission during the game (using an external lib)
+ read ramjee94adaptive.pdf
+- Keep-alive packets. Store time of last packet sent, use alarms to determine
+ when to send the next one. Count received messages?
+- Some way to (optionally) hide your fleet setup until the start of the
+ game? With either a previously determined maximum fleet value, or
+ just display a number to the opponent.
+- (when ships stats are in the content) Negotiate the ship stats, so people
+ can play with non-default ships.
+- Pre-fleet-setup setup
+ The values negotiated could include handicapping (different values for
+ each player)
+ - hide fleets (also handicapping here)
+ - maximum number of ships per side
+ - maximum ship cost per side
+ - ship properties
+- Send taunts (prerecorded samples) at the touch of a button?
+ Use taunt add-on packages? Send the opponent's package before the start
+ of a game?
+
+
+Future improvements/optimisations:
+- For BSD sockets: use dup2() to move fds to lower values, so that less fds
+ have to be checked on select().
+- Use writev() to send multiple packets in one syscall, instead of
+ calling send() for each packet.
+- Refusing games with both parties network controlled is not always
+ necessary. In theory it should be possible to have a client work
+ as "proxy". The client can watch as the actual players play the game.
+ Checking for "loops" would be tricky (eventually there should be a human
+ or computer controller for each side).
+- Concurrent selection of ships. Note that if this is handled properly, it
+ will also be easy to take care of the "Allow Shofixti to choose last" bug.
+ Note that one party will still have to send his choice to the other side
+ first, which may be "exploited". Encryption would take care of this,
+ but at the least make sure the same player who gets to chose first
+ every time.
+- meta-server. Use HTTP? Existing libs can be used, no problems with NAT,
+ human-readable. Speed is not an issue.
+- move to UDP. Repeat past battleinput packets for each new packet that
+ is sent until they are confirmed.
+- Once the protocol is stable: register the port number with IANA
+- Per state data (in NetConnection.stateData) is unnecessarilly complicated.
+ Putting all fields directly in NetConnection simplifies things a lot.
+ It's not as generic, but this code won't be used elsewhere anyhow.
+- Send captain names to the other side
+
+
+Bugs:
+- as positions are dependant on the screen resolution, you won't be able
+ to keep sync on games with a different resolution.
+- collision detection is dependant on the images used. Using different
+ graphics packs will result in a desync.
+- Both sides need identical battle frame rates. This value is not
+ negotiated.
+- If one player closes the connection while the other player is selecting
+ a ship to put in his fleet, or loading a fleet, the "Network Control"
+ button won't be updated.
+- If one side is computer-controlled, sync loss will occur, because the AI
+ uses the RNG. It needs its own RNG context.
+- Pressing F10 to exit the supermelee setup when a connection is active
+ will cause an attempt to draw a NULL frame. (possibly the disconnect
+ feedback)
+
+
+Final actions:
+- Check out TODO, XXX, WORK tags
+- memleak testing
+ - check for and remove mtrace()/muntrace() calls.
+- update documentation
+ - FILES, also note which part of the separation they are in
+- check coding style (search for '\>(')
+- compile with maximum warnings
+
+
+To put in the announcement of Netplay:
+- Slow connections is acceptable. Packet loss isn't.
+
+
+Bugs and todos unrelated to netplay.
+- other player being able to choose the next ship after 3 seconds
+ of inactivity
+- DoRunAway() shouldn't be handled in ProcessInput()
+
+
diff --git a/doc/devel/orggenerate b/doc/devel/orggenerate
new file mode 100644
index 0000000..fce2207
--- /dev/null
+++ b/doc/devel/orggenerate
@@ -0,0 +1,133 @@
+Note: this file describes the way in which various things were generated
+in the original source. See the file 'generate' for the current system.
+
+============================================================================
+
+The various universe related game data is generated through a call
+to a solar system dependant generation function.
+This function is of type PLAN_GEN_FUNC, which is a typedef to
+ void (*PLAN_GEN_FUNC) (BYTE control)
+, where the 'control' argument specifies what type of data needs to be
+generated (one of GENERATE_PLANETS, GENERATE_MOONS, GENERATE_ORBITAL,
+INIT_NPCS, REINIT_NPCS, UNINIT_NPCS, GENERATE_MINERAL, GENERATE_ENERGY,
+GENERATE_LIFE, or GENERATE_NAME).
+
+The generation function for a solar system is kept in the 'GenFunc'
+field of the SOLARSYS_STATE structure.
+The SOLARSYS_STATE structure contains the data for a solar system.
+Currently, only one SOLARSYS_STATE structure is used at once, and
+the global variable pSolarSysState points to the current one.
+The GenFunc field is initialised in ExploreSolarSys(), to the value
+returned by GenerateIP() in sc2code/gendef.c. Usually, this will be
+'GenerateRandomIP', but for some specific solar systems a (pointer to a)
+custom generation function is returned. This depends on the value of
+CurStarDescPtr->Index, which contains values such as SOL_DEFINED,
+MELNORME0_DEFINED, AQUA_HELIX_DEFINED, etc (see sc2code/encount.h
+for the complete list).
+The starmap_array in sc2code/plandata.c specifies Index for all
+the solar systems in the game.
+
+Following are the possible values of the 'control' argument to the
+generation function, with the description of how the generation function
+acts on this. As the custom generation functions often only need to
+change one specific aspect of this game data generation, they will
+often call GenerateRandomIP() for the rest.
+StarBases are handled as if they were moons.
+
+GENERATE_PLANETS
+Pre: the global variable pSolarSysState points to the relevant solar system.
+Pre: the RNG is initialised with a seed to be used for the generation.
+ In practice, this seed is generated from the HyperSpace coordinates
+ of the solar system (which are hardcoded in sc2code/plandata.c),
+ followed by exactly one call to TFB_Random().
+Post: the RNG is in an undefined state.
+This function determines how many planets the system has, and fills in
+pSolarSysState->PlanetDesc[] for all planets, including the NumPlanets
+field, which determines how many moons the planet will have.
+It also sets the random seed that is used for data generated for this planet
+(including the number of moons), based on its coordinates (which are in the
+general case randomly determined themselves).
+
+GENERATE_MOONS
+Pre: the global variable pSolarSysState points to the relevant solar system,
+ which is initialised by a GENERATE_PLANETS call.
+Pre: the RNG is initialised with a seed to be used for the generation.
+ In practice, this seed is the seed stored by GENERATE_PLANETS
+ in the rand_seed field for the planet around which the moon(s) orbit.
+Pre: pSolarSysState->pBaseDesc points to the the relevant planet
+ of pSolarSysState->PlanetDesc[].
+Post: The RNG is in an undefined state.
+This function fills in pSolarSysState->MoonDesc[] for all moons around
+the planet pointed to by pSolarSysState->pBaseDesc.
+It also sets the random seed that is used for data generated for the moon
+based on its coordinates (which are in the general case randomly determined
+themselves).
+
+GENERATE_ORBITAL
+Pre: the global variable pSolarSysState points to the relevant solar system,
+ which is initialised by a GENERATE_PLANETS call.
+Pre: pSolarSysState->pOrbitalDesc points to the relevant planet or moon from
+ pSolarSysState->PlanetDesc[] or pSolarSysState->moonDesc[]
+Pre: the planet or moon that pSolarSysState->pOrbitalDesc points to
+ is initialised by a GENERATE_PLANETS or GENERATE_MOONS call.
+This function fills in pSolarSysState->SysInfo with the characteristics
+of the planet or moon, as seen from orbit.
+It also initialises the random seeds used for the generation of bio,
+minerals, and energy nodes on the surface.
+It also sets the discovery report string (if appropriate), initialises
+the surface graphics, and start the planet music.
+For specific planets, it may initiate race communication and possibly combat,
+and will only return once these are over.
+NB. The GENERATE_ORBITAL code should be split up into separate calculation
+and activation (graphics and music) parts.
+
+GENERATE_MINERAL, GENERATE_ENERGY, GENERATE_LIFE
+Pre: the global variable pSolarSysState points to the relevant solar system,
+ which is initialised by a GENERATE_PLANETS call.
+Pre: pSolarSysState->pOrbitalDesc points to the relevant planet or moon from
+ pSolarSysState->PlanetDesc[] or pSolarSysState->moonDesc[]
+Pre: the planet or moon that pSolarSysState->pOrbitalDesc points to
+ is initialised by a GENERATE_PLANETS or GENERATE_MOONS call.
+Pre: pSolarSysState->SysInfo is filled in by a GENERATE_ORBITAL call
+This function determines the properties of one mineral deposit, energy node,
+or life form on a planet or moon. On entry the caller sets
+pSolarSysState->CurNode to the index of the requested item. This function
+will then fill in pSolarSysState->SysInfo.PlanetInfo.CurPt,
+pSolarSysState->SysInfo.PlanetInfo.CurType, and in the case of minerals also
+pSolarSysState->SysInfo.PlanetInfo.CurDensity.
+In case pSolarSysState->CurNode is set to a value larger than or equal to
+the number of items of the requested kind ((COUNT) ~0 in practice), it is
+set to the real number of nodes. In this case the CurXXX fields of
+pSolarSysState->SysInfo.PlanetInfo are set to the values corresponding to
+the largest valid CurNode index, but should probably be considered to be
+undefined.
+These functions may also change the game state, cause the lander
+to take off (by setting InTransit to true in the active PLANETSIDE_DESC
+structure), or mark an energy node as not retrieved, usually in response
+to an item having been picked up since the last call. The game makes
+a GENERATE_MINERAL, GENERATE_ENERGY or GENERATE_LIFE call (whatever
+is relevant) for each item right after it is picked up.
+
+GENERATE_NAME
+Pre: pSolarSysState is set to the relevant solar system.
+Pre: The planet is initialised by GENERATE_PLANETS.
+Pre: pSolarSysState->pBaseDesc points to the relevant planet, which should
+ be in the system.
+This function fills GLOBAL_SIS (PlanetName) with the name of the planet
+pointed to by pSolarSysState->pBaseDesc.
+It also sets the GAME_STATE flag BATTLE_PLANET to the type of this planet,
+so that it will be shown appropriately in melee if combat follows.
+There is no generate function for the names of moons. The few moons that
+are named (those in the Sol system), are handled as a special case of
+the routines that prints these names (PrintCoarseScan3DO and
+PrintCoraseScanPC).
+
+INIT_NPCS
+REINIT_NPCS
+UNINIT_NPCS
+[TODO]
+
+
+Initial version of this document created by Serge van den Boom, on 2005-07-11.
+
+
diff --git a/doc/devel/pkgformat b/doc/devel/pkgformat
new file mode 100644
index 0000000..69a2513
--- /dev/null
+++ b/doc/devel/pkgformat
@@ -0,0 +1,174 @@
+The .pkg/.ndx format as used for Starcon.pkg on the 3DO cd.
+Acquired directly from the source.
+
+This format is used both in the file and is memory. There are some
+little differences; where this is this is the case, this is
+mentioned below in square brackets.
+
+Everything is stored LSB first.
+
+This document talks about packaged files.
+Packaged files have multiple resources stored in one file. All the resources
+in one package are stored in a single file, whose name is specified in
+p.packmem. The name may be '\0', in which case the package file itself
+is used.
+Non-packaged files have one resource per file. The name is specified
+in each resource instance info field.
+
+Main header: (resinit.c, _GetResFileData())
+position length meaning
+0x00 2 Whether or not the file is packaged (res_flags)
+ bit 0: 0 - the .pkg file is not packaged
+ 1 - the .pkg file is packaged
+0x02 4 offset from the beginning of the file where the list
+ of package information is stored (packmem_list_offs)
+0x06 4 offset from the beginning of the file where the list
+ of pathnames is stored (path_list_offs)
+0x0a 4 offset from the beginning of the file where the list
+ of file names is stored (file_list_offs)
+0x0e 2 number of packages in the file (num_packages)
+0x10 2 number of types of packages present in the file (num_types)
+0x12 4 length of this header. (index_info.header_len)
+ (unused if the .pkg file is not packaged)
+0x16 8*num_packages:
+ On position i the information for package i + 1 is
+ stored. There is no package 0.
+ 4 p.packmem_info
+ bits 0-7: number of resource types
+ bits 8-20: number of resource instances
+ bits 21-31:
+ For packaged files: index in file_list_offs of the
+ file name for this resource
+ For non-packaged files: unused (0)
+ 4 p.flags_and_data_loc
+ MSB is flags, rest is data_loc,
+ if MSB == 0, then of the data_loc only the low 16 bits
+ are used as a MEM_HANDLE [only in memory],
+ if MSB == 0xff, then the data_loc is an offset in the
+ file to the actual data
+0x16+8*num_packages Type information
+ 2*num_types
+ t.instance_count
+ The number of instances there are of this type.
+ On position i the instance count for type i + 1 is
+ stored. There's no type 0.
+packmem_list_offs (should be directly after the index info):
+ for each of the num_packages packages:
+ for each of the resource types for this package
+ (as in p.packmem_info):
+ 4 bits 0-7: The type number for this type. What that
+ number means isn't specified, and may
+ vary per .pkg file.
+ For the 3DO SC2 starcon.pkg file these are:
+ 0 - not a type
+ 1 - Graphics data (GFXRES)
+ 2 - String data (STRTAB)
+ 3 - Music data (MUSICRES)
+ 4 - Resource index (RES_INDEX)
+ 5 - Code (CODE)
+ bits 8-20: The instance number of the first instance
+ of this type in this package. Every
+ following instance has a number 1 higher
+ than the one before.
+ bits 21-31: number of resources of this type in the
+ package
+ for each of the resource instances for this package
+ (as in p.packmem_info):
+ 2 if this is a packaged file: multiply by 4 to get
+ the length of this resource. [1]
+ if this is a file that is not packaged:
+ index in file_list_offs of the file name for
+ this resource.
+ [the same position is in memory used as a MEM_HANDLE
+ to the actual data]
+path_list_offs (should be directly after the packmem list)
+ ? null terminated path strings, indexed from the file list
+ table
+file_list_offs (should be directly after the path list)
+ ? A number of file info structures. For packaged files,
+ these are indexed from the p.packmem_info (so (at most)
+ one per package). For non-packaged files, these are
+ indexed from an entry for an instance from
+ p.packmem_list (so possibly more per package)
+ These structures are in this form:
+ 13 file info:
+ 2 location relative to path_list_offs of the
+ the path to this file, or 0xffff if no path.
+ 8 file name (8 chars or null-terminated)
+ 3 extension (3 chars or null-terminated)
+
+The following section is present in the package only for packaged files.
+For non-packaged files, the fields below exist in the external file indicated
+by p.packmem_info.file_index.
+For each package p:
+p.data_loc for each type p.t:
+ for each instance p.t.i:
+ p.t.i.length
+ the data for the resource
+ As the length always is a multiple of 4, the last
+ few bytes may not belong to the resource itself.
+ Their content is unspecified.
+
+
+Resources with type 'resource index' (type 4 in the 3DO sc2 starcon.pkg file)
+are files with the same format as this .pkg file itself.
+
+
+The information above, about the format used on the 3DO, is gathered from
+the resource library sources itself.
+The information below, about the format used on the PC, and for SC1,
+is induced from the packed files themselves.
+
+
+The format used in SC1 is somewhat different. The differences are listed
+here:
+0x02 4 offset from the beginning of the file where the list
+ of pathnames is stored (path_list_offs)
+0x06 4 offset from the beginning of the file where the list
+ of file names is stored (file_list_offs)
+0x0a 4 offset from the beginning of the file where the list
+ of package information is stored (packmem_list_offs)
+0x0e 2 number of types of packages present in the file (num_types)
+0x10 2 ?
+0x12 2 number of packages in the file (num_packages)
+0x14 2 ?
+packmem_list_offs
+ 4 as for the 3DO
+ 2 if this is a packaged file: the length of this resource.
+ No multiplication by 2 or 4 as on other platforms. [1]
+
+
+The format used in the DOS version of SC2 is different yet again.
+The differences to the 3DO version are listed here:
+0x10 1 number of types of packages present in the file (num_types)
+0x11 1 unknown
+packmem_list_offs
+ 4 as for the 3DO
+ 2 if this is a packaged file: multiply by 2 to get
+ the length of this resource. [1]
+
+
+[1]. In some of the packaged .pkg files used in the Toys For Bob games,
+the length field of a resource instance is overflowed for some resources,
+even though the use of a multiplier will have had the purpose of preventing
+this. The actual size is a multiple of 0x10000 times the multiplier larger.
+This occurs in 18 packages in the PC version of Star Control II, in
+1 package of the Amiga version of Star Control 1, and in 2 packages of
+the PC version of The Horde. The PC version of Star Control 1, and the 3DO
+version of Star Control II don't have such overflows.
+The actual size of a package can be determined by looking at the
+difference in offset between two subsequent packages.
+Where the package contains only one resource instance, the extra data can
+only belong to that instance. Where a package contains more than one
+resource instance, the extra data most likely belongs to the last resource,
+as an incorrect size results in an incorrect offset for all subsequent
+instances in the package, which would most likely have been noticed due to
+corruption in the game.
+
+
+The part pointed to by file_list_offs is frequently followed by a bit of
+unused space, which may contain garbage.
+
+
+Initial version of this file 2002-10-10 by Serge van den Boom.
+
diff --git a/doc/devel/planetrender b/doc/devel/planetrender
new file mode 100644
index 0000000..aa3c908
--- /dev/null
+++ b/doc/devel/planetrender
@@ -0,0 +1,54 @@
+Planet surface rendering code
+--------------------------------------------------------------
+
+The way the planets appear on the screen (based on planet type
+definition in plandata.c) is determined by several factors:
+
+1. Topography algorithm (PlanetFrame.Type)
+2. Color map (PlanetFrame.CMapInstance)
+3. Elevation -> colormap index xlat table (PlanetFrame.XLatTabInstance)
+4. Base elevation (PlanetFrame.base_elevation)
+5. Several others not covered here: faults, craters (blemishes)
+
+First, the planet topography is generated according to the algorithm
+selected for the planet: TOPO_ALGO, CRATERED_ALGO, GAS_GIANT_ALGO.
+TOPO_ALGO and CRATERED_ALGO use a fractal algorithm to pseudo-randomly
+generate a surface, then 'craters' are added and, at the end, the map is
+dithered for CRATERED_ALGO. GAS_GIANT_ALGO is of course different
+because it needs to produce a series of ring-like structures with
+'storms' added at the end.
+
+The topographical map is a rectangle with each pixel representing an
+elevation level relative to 0, so the topography is expressed in terms
+of elevation relative to base elevation. Base elevation is applied to
+the generated map. Topography is created with elevations -128..127,
+and base elevations, currently, range from 100 to 200 (plandata.c) for
+normal worlds and are always 29 for gas giants. Since the gas giants
+do not have a real topography or a surface to speak of, their surfaces
+are rather simulated with elevations.
+
+At this point, the elevation levels are translated to the actual colors
+using the xlat table and color map. First, the elevation is translated
+to an index into the colormap using the xlat table (.xlt files), and
+after that, the actual RGB color is drawn from the colormap (.ct files)
+at this index.
+
+There are 3 colormaps per instance specified in PlanetFrame. The active
+colormap is selected from these 3 based on the surface temperature of
+the planet: cold, normal and hot. The framework is also laid down for
+3 xlat tables (one per surface temperature), but, AFAIK, distinct xlat
+tables are never actually used. Currently, there is only 1 xlat table
+per instance in each file.
+
+The colormap files (.ct) seem to be in original DOS format. Probably
+because they do not translate to the CLUT system very well. The colormaps
+are carefully crafted and synchronized across all planet types to make
+the entire system function properly. They are composed of 4 gradients of
+different hue, 32 colors each (4*32=128 colors). Gradients go from the
+most intense color to near black. For the most planet types, the three
+colormaps per instance are all the same, so that the way a planet
+surface looks does not change with the surface temperature. Notable
+exceptions are: h2o_cts_ (water world) and mtl_cts_ (metal world); there
+could be others as no byte-identical examination was done.
+See blue-gas-giant-pal.png for an example colormap.
+
diff --git a/doc/devel/planetrotate b/doc/devel/planetrotate
new file mode 100644
index 0000000..387c455
--- /dev/null
+++ b/doc/devel/planetrotate
@@ -0,0 +1,31 @@
+Planet-rotate code rev3:
+written by PhracturedBlue
+Date: Nov 1, 2002
+
+This is the code to make the planets spin when in orbit view.
+The planet will zoom in (as in the 3do version)
+Shield support is very preliminary, mosly becuase I have not figured
+out how to get the 'look' right.
+
+The planet rotation speed is controlled by ROTATION_TIME which is defined in plangen.c.
+The default is '22' which gives a speed comparable to the DOS version of the game
+
+The planet zoom speed is defined by PLANET_ZOOM_SPEED which is defined in pl_stuff.c
+
+The lighting algorithm is really just a hack. All lighting code is in plangen.c
+Currently, lighting is performed by placing the light source at a certain distance
+(LIGHT_MULT) from the center of the planet (a value of 1 would place the light at
+the planet's radius. (The angle is determined by the planet's position in orbit with
+respect to the sun). The brightest poinnt will have the original color of the topo-map.
+The light falls off as the cos(r^2/(LIGHT_RADIUS^2)).
+The light can never be dimmer than AMBIENT_LIGHT
+
+The shield is done in 2 parts: the halo and the planet-mask. Whether this is needed or
+not, I don't know, but it gives a bit more flexibility in how the effect is applied.
+
+The code works by blitting directly to an SDL_Surface, rather than using DrawBatch (and
+the rendering thread). This gives a huge performance win (My P3-1000 went from ~40fps
+using the DrawBatch to ~500fps using the current method). All lighting, planet tilt, and
+sphere->plane mapping is precomputed into the 'map_rotate' and 'phong' tables (in plangen.c)
+To optimize performance (there is no floating-poinnt code used during the actual frame
+generation)
diff --git a/doc/devel/planettopo b/doc/devel/planettopo
new file mode 100644
index 0000000..7f27a39
--- /dev/null
+++ b/doc/devel/planettopo
@@ -0,0 +1,92 @@
+Planet Topography Code: sc2code/planets/gentopo.c
+----------------------------------------------------
+
+This text covers only topography generation code. It does NOT cover the
+craters (blemishes) nor the smoothing. Variables names are the same in
+"sc2code/planets/gentopo.c".
+
+A brief overview:
+
+The algorithm works by applying several elevation/lowering steps on the
+same terrain. Each step works by randomly generating two non-intersecting
+lines, LineDDA0 and LineDDA1. That delimits two regions. Each region is
+then displaced by a certain height delta (depth_delta). That step is
+repeated several times.
+
+There's a pseudocode below, with detailed information about it in the next
+section.
+
+The DeltaTopography() function works as follows:
+
+ Function parameters:
+
+ COUNT num_iterations // Number of height displacements on the
+ // planet's surface
+ PSBYTE DepthArray // Target surface, receives topography data
+ PRECT pRect // Surface dimensions
+ SIZE depth_delta // The amount of height units to raise/lower
+ // on each displacement
+
+ for i from 1 to num_iterations
+ randomly either negates depth_delta's or not, influencing
+ the displacement direction
+ randomly pick two line segments, LineDDA0 and LineDDA1
+ increase the height of the region between LineDDA0 and
+ LineDDA1 by depth_delta
+ decrease the height of the region between LineDDA1 and
+ LineDDA0 by depth_delta (by wrapping around the surface)
+ end for
+
+Detailed information about the algorithm's steps:
+
+First, in half the steps (randomly) depth_delta is negated.
+That influences on the direction of the displacements.
+Note that in each step exactly two height displacements occur:
+a lifting and a lowering.
+
+Next, it sets both w1 and w2 to different random WORD values. Those are
+used in the line segment generation process.
+
+LineDDA0 starts on a random position on the top of the surface, and ends
+at another random position on the bottom of the surface.
+LineDDA0 never wraps around the surface, since their X coordinates are
+generated in the range 0..width-1:
+
+ LineDDA0.x_top = LOBYTE (w1) % width;
+ LineDDA0.x_bot = HIBYTE (w1) % width;
+
+LineDDA1 is generated much like the way LineDDA0 is, the difference being
+LineDDA1's x coordinates are displaced by LineDDA0 ones:
+
+ LineDDA1.x_top = (LOBYTE (w2) % (width - 1)) + LineDDA0.x_top + 1;
+ LineDDA1.x_bot = (HIBYTE (w2) % (width - 1)) + LineDDA0.x_bot + 1;
+
+Y coordinates are 0 for top, and 'height' for bottom in both line
+segments.
+
+This delimits basically two regions. One delimited by LineDDA0 on the left
+side, and LineDDA1 on the right right, which we call "0->1". The other is
+delimited by LineDDA1 on the left, and LineDDA0 on the right, which we call
+"1->0".
+Note that, since we're talking about a planet, the rightmost side of the
+surface if "connected" to the leftmost side. At least one of those regions
+"wrap around" the surface.
+
+The final step in the iteration is to increase the height of the region
+0->1 by depth_delta, and decreasing 1->0 by the same value. Note that since
+delta_depth may be negative, raising part of the surface by delta_depth
+may result in the surface being lowered.
+
+This step is repeated num_iteration times.
+
+About the terrain generation algorithm: This method of displacing
+line-delimited subsets of a surface is commonly known as Fault Formation.
+
+The DDA acronym stands for "Digital Differential Analyzer". Hence the names
+LineDDA0 and LineDDA1.
+
+The first version of this document was written by:
+Daniel Ribeiro Maciel <daniel.maciel@gmail.com>
+on 2006-11-24
+
+
diff --git a/doc/devel/plugins b/doc/devel/plugins
new file mode 100644
index 0000000..505d7d1
--- /dev/null
+++ b/doc/devel/plugins
@@ -0,0 +1,129 @@
+UQM Code DataPlate modules
+=====================================================================
+Terminology:
+------------
+cdp Code DataPlate
+ refers to either a module or the architecture
+ itself;
+
+module cdp module (ditto ^)
+
+interface a set of functions defined by either the core
+ engine or a module aimed at performing various
+ tasks on a specific part of the game
+
+itf interface; short form
+
+host the game itself or core engine; also a top-level
+ interface for use by modules
+
+interface kind a unique identifier of a particular defined
+ interface (not of the interface instance);
+ there can be several interfaces of the same
+ kind registered, but they all have to cover
+ different API versions (version ranges may
+ overlap though)
+
+standard interface interface *defined* by the core engine
+ all host, sound, video, gfx, threads, time,
+ input, io (uio), memory, resource interfaces
+ are standard, including all subdivisions like
+ 'sound mixer' and 'sound decoder';
+ a module can implement standard behavior of
+ the game or extend the game by implementing and
+ registering a corresponding interface
+
+built-in interface interface *provided* by the core engine
+ e.g. host, sound, video, gfx, etc. lib wrappers
+ anything except 'host' can theoretically be
+ implemented as a 'standard' interface rather
+ than built-in; sound and video interfaces,
+ for example, would not make sense to rip out
+ from the core, but parts of 'gfx' might be good
+ candidates (gfx should probably be more than
+ 1 interface); do not confuse 'sound' interface
+ with 'sound decoder' and 'sound mixer', mixers
+ (MixSDL and OpenAL) are also prime candidates
+
+custom interface interface *defined and provided* by a module,
+ other than a standard interface
+ a module may decide to provide (expose) some
+ interfaces so that other modules can utilize
+ them; a module will register such interface
+ the same way it would register a standard
+ interface it implements
+
+vtbl virtual table; a table of interface functions;
+ pointer to vtbl is semantically equivalent to
+ an interface pointer
+
+event a bindable point in code of the engine or any
+ module; event observer recieves event
+ notifications via event handlers it installs
+
+h_foo handle to 'foo'
+
+plate cdp module
+fork interface; something to poke a plate with
+spoon event;
+ "hit the plate with a spoon" == "notify via
+ event handler"
+
+
+Typical calling sequence:
+-------------------------
+1) something calls adlm_LoadModule(the_mod) ('the_mod' is used here
+ to identify the module and to *logically* group module properties
+ and operations performed on the module for the sake of this
+ document); the_mod gets dlopen()ed;
+
+2) adlm_LoadModule() looks up the only exported symbol 'adlminfo'.
+ This symbol is the adlm_ModuleInfo struct;
+
+3) adlm_LoadModule() verifies that the_mod is compatible with current
+ engine and API versions and calls
+ adlm_GetInterface(HOST,the_mod.api_ver) to lookup the host interface
+ with the correct API version for the module;
+
+4) adlm_LoadModule() either increments module ref-count (if the module
+ has already been loaded previously) or calls
+ the_mod.module_init(host_itf)
+
+5) the_mod.module_init() stores off the host_itf pointer and performs
+ internal initialization;
+
+6) [Optional; but not useful w/o] the_mod.module_init() calls
+ host_itf->GetInterface(kind) to get access to whatever standard or
+ custom interfaces it requires (for example, it requests a sound
+ interface to register an audio decoder);
+
+7) [Optional] the_mod.module_init() calls
+ host_itf->RegisterItf(kind,...,itf_vtbl,...) to register the custom
+ or standard (do not confuse with built-in) interfaces it wishes to
+ expose to the core engine or other modules;
+
+8) [Continuous normal operation] module calls members of the interfaces
+ it acquired to perform various game-related tasks; core engine
+ and/or other modules call members of the interfaces that module
+ exposed (if it did so);
+
+9) something calls adlm_FreeModule(h_the_mod) either when the game
+ quits or when the module is dynamically unloaded for whatever
+ reason: possibly when user decides to dump the game-mod and use
+ something else in its place or nothing at all, but for now there
+ is no mechanism to ensure safe mid-game unloading of modules --
+ interfaces are not ref-counted and anything can hold a pointer to
+ an interface at any given time (creating a safe system to do this
+ is probably not cost-effective);
+
+10) adlm_FreeModule() decrements module ref-count and, when ref-count
+ reaches 0, calls the_mod.module_term();
+
+11) the_mod.module_term() calls host_itf->UnregisterItf(h_itf) to
+ unregister the interfaces it had exposed previously; then it
+ unregisters any other objects it registered, releases all objects
+ it acquired through interfaces and destroys any objects it is
+ responsible for;
+
+12) the_mod.module_term() performs internal cleanup;
+
diff --git a/doc/devel/queues b/doc/devel/queues
new file mode 100644
index 0000000..274828e
--- /dev/null
+++ b/doc/devel/queues
@@ -0,0 +1,62 @@
+The various ship queues used in the game:
+
+GlobData.Game_state.avail_race_q:
+ Contains fleet information, ship template and other info about the
+ alien races present in the game. All races are present that are
+ defined by the enum in races.h that defines NUM_AVAILABLE_RACES,
+ except for, technically, SAMATRA_SHIP. URQUAN_PROBE_SHIP is a
+ very incomplete 'race'.
+ Elements are of type FLEET_INFO.
+ Filled in InitGameStructures().
+ Partially included in savegames.
+
+GlobData.Game_state.built_ship_q:
+ The fleet accompanying the flagship (escorts).
+ Elements are of type SHIP_FRAGMENT.
+ which_side is always GOOD_GUY here.
+ Partially included in savegames.
+
+master_q:
+ List of templates for all the ships that are available in SuperMelee.
+ Elements are of type MASTER_SHIP_INFO.
+ Sorted on the (abbreviated) race name (see doc/devel/racestrings).
+ Filled in LoadMasterShipList().
+
+GlobData.Game_state.npc_built_ship_q:
+ The npc ships in an encounter, or list of ship groups when in IP;
+ empty otherwise.
+ Elements are of type SHIP_FRAGMENT. IP group list will most likely
+ change to contain GROUP_INFO instead.
+ For encounters with an infinite number of ships, the queue consists
+ of a single ship with ShipInfo.crew_level set to (BYTE)~0.
+ and the side that this ship is on.
+ Partially included in savegames.
+
+race_q[NUM_PLAYERS]:
+ Contains the ships participating in a battle for each player.
+ Elements are of type STARSHIP.
+ Filled in BuildBattle().
+ RaceDescPtr points to a loaded ship's descriptor once the ship data
+ is loaded in spawn_ship(); NULL otherwise.
+
+
+Other queues:
+
+GlobData.Game_state.GameClock.event_q:
+ Queue of game events.
+ Elements are of type EVENT.
+
+disp_q:
+ Display queue. This contains all visible elements; everything
+ that floats in TrueSpace, HyperSpace/QuasiSpace, battle.
+ Elements are of type ELEMENT.
+
+GlobData.Game_state.encounter_q:
+ Contains information regarding the black globes flying around
+ in HyperSpace.
+ Elements are of type ENCOUNTER.
+
+
+Initial version of this document created by Serge van den Boom, on 2006-03-08.
+
+
diff --git a/doc/devel/racestrings b/doc/devel/racestrings
new file mode 100644
index 0000000..2993a65
--- /dev/null
+++ b/doc/devel/racestrings
@@ -0,0 +1,45 @@
+This file describes the use for each entry of the
+content/base/ships/<race>/<ship>.txt files.
+
+
+Entry #0:
+ Battle group name
+ Used in uppercase on the "debris scavanged" message after destroying
+ a battle group in the full game, from UninitEncounter().
+
+Entry #1:
+ Race name
+ Displayed on the starmap, from DrawStarMap() (and GetSphereRect()).
+ Used in combat (both in the full game and in SuperMelee) as the
+ name of the race, from InitShipStatus().
+
+Entry #2:
+ Abbreviated race name.
+ Used when sorting the races in LoadMasterShipList().
+
+Entry #3:
+ Ship name.
+ Unused (?)
+
+Entry #4:
+ Abbreviated ship name.
+ Unused (?)
+
+Entry #5 (NAME_OFFSET) through #20 (NAME_OFFSET + NUM_CAPTAINS_NAMES - 1):
+ The names of the captains of the ships of this race, as displayed
+ during combat.
+
+
+For some races, some plot-specific captain names follow:
+Shofixti:
+ - Entry #21: Tanaka
+ - Entry #22: Katana
+Spathi:
+ - Entry #21: Fwiffo
+
+
+Note that the race/ship name combinations shown when adding a ship to your
+fleet in the shipyard are actually images (lbm/shipyard.3.png through
+shipyard.23.png). They are displayed from DrawRaceStrings().
+
+
diff --git a/doc/devel/resources b/doc/devel/resources
new file mode 100644
index 0000000..20db1b7
--- /dev/null
+++ b/doc/devel/resources
@@ -0,0 +1,196 @@
+This file documents both the currently used resource system and the
+legacy system used in the original implementations. It also describes
+how to update the resources while keeping everything functional.
+
+ THE UQM RESOURCE SYSTEM
+ -----------------------
+
+Resources are identified by "resource IDs", which are arbitrary
+strings. The UQM convention is to treat them as paths or qualified
+names, with the period being the separator. An example would be
+"comm.arilou.dialogue", which is conceptually grouped with all other
+resources beginning with "comm." or "comm.arilou."
+
+Resources are mapped to files via "resource map files" or RMPs. These
+files are full of key-value pairs. Each line of an RMP file matches
+this format:
+
+ resource_ID = RESOURCE_TYPE:resource_data
+
+The currently defined resource types and their accompanying data are:
+
+GFXRES: A single animation. The resource data is the name of the
+ .ani file that defines it. See the "aniformat" file for
+ details.
+FONTRES: A font. The resource data is the name of the directory
+ in which the font is defined.
+MUSICRES: A music file. The resource data is the filename of the
+ relevant file in OGG or MOD format.
+SNDRES: A set of related sounds. Points to a text file,
+ traditionally suffixed ".snd", that lists each sound
+ file in the collection, one per line. These sounds are
+ in WAV format.
+STRTAB: An unadorned string table. The resource data is the file
+ name.
+BINTAB: Indexed binary data, mostly used for palettes and
+ topological data for planet terrain generation. The
+ resource data is the file name. See the "strtab" file, but
+ be aware that all information not regarding .ct or .xlt
+ files has been obsoleted.
+CONVERSATION: All data corresponding to an individual conversation
+ tree. The resource data has three components, separated
+ by colons: the conversation text (similar to the
+ STRTAB), the directory in which voiceovers may be
+ found, and the timestamp file corresponding to those
+ voiceovers. The second and third values are optional,
+ but if either is present, both must be.
+SHIP: This is an integer that specifies which ship corresponds
+ to a specified resource. The mapping of SHIP integers
+ to actual ship_info structures is done by the dummy.c
+ routines.
+STRING: A string. The resource data is the string itself.
+INT32: A 32-bit integer. The resource data is the integer as a
+ string giving its representation in decimal.
+BOOLEAN: A true/false value. Any value of the resource data that
+ is not the exact case-insensitive string "true" will be
+ treated as false.
+UNKNOWNRES: A catch-all internal type for any type the system does
+ not recognize. It is functionally equivalent to STRING,
+ mainly so that sensible debug messages may be emitted.
+
+When UQM is started, each RMP file in the content directory (but not
+its subdirectories) is read and indexed. Then, for each addon pack
+rqeuested, it reads each RMP file in the addons/(addon name)/
+directory and updates the resource index accordingly. Generally
+speaking, this will overwrite older values of the resources with
+pointers to the new content.
+
+It is permissible to have multiple RMP files in a single directory;
+however, if this is done, there should be no overlap between the
+resources defined. The UQM resource system makes no guarantees about
+the loading order of RMP files within a unit.
+
+It is not required for an addon to restrict its references to its own
+subdirectory; all paths are relative to the base of the content
+directory. This allows fonts to be shared across addons, for an "addon
+pack" to simply reorganize content within the base directory. (For
+instance, a popular modification to the original games involved
+juggling .SHP files and renaming them so that the "Earthling Cruiser"
+was actually a much more powerful ship like the Utwig Jugger or Chmmr
+Avatar. This may be effected in the current system by making an addon
+pack that redefines the relevant SHIP-typed resources.)
+
+ UPDATING THE CORE RESOURCES
+ ---------------------------
+
+The officially supported content is kept in three indices:
+
+- content/uqm.rmp: The core content.
+- content/addons/3domusic/3domusic.rmp: 3DO music.
+- content/addons/3dovoice/3dovoice.rmp: The 3DO conversations.
+
+These latter two are treated the same as any other addons, except that
+they are guaranteed to be loaded first if selected by the
+configuration file.
+
+These files do not house all the necessary data, however. The code
+itself uses a set of automatically generated header files to #define
+constants that correspond to each resource. In order to add new
+resources or change currently defined resource IDs, the .h files must
+also be updated.
+
+To keep all information in one place, the tools/resmap directory
+contains a master data file for all core resources ("resource.csv")
+and a number of Python scripts for manipulating it.
+
+If files have simply been moved, renamed, or re-typed, one may reflect
+these changes in uqm.rmp and run the "reverse_rmp.py" script. This
+will reflect changes in uqm.rmp back into resources.csv.
+
+If the header constants or resource IDs have changed, changes will
+need to propagate to the .h files. Edit or add the relevant lines to
+resources.csv and run "gen_resfiles.py". This will read resources.csv
+and regenerate uqm.rmp and all the relevant header files.
+
+The resources.csv file is a comma-separated-values file suitable for
+importing into most spreadsheet programs. It has one line for each
+resource, and each line has five "columns":
+
+ C constant, resource id, header file, resource type, resource data
+
+If a resource exists in the code, but not in the base content the
+resource type and resource data are both the string "--". The C
+constant and header file are still mandatory - otherwise UQM will not
+compile. Such resources will not be reflected in the RMP files, but
+will have their headers defined appropriately so that addon packs may
+provide values.
+
+Major reorganization of files may be done with the transform.py file;
+its usage string describes its script format.
+
+ LEGACY SYSTEM
+ -------------
+
+The resource files the resource system in SC2 uses, comes in two flavours.
+There are 'packaged' files, which contain the data in the file itself,
+and 'non-packaged' (index) files, which only point to other files.
+The internal formats are described in pkgformat, and are mostly the same.
+
+A resource file is opened by a calling OpenResFile(), after which a
+MEM_HANDLE to a resource can be acquired from it by calling GetResource().
+
+The argument of GetResource() is an integer value specifying the resource.
+There are defines for this defined in (files included from) the various
+resinst.h file. The defines are unique to a resource file.
+A resource id can be something like this: 0x00400002
+Bits 21-31 specify the package. (resources are grouped together in a
+ resource file in packages) (a number >= 0).
+Bits 0-7 specify the resource type of the resource (a number >= 1).
+Bits 8-20 specify the instance number (the number of the resource of a
+ type in a package) (a number >= 0).
+
+The resource type is a number. What kind of resource that actually is,
+is not specified in the package. The program registers functions for
+loading data of a specific type number, by calling InitResTypeVectors().
+
+In the original 3DO version, the following types are used:
+GFXRES (1) - graphics data
+STRTAB (2) - string table
+MUSICRES (3) - music and sound data
+RES_INDEX (4) - a resource 'file'
+CODE (5) - identifies code to use (the resouce file itself does not
+ contain any code)
+
+
+In the PC version of Star Control II, the following types are used
+(the names are taken from the other versions):
+KEY_CONFIG (1) - keyboard configuration
+GFXRES (2) - graphics data
+SNDRES (3) - waveform audio
+STRTAB (4) - string table
+MUSICRES (5) - mod audio
+RES_INDEX (6) - a resource 'file'
+CODE (7) - actual PC code (compressed; used for ships as well as comm;
+ may include other resources)
+ (8) - Deluxe Paint .ANM
+
+
+In the UQM project pre-resmap, the following types were used:
+KEY_CONFIG (1) - keyboard configuration (not used in the 3do packages)
+GFXRES (2) - graphics data
+FONTRES (3) - font data
+STRTAB (4) - string table
+SNDRES (5) - waveform audio
+MUSICRES (6) - music
+RES_INDEX (7) - a resource 'file'
+CODE (8) - identifies code to use (the resouce file itself does not
+ contain any code)
+
+The resource files, resinst.h, restypes.h, and respkg.h files were
+originally generated from information from the .res and .typ files. The
+resource library should be compiled with 'PACKAGING' defined for this.
+
+---
+
+Initial version of this file 2002-10-23 by Serge van den Boom.
+Updated for the 0.7.0 system by Michael Martin.
diff --git a/doc/devel/savefile b/doc/devel/savefile
new file mode 100644
index 0000000..306c1ab
--- /dev/null
+++ b/doc/devel/savefile
@@ -0,0 +1,149 @@
+ SAVEFILE FORMAT
+ ---------------
+
+This document represents a work in progress. The save format described
+here will evolve before finalization for 0.8.
+
+The old save file format used a custom compressor and was very finicky
+about padding and alignment for machines that were not even in use
+anymore. It was also extremely fragile and hard for modders to extend.
+
+The new save format seeks to alleviate these problems.
+
+ GENERAL FORMAT
+ --------------
+
+All multibyte values are little-endian. There are no alignment
+restrictions inherent in the format.
+
+The save file begins with a 32-bit identifier and version number (a
+"magic number") that identifies it as a particular version of an UQM
+save file. If the format changes in a way that older versions of UQM
+cannot read it, either the identifier or the version number should
+change.
+
+The vanilla UQM system has a save number of 0x01534d55, which, if
+interpreted as a byte stream is UMS (Ur-quan Masters Save) and a
+binary 1 (version 1). Vanilla UQM reserves the tags "UMSx" for all x
+for use to evolve the core save format. Modders are encouraged, but
+not required, to also use the fourth bit as a version number.
+
+Following the 32-bit file identifier comes a series of chunks. All
+chunks have the same general format: a 32-bit tag, similar to that of
+the file as a whole, followed by a 32-bit integer specifying the size
+of the chunk, and then that many bytes of data.
+
+Bytes in a chunk tag should all be in the range 0x20-0x7E -- that is,
+they should be printable ASCII characters. Chunks are traditionally
+referred to by their tag names.
+
+Chunks whose tag has a least significant byte in the range 0x41-0x5a,
+inclusive---that is to say, whose names start with a capital
+letter---are mandatory. If you extend the set of mandatory chunks, you
+must increase the version of the file. Tags that do not start with a
+capital letter may be ignored by other versions of UQM that otherwise
+understand that data version.
+
+(Why would you want to have ignorable bits of save file? Such chunks
+may contain helpful but ancillary information. For instance, at the
+time of this writing, there is an outstanding bug that life forms are
+un-stunned if you save and load in orbit. One could add a new chunk
+that tracks the stunned status of life forms on the planet you're in
+orbit around, and just revert to the old behavior if it's not there or
+if you're running on a version without that fix. Such an ancillary
+data chunk would have a tag like "stun" or "biot".)
+
+Note also that despite being "mandatory", it is not the case that all
+chunks will be present in all save files. Different data is saved out
+depending on the situation you saved in.
+
+Unless otherwise specified, chunks may be stored in any order in the
+save file.
+
+ CHUNK INVENTORY
+ ---------------
+
+- "Summ": Summary. This chunk must come first. This chunk
+ carries the flagship configuration information and some overview
+ information that is displayed on the savegame view screen. It is of
+ variable length, because the last element of this chunk is the name
+ of the save as chosen by the user.
+
+- "GlSt": Global State. This chunk must come second, after
+ Summ. Represents most of the data in the global state structure in
+ globdata.h. BattleGroupRef is excised from this; its value is
+ computed later on.
+
+- "GmSt": Game State. This chunk must come third, after GlSt. This is
+ the gigantic bitfield that the GET_GAME_STATE macros modify. It is
+ variably-sized; excess bytes in this array will be ignored, and if
+ there are insufficient bytes in the save file, the remaining bits
+ will be initialized to zero. Modders setting extra event flags may
+ be able to import a legacy game into a sensible state by choosing
+ their defaults judiciously.
+
+- "Evts": Events. An array of values describing scripted future
+ events.
+
+- "Enct": Encounters. Details of battle groups that are pursuing you
+ through HyperSpace.
+
+- "RacQ": Available Race Queue. Which species are active in the game,
+ where they are, etc. Corresponds to avail_race_q.
+
+- "IGpQ": Interplanetary Group Queue. Battlegroup information for
+ ships in your current star system, if you're in a current star
+ system. It is currently unclear whether or not this ever needs to
+ exist, but in keeping with legacy logic, it will appear whenever you
+ are in a star system but not in the middle of an encounter.
+
+- "NpcQ": NPC Queue. Battlegroup information for ships you are in the
+ middle of encountering. This should only appear if your loaded
+ activity is "IN_ENCOUNTER" and loading the game will trigger the red
+ alert.
+
+- "ShpQ": Ship Queue. Battlegroup information for your flagship's
+ escort fleet.
+
+- "Star": Star Description. Basic indexing information to indicate
+ which star system you are in.
+
+- "Scan": Scanner Masks. This is a semi-structured tree of DWORDs that
+ represents which planetary resources have been captured or
+ removed. It is a format roughly similar to the old star info
+ statefile format (see doc/devel/statefile) but little-endianness is
+ enforced, making this chunk endian-safe where the old statefile dump
+ was not.
+
+- "BtGp": Battle Group. Defines the relevant information for all ships
+ in a given star system. This includes an "encounter ID" - randomly
+ generated fleets have an encounter ID of zero, and ones built by the
+ plot have an 32-bit identifier. Vanilla UQM reserves the first 32
+ encounter IDs for itself, and uses 15 of them (random encounter,
+ Ur-Quan Probe, Shofixti Survivor, Zoq-Fot-Pik Emissary, Unzervalt
+ Guardian, nine Melnorme Traders, and the final boss). This also
+ includes the expiration date for random encounters and which system
+ they are relevant to. Much of this information was originally stored
+ in randgrp.dat, but it has echoes in defgrp.dat as well. The data
+ here is a ragged 2D array of a slight extension of the SHIP_FRAGMENT
+ structure. There is one BtGp chunk per defined group. (Since one of
+ these is defined at game start, and the random encounter structure
+ has values that mean 'no encounter present', there should always be
+ at least two of these chunks in any save.)
+
+- "Grps": Active Battle Groups. These are IP_GROUP structures to
+ supplement the SHIP_FRAGMENTs specified in BtGp chunks. They give
+ more detailed information about the precise location and disposition
+ of each ship in the system you are either in or most recently left.
+
+ THINGS LEFT TO DO
+ -----------------
+
+The last 448 bits in GmSt probably shouldn't exist. However, we should
+not remove them from the source base (and thus the save file) until
+after other pending commits have been merged. When this happens, we
+can break out those bits into an array of DWORDs instead. The loading
+code basically ignores those GmSt bits by overwriting them while
+loading later chunks, and GmSt is an expandable array in the first
+place, so removing those final bits from the Game State array should
+be compatible in both directions.
diff --git a/doc/devel/sc1 b/doc/devel/sc1
new file mode 100644
index 0000000..373ac16
--- /dev/null
+++ b/doc/devel/sc1
@@ -0,0 +1,186 @@
+This file documents the file formats used in Star Control 1.
+
+The .pkg files are in the format described in the file "pkgformat".
+The extracted files are described in this document.
+
+The following describes the format used in the DOS version of SC1.
+
+Resource types used in starcon.pkg:
+ 1 - key config
+ 2 - some graphics type (flags = 7)
+ 3 - some graphics type (flags = 1)
+ 4 - some graphics type (flags = 2) 5 - some graphics type (flags = 3)
+ 6 - font
+ 7 - scenario
+ 8 - palette
+ 9 - strtab
+10 - ? (sound?)
+
+
+Files of types 2, 3, 4, 5, 9, and 10 may be compressed; they have
+a header of the following format: have the following format:
+
+Uncompressed files:
+ off len
+ 0x00 1 0 (means: not compressed)
+ 0x01 1 flags, 0 in practice
+ 0x04 2 Number of bytes that follow (MSB first)
+ 0x06 start of data
+
+Compressed files:
+ off len
+ 0x00 1 6 (means: compressed)
+ 0x01 1 flags
+ bit 0: unused
+ bit 1: (table2CodeLen)
+ if not set: table2 results are shifted by 6 bits.
+ if set: table2 results are shifted by 7 bits.
+ (never set in PC SC1 files)
+ bit 2: (litencoded) set if literal bytes are Huffman encoded
+ (never set in PC SC1 files)
+ rest: unused
+ 0x02 4 uncompressed size (MSB first)
+ 0x06 Huffman table 0 (8-bit codes) (only present if litencoded set)
+ used for encoding literal bytes
+ Huffman table 1 (6-bit codes)
+ used for encoding lengths
+ Huffman table 2 (6-bit codes)
+ used for the most significant table2CodeLen bits of an offset
+
+
+
+Huffman table:
+(numbers are in bits)
+ 8 one less than the number of lengths of codes
+ in the table (lenCnt)
+ 8 * lenCnt LONIBBLE: one less than one of the code lengths
+ HINIBBLE: one less than the number of codes with
+ this length
+This is enough to construct the huffman table.
+
+TODO: document the rest of the compression format; for now, look at the
+ code of sc1-decomp.
+
+
+Resource type 1 (key config):
+ off len
+ 0x00 1 bottom player special key ('n')
+ 0x01 1 top player special key ('1')
+ 0x02 1 bottom player left key ('m')
+ 0x03 1 top player left key ('2')
+ 0x04 1 bottom player right key (',')
+ 0x05 1 top player right key ('3')
+ 0x06 1 bottom player thrust key ('.')
+ 0x07 1 top player thrust key ('4')
+ 0x08 1 bottom player fire key ('/')
+ 0x09 1 top player fire key ('5')
+ 0x0a 1 ?
+ 0x0b 1 ?
+ 0x0c 1 ?
+ 0x0d 1 ?
+ 0x0e 1 ?
+ 0x0f 1 ?
+ 0x10 1 ?
+ 0x11 1 ?
+ 0x12 1 ?
+ 0x13 1 ?
+
+
+Resource types 2, 3, 4, and 5 (graphics):
+The difference between those types is the flags parameter that is passed
+to the load functions (see above in the table of resource types).
+bit 0: ?
+bit 1: probably indicates whether a palette is used
+bit 2: ?
+rest: unused
+
+(after decompression/removing packing header)
+ off len
+ 0x00 4 "IANM"
+ 0x04 2 frame count (MSB first)
+ 0x06 2 MSB first
+ LOBYTE: bits per pixel. All SC1 files are either 1 bpp or 4 bpp.
+For every frame:
+ 2 width (MSB first)
+ 2 height (MSB first)
+For every frame:
+ 2 x hotspot
+ 2 y hotspot
+ 1 if not zero, the file includes palettes
+ 1 transparant color
+ 16 (optional) (CGA?) palette (16 entries of 1 byte)
+ 16 (optional) (EGA/Tandy?) palette (16 entries of 1 byte)
+ 16 (optional) (MCGA/VGA?) palette (16 entries of 1 byte)
+ ? pixel data (indicees in palette)
+
+
+
+Resource type 6 (font):
+ off len
+ 0x00 1 ?
+ 0x01 1 ?
+ 0x02 1 LONIBBLE:
+ HINIBBLE:
+ 0x03 48
+
+The letters are actually readable if you do 'xxd -b'; it shouldn't be too
+hard to RE this one.
+
+
+Resource type 7 (scenario):
+ off len
+ 0x00 16 Title (\0 terminated)
+ 0x10 ? Short description (\0 terminated)
+ ? ? Unknown (probably description of star systems, Space Spines,
+ fleets and bases (maybe random seeds?))
+ 0x80 840(?) Long description (\0 terminated)
+
+
+Resource type 8 (palette):
+ off len
+ 0 768 palette data:
+for each of the 256 entries (with index 0 through 255):
+ 1 red value
+ 1 green value
+ 1 blue value
+
+
+Resource type 9 (string):
+ off len
+ 0x00 2 Number of strings (MSB first)
+ 0x02 2 unknown (always 0x0000)
+for each string s:
+ 2 len[s]: length of the string (MSB first)
+for each string s:
+ len[s] String data (not '\0'-terminated)
+
+
+starcon.exe:
+compressed using lzexe
+(http://fabrice.bellard.free.fr/lzexe.html)
+Using PLINK86 to load starcon.ovl as an overlay.
+
+
+
+The Amiga version of SC1:
+
+Resource types used in starcon.pkg:
+ 1 - key config (presumed; different from the DOS version)
+ 2 - graphics
+ 3 - graphics
+ 4 - graphics
+ 5 - graphics
+ 6 - font
+ 7 - scenario (as with the DOS version)
+ 8 - strings as on DOS, but also other data in the same format
+ (presumably including sound)
+
+Files of types 2, 3, 4, 5, 8 may be compressed as in the DOS version.
+
+Graphics files are in a different file format as on DOS. I haven't worked
+on these files yet.
+
+
+Initial version created on 2007-06-01 by Serge van den Boom.
+
+
diff --git a/doc/devel/script b/doc/devel/script
new file mode 100644
index 0000000..07dbf0f
--- /dev/null
+++ b/doc/devel/script
@@ -0,0 +1,117 @@
+SCRIPT CONVENTIONS
+------------------
+
+The .txt files in the content/comm directories are unlikely to stay in
+their current form forever, as it's a rather fragile format. However,
+in the the meantime, and for those who seek to edit the script files
+(to conform to 3DO, PC, and/or director's cut versions).
+
+This file will describe the format, and how it relates to the source
+code in the src/sc2code/comm directory.
+
+The .txt files
+--------------
+
+The text files should all have a set of records, optionally separated
+by newlines. Each record has a header, then one or more lines of
+text.
+
+The header is a hash (#), an identifier in parentheses, and (if it's
+an alien voice) a tab, then the name of the file corresponding to that
+voice. Alien voices have identifiers in ALL_CAPITAL_LETTERS, while
+Zelnick's lines are in_lower_case. Often one line is broken into
+several parts - in these cases the full line is knitted together by
+the communications code (usually inserting the name of the Captain, or
+the flagship, or whatever).
+
+A modest example:
+
+#(HAVING_FUN_WITH_ILWRATH_2) thrad103.wav
+The exploding starships! The screaming crew!
+The direct hits, the cunning escapes!
+These are the moments we live for!
+Now we must return to the great battles!
+Farewell, Great Teacher.
+
+Zelnick's lines must be ON ONE LINE ONLY; line breaking is handled by
+the communication code and anything after the first newline is
+IGNORED. So don't do it while repairing his lines, and if you find
+one (a lowercase id with multiple lines following it) delete the
+newlines and make it all one line.
+
+It appears that newlines may appear in the middle of speeches;
+however, most of the lines by aliens have pauses represented by a
+single space or tab. It seems reasonable to duplicate this.
+
+When multiple records are used to define a single speech line (as
+often happens when they say your name, for instance), only the first
+line has an audio file associated with it.
+
+Lines that do not end in a punctuation mark or a space have a "..."
+added to the end of them by the communications code. If the previous
+line had "..." appended to it and this line does not START with a
+space, this line will have "..." prepended to it. The "scriptcheck"
+tool looks for all cases where "..." does not occur in midsentence.
+When editing the script files, check your intended results against
+this.
+
+The .h files (src/sc2code/comm)
+-------------------------------
+
+Each race has its own directory in src/sc2code/comm, and there is a
+file marked strings.h in each directory. This file defines a single
+enum which should list every record identifier in the appropriate
+race's .txt file over in content/comm/{race}, IN THE PRECISE ORDER
+THOSE RECORDS ARE GIVEN. Due to the non-symbolic nature of C, there
+is no relation whatsoever between the identifiers in the record and in
+the enum (though it would be reasonably straightforward to generate
+the strings.h files from the .txt files) The values of the enum are
+used in the {racec}.c files in the same directory.
+
+The scriptcheck utility also checks for proper correlation between the
+.h file and the associated .txt file. It assumes that one enum value
+is listed per line, and that the general format of the file matches
+the current one.
+
+Types of script bugs
+--------------------
+
+Script bugs can fall into three broad categories.
+
+- Voice/Speech mismatch. These are easy. The wrong audio file is
+ associated with this clip. Merely change the clip to make it fit.
+ If a clip is expected but is not specified, this appears to crash the
+ game. Example: The Zoq-Fot-Pik's "Goodbye Captain." "See ya." lines
+ had no clips associated with them, which both caused the game to loop
+ forever on those lines and misaligned all clips after that so that the
+ voices did not match the subtitles.
+
+- Subtitling error. These are also easy. The voice and text more or
+ less match, but the phrasing is slightly different. This is also
+ easy. Change the text to match. If the speech is *wildly* different,
+ make sure that it's not a misfiled audio file. NOTE: The PC and 3DO
+ versions had slightly different texts, and the texts we are working
+ with here match neither one. The voices are to be taken as the
+ ultimate authority on the 3DO text.
+
+- Communications Logic errors. Basically, this means the enum in the
+ appropriate strings.h was defined wrong, or, worse, was misused by the
+ {race}c.c file. One fixed example was the Spathi Ruling Council (Race
+ name: spahome), where strings.h defined *two* enums, one for the
+ Captain's lines, one for the Spathi. This would have horribly garbled
+ everything were it not for the fact that it made their initial
+ challenge and your responses invalid, thus causing the game to lock up
+ on your first visit. An example of one of these that made it into the
+ final game (PC version, anyway) is when the Umgah are trying to reward
+ you as Great Hero - the responses for the "I act purely from largesse"
+ and "Yep! You guys owe me BIG time" are clearly reversed. No
+ decision has yet been made on how to handle these (whether to
+ reproduce them precisely, or fix them, or only fix them in a
+ "director's cut" which would presumably require input from the
+ director) so leave them alone for now unless they crash the game. (To
+ my knowledge, the only truly serious error of this type was the Spathi
+ Homeworld, which has since been repaired.)
+
+
+
+ (Initial version: Michael Martin, 10/10/02)
diff --git a/doc/devel/sfx b/doc/devel/sfx
new file mode 100644
index 0000000..67a29d5
--- /dev/null
+++ b/doc/devel/sfx
@@ -0,0 +1,202 @@
+The Ur-Quan Masters Sound Effects
+
+Path/File/Duplicates Description
+=========================== ============================================================
+androsyn
+ androsyn/primary.wav Molecular acid (bubble sounds)
+ androsyn/secondary.wav Blazer form (comet "burner")
+
+arilou
+ arilou/primary.wav Ventral auto-aiming laser (yellow laser)
+ (lastbat/primary.wav)
+ arilou/secondary.wav Shortrange hyperdriver (transporter)
+ (lastbat/secondary.wav)
+
+blackurq
+ blackurq/fightret.wav not used
+ (urquan/fighter_get.wav)
+ blackurq/fightzip.wav not used
+ (ipanims/land_sht.wav)
+ (urquan/fighter_laser.wav)
+ blackurq/primary.wav Spinning blade
+ blackurq/secondary.wav F.R.I.E.D. Emitter plasma
+
+chenjesu
+ chenjesu/dogibark.wav D.O.G.I. hit (kind of "space" dog bark)
+ chenjesu/dogidie.wav D.O.G.I. dies (kind of "space" dog whine/yelp)
+ chenjesu/primary.wav Photon crystal shard firing
+ chenjesu/secondary.wav D.O.G.I. launching, low humming
+ chenjesu/sharpnel.wav Photon crystal shard explode (sharp sound)
+
+chmmr
+ chmmr/primary.wav Terawatt Laser (sharp "crystal" phaser beam)
+ chmmr/secondary.wav Tractor beam hum (cut resonance)
+
+druuge
+ druuge/primary.wav High-recoil cannon (a bit like shotgun)
+ (orz/primary.wav)
+ druuge/secondary.wav "Aarrghf" sacrifice scream
+
+human
+ human/primary.wav Nuclear warhead (rocket)
+ human/secondary.wav Point defence laser shot (white laser)
+
+ilwarth
+ ilwarth/cloak.wav Cloacking hum (quite bassy)
+ ilwarth/primary.wav Hellfire (flame thrower)
+ ilwarth/uncloak.wav Decloacking hum (less bassy, and sounds a bit like reversed clock.wav)
+
+ipanims
+ ipanims/land_awa.wav Lander takes of from the planet surface
+ ipanims/land_bit.wav Lander gets bitten by bio (teeth clank)
+ (vux/limpet_bite.wav)
+ ipanims/land_can.wav Bio canned by stun shot (weird sound)
+ ipanims/land_die.wav Lander explodes (long explosion)
+ (lbm/shipdies.wav)
+ ipanims/land_ful.wav Lander cargo hold full, cannot pick up ("burp")
+ ipanims/land_get.wav Lander picks up item/mineral (sounds like somone sucking)
+ ipanims/land_hit.wav Lander gets hit by something (snappy sound)
+ ipanims/land_hot.wav Firelava hot hum on planet surface
+ (thradd/secondary.wav)
+ ipanims/land_hrt.wav Lander crew dies (just "ugh" human sound)
+ ipanims/land_lau.wav Lander launching
+ (mmrnmhrm/primaryy.wav)
+ ipanims/land_lig.wav Lightning on planet surface
+ ipanims/land_qua.wav Earthquake on planet surface
+ ipanims/land_sht.wav Lander blaster shot
+ (urquan/fighter_laser.wav)
+ (blackurq/fightzip.wav)
+
+lastbat
+ lastbat/primary.wav not used
+ (arilou/primary.wav)
+ lastbat/secondary.wav not used
+ (arilou/secondary.wav)
+
+lbm
+ lbm/boom1.wav Tiny hit to planet/asteroid on melee (same sound, but higher pitch as ipanims/land_hit.wav)
+ ((ipanims/land_hit.wav))
+ lbm/boom23.wav Small hit to planet/asteroid on melee
+ lbm/boom45.wav Larger hit to planet/asteroid on melee
+ lbm/boom67.wav Big hit/explosion to planet/asteroid on melee
+ lbm/getcrew.wav Get crew back to ship (Syreen called crew) (notes: should be in syreen/ ?)
+ lbm/menusnd01.wav Enter menu item
+ lbm/menusnd02.wav Select menu item
+ lbm/menusnd03.wav Cannot do (cancel) menu item (same as sis_ship/secondary.wav, but with echo)
+ lbm/menusnd04.wav Use device
+ (yehat/secondary.wav)
+ lbm/shipdies.wav Ship explosion (long explosion)
+ (ipanims/land_die.wav)
+
+melnorme
+ melnorme/primary.wav Confusion Ray (same as melnorme/secondary.wav, but reversed and one octave higher)
+ melnorme/secondary.wav Powerblaster (synth bass slap a like)
+
+mmrnmhrm
+ mmrnmhrm/primaryx.wav Laser cannon (sharp red laser beam)
+ mmrnmhrm/primaryy.wav Rocket launcher
+ (ipanims/land_lau.wav)
+ mmrnmhrm/secondary.wav Transformer
+
+mycon
+ mycon/primary.wav Plasma (long sound)
+ mycon/secondary.wav Crew regeneration (strange howling)
+
+orz
+ orz/argh.wav High pitched "Argh"
+ orz/intruder.wav Echoed and reverbed "Intruder"
+ orz/primary.wav Howitzer cannon
+ (druuge/primary.wav)
+ orz/secondary.wav "Go!"
+ orz/zap.wav Pulse cannon zap
+
+pkunk
+ pkunk/insult01.wav "Baby"
+ pkunk/insult02.wav "Dou-Dou"
+ pkunk/insult03.wav "Fool"
+ pkunk/insult04.wav "Idiot"
+ pkunk/insult05.wav "Jerk"
+ pkunk/insult06.wav "Looser"
+ pkunk/insult07.wav "Moron"
+ pkunk/insult08.wav "Nerd"
+ pkunk/insult09.wav "Nitwit"
+ pkunk/insult10.wav "Stupid"
+ pkunk/insult11.wav "Twig"
+ pkunk/insult12.wav "Whimp"
+ pkunk/insult13.wav "Worm"
+ pkunk/insult14.wav "Dummy"
+ pkunk/primary.wav Small blaster gun
+ (spathi/primary.wav)
+ (zoqfot/primary.wav)
+ pkunk/rebirth.wav Short piece of Handel played on Pkunk resurrection
+
+shofixti
+ shofixti/primary.wav Blaster gun
+ (thradd/primary.wav)
+ shofixti/secondary.wav Self-destruct, explosion and "ayeee!" yell
+
+sis_ship
+ sis_ship/primary.wav Precursors gun
+ sis_ship/secondary.wav Cancel sound, almost the same as lbm/menusnd03.wav, but no delay echo
+ (spathi/secondary.wav)
+
+slyland
+ slyland/primary.wav Electric discharger (kind of lightning)
+ slyland/secondary.wav Robotic "Energize"
+
+spathi
+ spathi/primary.wav Small blaster gun
+ (pkunk/primary.wav)
+ (zoqfot/primary.wav)
+ spathi/secondary.wav Rear launcher
+ (sis_ship/secondary.wav)
+
+supox
+ supox/primary.wav Sprout Gun
+
+syreen
+ syreen/primary.wav Partical Beam Stiletto
+ syreen/secondary.wav Syreen call
+
+thradd
+ thradd/primary.wav Blaster gun
+ (shofixti/primary.wav)
+ thradd/secondary.wav Afterburner
+ (ipanims/land_hot.wav)
+
+umgah
+ umgah/primary.wav Antimatter (like shaver)
+ umgah/secondary.wav Retro Propulsion (Zap sound)
+
+urquan
+ urquan/fighter_get.wav Fighter returning (a bit like end of tincan hit reversed)
+ (blackurq/fightret.wav)
+ urquan/fighter_laser.wav Fighter laser
+ (ipanims/land_sht.wav)
+ (blackurq/fightzip.wav)
+ urquan/primary.wav Photon torpedo (Star Trek sound)
+ urquan/secondary.wav Low pitched voice "Launch fighters"
+
+utwig
+ utwig/primary.wav Wide area guns (Low humming)
+ utwig/secondary.wav Battery (sounds a bit like reversed water drops)
+ utwig/shieldbattgain.wav Battery gain (sounds a bit like reversed water drops, plus some hum)
+
+vux
+ vux/limpet_bite.wav Limpet attaching to ship hull
+ (ipanims/land_bit.wav)
+ vux/primary.wav Gigawatt laser (beam sound)
+ vux/secondary.wav Limpet launch (reversed *plup* sound)
+
+yehat
+ yehat/primary.wav Rapid fire pulse cannon
+ yehat/secondary.wav Shield generator
+ (lbm/mainmenu04.wav)
+
+zoqfot
+ zoqfot/primary.wav Antimatter spray gun
+ (spathi/primary.wav)
+ (pkunk/primary.wav)
+ zoqfot/secondary.wav Plasma injector tongue ("yak" voice)
+
+
diff --git a/doc/devel/statefiles b/doc/devel/statefiles
new file mode 100644
index 0000000..3007bdf
--- /dev/null
+++ b/doc/devel/statefiles
@@ -0,0 +1,123 @@
+ Ur-Quan Masters State Files
+ ---------------------------
+
+Statefiles are a legacy component of the UQM runtime and savegame
+format. They represent largish (10-64KB) chunks of semi-structured
+data that the engine used to keep on disk during gameplay, checking
+and updating it as needed. These files were then dumped into and
+restored from save files in a compressed form.
+
+In UQM as it exists now (0.7), these files exist as expandable memory
+arrays that are consulted as if they were files. UQM 0.8 will change
+the savegame format to remove the compression (64K just isn't much
+anymore) and put more structure to the data within. The statefile
+abstraction itself is not guaranteed to be retained, and indeed core
+team considers it kind of horrible and would like to destroy it.
+
+There are three state files.
+
+ STARINFO_FILE aka "starinfo.dat"
+ --------------------------------
+
+This is probably the most reasonable of the three. It keeps track of
+which star systems you have visited, and which mineral deposits and
+interesting life forms and gadgets you have harvested from the worlds
+therein.
+
+The file begins with one DWORD for every star system in the
+game. (There are 502 star systems, defined in a gigantic array in
+starmap_array in plandata.c). The DWORD is 0 if the star system is
+unvisited. It is otherwise an absolute offset within the state file.
+
+Generally speaking, UQM star systems are procedurally generated with a
+PRNG and various properties of the star including its type and
+location. Thus, the information in starmap.c is sufficient to provide
+an accounting of the number and quality of worlds in any given
+system. Each world can have up to 32 each of mineral deposits, energy
+signatures, or life forms. Thus, each world, in order, in the system
+will be listed at its offset with three DWORDS, representing mineral,
+energy, and biological entities respectively. Captured entities have a
+1 bit set.
+
+With a little over 3,800 visitable celestial bodies, this state file
+is capped at a little under 50 KB.
+
+ RANDGRPINFO_FILE aka "randgrp.dat"
+ ----------------------------------
+
+This is a "battle group file" - it tracks the information regarding
+groups of ships that you can encounter in interplanetary space. This
+file gives the location information for all ships in the last solar
+system you visited, and it tracks the fleet composition, health, &c
+for ships randomly generated due to visiting a solar system in some
+species's sphere of influence. Random battle groups are reset after a
+week in HyperSpace or upon arrival in some other star system.
+
+The data structures, and the reader/writer functions for them, are
+primarily defined in grpinfo.c.
+
+The RANDGRPINFO file starts with a GROUP_HEADER struct, specifying
+which star this information is for, when the data expires, and then 65
+offsets into the file. This is a *one-indexed array* for
+randomly-generated groups.
+
+This is because the offset for group zero points to an entirely
+different data structure: the "Group List". This gives the starmap
+depiction and location on the Interplanetary map of every battle group
+in the system, whether it is randomly generated or pre-defined. This
+comprises two bytes (the ID of the most recently encountered group,
+and then the number of groups), followed by a series of 17-byte chunks
+representing battle groups. These are a byte indicating the race
+identifier of the fleet (battle groups can be mixed-composition, but
+only one ship appears on the map at a time; this specifies that)
+followed by 16 bytes that represent an IP_GROUP structure. See the
+Read/WriteIpGroup functions in gengrp.c for the exact layout in the
+virtual file. There's a lot of wasted space there, a legacy of the
+time when these files were actually structure dumps on 32-bit machines
+with very specific memory layouts.
+
+The offsets that are not Group Zero have a similar layout, interpreted
+differently. Each of these represents a single battle group. It
+retains the two-byte prologue, the second of which specifies the
+number of 17-byte chunks to follow. The first byte here is the
+displayed race identifier, again, and then each 17-byte chunk is that
+ship's particular race ID followed by a 16-byte representation of a
+SHIP_FRAGMENT.
+
+There are no requirements about order of layout or total size of this
+file; the only requirement is that there is a GROUP_HEADER at offset
+zero and that the extents described in the valid offsets do not
+overlap.
+
+ DEFGRPINFO_FILE aka "defgrp.dat"
+ --------------------------------
+
+This is a random-access scratch space for battle groups that are
+deliberately placed by the plot. There's one GROUP_HEADER in this
+file, somewhere, for each star system that has ever had predefined
+ships and that the player has visited. There is *no guarantee of any
+kind* as to where they are, a priori.
+
+This information instead lives within the game state array, a
+155-byte-long bitfield that is mostly used for storing plot events and
+event flags. 32-bit values within this array store the relevant
+offsets for their fleets, or a 0 if they have not yet been
+encountered. In vanilla UQM, there are 14 of these values,
+corresponding to the Ur-Quan Probe, the Zoq-Fot-Pik scout, the
+Shofixti Survivor, the Unzervalt Guardian, the Sa-Matra, and the nine
+Melnorme traders in TrueSpace. Each of these has a corresponding entry
+in the game state array that ends in _OFFS0. (Due to the
+implementation of GET_GAME_STATE, these values actually are stored as
+four eight-bit values each, but this can be ignored pretty much
+everywhere but the definition of the states themselves).
+
+If one of these offsets is non-zero, then that offset in the
+DEFGRPINFO_FILE will have a SHIP_FRAGMENT-based group definition in
+the same format as the ones in RANDGRPINFO_FILE.
+
+The Game State array uses 0 as a special value to mean "this
+predefined battle group has not yet been spawned." Because of that, 0
+is not a legal offset to place a GROUP_HEADER. To ensure that no
+GROUP_HEADER is placed there, a zero is written to the first byte of
+the file. That way, the first defined group (which, for vanilla UQM,
+will always be the Ur-Quan Probe) thus begins at offset 1.
diff --git a/doc/devel/strtab b/doc/devel/strtab
new file mode 100644
index 0000000..11170c2
--- /dev/null
+++ b/doc/devel/strtab
@@ -0,0 +1,76 @@
+This is the format for resources of type STRTAB. It contains a number of
+items of unspecified data (not necessarilly strings).
+This is used for game strings (extension .txt), colour tables (.ct),
+colour translation tables (.xlt), and sound-effect tables (.snd)
+
+Everything is stored MSB first unless otherwise specified.
+
+position length meaning
+ 4 0xffffffff if the file is uncompressed.
+ Otherwise, the file is compressed. When uncompressed, the
+ file complies with the rest of the format as described
+ below.
+ 2 Unused in file, always 0x0000
+ 2 number of items in the file (StringCount)
+
+Followed by:
+ In file:
+ 4 Placeholder, always 0x00000000
+ numitems times:
+ 4 length of string
+ In memory:
+ numitems times:
+ 4 offset from &StringCount to the string
+ followed by:
+ 4 offset from &StringCount until one char past the end
+ of the last string.
+
+For .ct files an item is as follows (new 256x24bit format):
+ 1 Index of first clut in this item.
+ 1 Index of last clut in this item.
+ For each clut:
+ 256 palette entries:
+ 1 red value
+ 1 green value
+ 1 blue value
+
+For old .ct files an item is as follows (obsoleted by new 256x24bit format):
+ 1 Index of first clut in this item.
+ 1 Index of last clut in this item.
+ For each clut:
+ 32 palette entries:
+ 2 bits 0-4: blue value
+ bits 5-9: green value
+ bits 10-14: red value
+ bit 15: specifies the interpolation mode for 3DO scaling
+ (is ignored now)
+The full palette contains 256 values, which are the original 32 values
+ multiplied by 1 to 8.
+
+
+For .ct files (planet surface version; in ipanims) an item is as follows:
+ 1 Index of first color in this colortab.
+ 1 Index of last color in this colortab.
+ Then for each color (6 bits per channel):
+ 1 bits 0-5: red value
+ 1 bits 0-5: green value
+ 1 bits 0-5: blue value
+The planet surface palette files were probably copied verbatim from DOS version
+and left alone because they do no exactly fit into the whole CLUT system.
+
+For .xlt files (planet surface; in ipanims) an item is as follows:
+ 2*3 3 elevation levels (not used, probably informational)
+ 1*256 256 colormap indices each corresponding to a particular
+ elevation level 0..255; only colormap indices 128..255
+ can be used currently because colormaps only define
+ colors 128..255
+The .xlt files combined with planet surface .ct files are used to select colors
+for planet surface rendering.
+
+
+For .snd files an item is as follows:
+ N-2 Signed, 8-bit, 1 channel PCM samples of the sound
+ effect, where N = (length of string)
+ 2 Sampling frequency of the sound, *LSB first*
+ (the frequencies themselves seem to be remnants of
+ the DOS version)
diff --git a/doc/devel/threads b/doc/devel/threads
new file mode 100644
index 0000000..5d1d65b
--- /dev/null
+++ b/doc/devel/threads
@@ -0,0 +1,165 @@
+The UQM Threading and Synchronization library
+
+This document describes the function and API for the many threading and
+synchronization routines that UQM uses. People attempting to port this
+to thread systems that aren't covered by SDL (such as OS 9, for
+instance) will find the necessary API descriptions here.
+
+#defines
+
+NAMED_SYNCHRO: When #defined, all synchronization objects are named.
+This should be kept on all the time, at least until 1.0.
+
+TRACK_CONTENTION: implies NAMED_SYNCHRO. Spits out status messages
+whenever a thread goes to sleep because of an object matching
+TRACK_CONTENTION_CLASSES.
+
+TRACK_CONTENTION_CLASSES: This is an ORring of enums defined in
+threadlib.h.
+
+Constructs
+----------
+
+The operation of each construct is given; these operations map to the
+API in fairly straightforward ways.
+
+The locking constructs have an argument called "sync_class"; this
+indicates which value must be defined in TRACK_CONTENTION_CLASSES to
+see reports from this object. Valid values are SYNC_CLASS_TOPLEVEL
+for game logic synchronizers, SYNC_CLASS_AUDIO and SYNC_CLASS_VIDEO
+for audio and video systems, and SYNC_CLASS_RESOURCE for low-level
+resource allocators like memory systems.
+
+- Task
+
+This is the construct that the UQM game logic sees. In our
+multithreaded code tasks map directly to threads. A task is
+"assigned" to be started. One of its arguments demands that a stack
+size be specified; UQM ignores this.
+
+Tasks can voluntarily yield their timeslice by calling TaskSwitch().
+This is mandatory inside busywait loops; otherwise priority inversion
+problems surface under BSD and even on other systems it causes undue
+CPU utilization.
+
+Tasks have "states" that can be read or modified by various other
+threads. The only state that is ever checked in the UQM code is
+TASK_EXIT, which is set when the task needs to be shut down.
+
+Task functions themselves return an integer and take a void pointer
+that can be cast to "Task". This is a reference to the Task itself,
+and is used to check its own state and properly de-initialize itself.
+
+The last thing a Task function must do before exiting is call
+FinishTask.
+
+If another thread wishes to terminate a Task, it can call
+"ConcludeTask" upon it. ConcludeTask will wait for the Task to
+recognize the TASK_EXIT state and exit; this can produce deadlocks if
+the thread requestion the Task's termination is holding a resource
+that the concluding Task needs. Program with care.
+
+API:
+Task AssignTask (ThreadFunction task_func, SDWORD Stacksize,
+ const char *name);
+DWORD Task_SetState (Task task, DWORD state_mask);
+DWORD Task_ClearState (Task task, DWORD state_mask);
+DWORD Task_ToggleState (Task task, DWORD state_mask);
+DWORD Task_ReadState (Task task, DWORD state_mask);
+void TaskSwitch (void);
+void FinishTask (Task task);
+void ConcludeTask (Task task);
+
+
+- Thread
+
+A somewhat more powerful and low-level construct than the Task.
+Threads carry a "ThreadLocal" data object with them - at present, this
+is a single Semaphore used for signaling the thread when it wants to
+sleep until some graphics have been rendered. Threads can be created
+with arbitrary data passed as an argument (in the form of the void *),
+and can request their own ThreadLocal object. Threads can also be put
+to sleep for various amounts of time. Waiting on a thread permits one
+to block a thread until another completes.
+
+API:
+Thread CreateThread (ThreadFunction func, void *data,
+ SDWORD stackSize, const char *name);
+void SleepThread (TimePeriod timePeriod);
+void SleepThreadUntil (TimeCount wakeTime);
+void TaskSwitch (void);
+void WaitThread (Thread thread, int *status);
+
+
+- Mutex
+
+The simplest form of lock. If a thread tries to lock a mutex, it will
+sleep if the mutex is already locked, and awaken once the mutex
+becomes available. A Mutex must be unlocked by the same thread that
+locked it, and a thread must never lock a mutex it has already locked
+(without unlocking it first).
+
+API:
+Mutex CreateMutex (const char *name, DWORD syncClass);
+void DestroyMutex (Mutex sem);
+void LockMutex (Mutex sem);
+void UnlockMutex (Mutex sem);
+
+- RecursiveMutex
+
+A somewhat more powerful version of the Mutex; this mutex may be
+locked multiple times by the same thread, but then to truly release it
+it must unlock it an equal number of times. The Draw Command Queue
+(DCQ) is protected by a recursive mutex. (This construct is
+occasionally called a "reentrant mutex.")
+
+API:
+RecursiveMutex CreateRecursiveMutex (const char *name,
+ DWORD syncClass);
+void DestroyRecursiveMutex (RecursiveMutex m);
+void LockRecursiveMutex (RecursiveMutex m);
+void UnlockRecursiveMutex (RecursiveMutex m);
+int GetRecursiveMutexDepth (RecursiveMutex m);
+
+- Semaphore
+
+Semaphores superficially resemble Mutexes; they are "set" and
+"cleared". An integer is associated with each semaphore. Clearing
+the semaphore raises the value by one; setting it decreases it by one.
+Attempting to set a semaphore that is at value 0 will sleep the thread
+until the semaphore is cleared.
+
+Semaphores are used in the code to sleep until another thread is
+finished doing something. They are used heavily by the FlushGraphics
+code and the thread handling routines. A Task in the game is
+dedicated to advancing the calendar when necessary; this task is put
+to sleep by the clock semaphore when the game is paused, the player
+goes into orbit or to the menu, or any of several other events that
+act to suspend the game clock.
+
+API:
+Semaphore CreateSemaphore (DWORD initial, const char *name,
+ DWORD syncClass);
+void DestroySemaphore (Semaphore sem);
+void SetSemaphore (Semaphore sem);
+void ClearSemaphore (Semaphore sem);
+
+- CondVar
+
+If a thread waits on a condition variable, it will go to sleep until
+some other thread tells that condition variable to signal a thread (or
+broadcast to all threads) that are waiting upon that variable. Our
+condition variables are weaker than the "standard" variables.
+Condition variables are generally used in conjunction with mutexes,
+but ours do not permit this synchronization and are only suitable for
+use if the condition variable will broadcast periodically. UQM has a
+condition variable associated with the DCQ that broadcasts whenever
+the queue is empty. Threads that attempt to write to the DCQ when the
+DCQ is full wait on this condition variable.
+
+API:
+CondVar CreateCondVar (const char *name, DWORD syncClass);
+void DestroyCondVar (CondVar);
+void WaitCondVar (CondVar);
+void SignalCondVar (CondVar);
+void BroadcastCondVar (CondVar);
diff --git a/doc/devel/timing b/doc/devel/timing
new file mode 100644
index 0000000..99aa62e
--- /dev/null
+++ b/doc/devel/timing
@@ -0,0 +1,66 @@
+1. Timing and Changes
+---------------------
+The current UQM timer runs on a 120 ticks/second clock, defined by the
+constant ONE_SECOND (in timelib.h). Theoretically, all code has been
+updated to use this constant where needed, so the timer precision can
+be increased to 1000, for example, to match the native SDL timer
+resolution.
+
+The following functions and all variables and constants used with them
+have been examined and patched where necessary.
+
+Functions that have something to do with time:
+ XFormColorMap
+ XFormPLUT
+ CycleColorMap
+ FadeMusic
+ SeedRandomNumbers
+ WaitForNoInput
+ GetTimeCounter
+ SleepThread
+ SleepThreadUntil
+
+Global vars:
+ GameClock
+
+Constants changed:
+ BATTLE_FRAME_RATE (element.h)
+ NUM_DELAYS (clock.c)
+ ACCELERATION_INCREMENT (gameinp.c)
+ IP_FRAME_RATE (solarsys.c)
+
+Constants added:
+ CLOCK_BASE_FRAMERATE (clock.c)
+ STEP_ACCEL_DELAY (pstarmap.c)
+ PLANET_SIDE_RATE (lander.c)
+
+All alien comm animation definitions (frame rates) were patched to take
+ONE_SECOND into account. So if some animations start to bug all of a
+sudden, you know where to look ;).
+
+The game-clock function SetGameClockRate() changed to use the rate
+defined by CLOCK_BASE_FRAMERATE and does not use ONE_SECOND now (and is
+not supposed to).
+
+
+2. Possible Rate Changes
+------------------------
+The PLANET_SIDE_RATE and IP_FRAME_RATE can be safely adjusted at this
+time. The BATTLE_FRAME_RATE needs more work.
+
+
+3. Battle rate
+--------------
+The BATTLE_FRAME_RATE constant (currently 24 fps) can be adjusted only
+after converting the rate counters for all ships used in melee. They
+are expressed in frames and *must* take BATTLE_FRAME_RATE into account.
+
+They are:
+ ENERGY_WAIT
+ TURN_WAIT
+ THRUST_WAIT
+ WEAPON_WAIT
+ SPECIAL_WAIT
+
+There is probably more that needs to be done to make it work properly
+with an altered BATTLE_FRAME_RATE. Expect more info to appear.
diff --git a/doc/devel/versions b/doc/devel/versions
new file mode 100644
index 0000000..4b3d36a
--- /dev/null
+++ b/doc/devel/versions
@@ -0,0 +1,42 @@
+This file lists the Subversion repository numbers that coincide with
+each release. You should be able to revert to any individual release
+by doing a checkout of that version. It is also possible to check out
+a tagged version of each major release, but this is deprecated.
+
+Major releases for versions 0.6.0 and before are identified by their
+tags in the CVS tree and correspond to source-release packages; all
+microversions are identified by the point at which uqmversion.h
+changed.
+
+Version 0.1: Revision 240
+Version 0.2: Revision 847
+Version 0.21: Revision 816
+Version 0.22: Revision 913
+Version 0.23: Revision 994
+Version 0.24: Revision 1036
+Version 0.3: Revision 1208
+Version 0.31: Revision 1220
+Version 0.32: Revision 1330
+Version 0.33: Revision 1440
+Version 0.34: Revision 1619
+Version 0.4.0: Revision 1814
+Version 0.4.1: Revision 1931
+Version 0.4.2: Revision 2049
+Version 0.4.3: Revision 2160
+Version 0.4.4: Revision 2196
+Version 0.5.0: Revision 2250
+Version 0.5.1: Revision 2309
+Version 0.5.2: Revision 2392
+Version 0.5.3: Revision 2436
+Version 0.5.4: Revision 2463
+Version 0.6.0: Revision 2627
+Version 0.6.1: Revision 2652
+Version 0.6.2: Revision 2669
+Version 0.6.3: Revision 2828
+Version 0.6.4: Revision 2869
+Version 0.6.5: Revision 3110
+Version 0.6.6: Revision 3143
+Version 0.6.7: Revision 3276
+Version 0.6.8: Revision 3334
+Version 0.6.9: Revision 3537
+Version 0.7.0: Revision 3631
diff --git a/doc/devel/voiceeffects b/doc/devel/voiceeffects
new file mode 100644
index 0000000..1d53e90
--- /dev/null
+++ b/doc/devel/voiceeffects
@@ -0,0 +1,20 @@
+Slylandro Probe
+---------------------------------------------------------------------------
+The voice of the Slylandro probe is "Bruce" from MacInTalk Pro. MacInTalk
+Pro requires a 68040 Mac, a Quadra or Performa, and System 7.3 minimum.
+Basilisk II emulator can do Quadra 900 well enough.
+
+The probe speech added to UQM was processed as follows:
+1) generated on Basilisk II v0.8.0.142 running System 7.5.3 Rev 2 on
+ Quadra 900. Words like "hundred" and "point" were mid-sentence to get
+ better intonation. Names of tens -- 20, 30, etc. -- were cut from number
+ phrases "twenty-five", "thirty-five", etc.
+2) captured at 44100 Hz
+3) post-processed with Audacity 1.3 beta; filters:
+ a) GVerb: room 40m, reverb time 0.1s, damping 0.85, input bandwidth 0.75,
+ dry signal +0dB, early reflection -22dB, trail level -30dB
+ b) Amplify: +2.5dB (depends on your capture level)
+ c) Bass boost: centered at 300 Hz, +4dB
+4) chopped up and exported at 11025 Hz
+
+