diff options
Diffstat (limited to 'doc')
45 files changed, 5946 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 Binary files differnew file mode 100644 index 0000000..0142f21 --- /dev/null +++ b/doc/devel/blue-gas-giant-pal.png 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
+
+
diff --git a/doc/users/manual.txt b/doc/users/manual.txt new file mode 100644 index 0000000..330d785 --- /dev/null +++ b/doc/users/manual.txt @@ -0,0 +1,799 @@ +THE UR-QUAN MASTERS v0.7 -- homepage: http://sc2.sf.net/ + +Welcome to this beta release of the Ur-Quan Masters port. This +document will tell you everything you need to play, even if you've +never played the original. + +For those of you who have played the original, read the first section +(starting the game and bug reports) and the last sections (Super Melee +and control summary), and you'll be good to go. + +STARTING THE GAME + +Simply invoke the executable from the directory you installed UQM in +to run the game. (Under Windows, this is uqm.exe; under Linux, it's +uqm.) This will use the default settings. The defaults and how to +change them are listed under COMMAND LINE OPTIONS, below. + +After a splash screen, you will see the main menu, which has five +options: + + - New Game: Begins a new Full Game. This is a galaxy-spanning space + adventure full of diplomacy, exploration, combat, high treason, + and low cunning. The introductory cutscenes will set the scene; + the THE STORY SO FAR section below provides more extensive + backstory for the curious. + + - Load Game: Restores a Full Game session that was saved earlier. + + - Super Melee!: Puts the game in Super Melee mode, where you may + hone your space combat skills or challenge your friends to fleet + battles. See the SUPER MELEE section below for details on this + section. + + - Setup: Lets you configure many options to customize your play + experience. Most options will take effect once you exit the setup + menu; a few specially marked options require you to restart UQM. + Setup options are preserved across sessions. The options are + described under COMMAND LINE OPTIONS, below. + + - Quit: Exits the program. + +COMMAND LINE OPTIONS + +The default options for an UQM install are 3DO music, 640x480 windowed +mode, and pure SDL graphics drivers. The initial defaults may vary on +the Windows install if you selected "Mimic PC" or "Mimic 3DO" as the +install type. You may pass various command line options to customize +your experience: + + -r 320x240 (or --res) + +Sets the screen resolution. Unless --opengl is set, the only valid +values are 640x480 and 320x240. + + -f (or --fullscreen) + +Uses full screen mode. Pretty straightforward. Usually good to +combine with -r 320x240 unless you're using a scaler. + + -w (or --windowed) + +Displays the game in a window. The opposite of --fullscreen. + + -o (or --opengl) + +Use OpenGL drivers. This produces higher-quality graphics, and may be +faster as well -- but it also may not work on older cards. It also +permits use of any screen resolution. + + -x (or --nogl) + +Do not use OpenGL drivers. This is more likely to run on systems with +poor or no 3D acceleration, and is often faster, especially on older +or less well supported cards. Only the 320x240 and 640x480 +resolutions are available when not using OpenGL. + + -k (or --keepaspectratio) + +Keep 4:3 aspect ratio when using custom resolutions. + + -c (or --scale=mode) + +Graphics scaling mode (bilinear, biadapt, biadv, triscan, hq or none). +Default is none. Try these to get smoother graphics with cost on +performance. + + -b (or --meleezoom=mode) + +Melee zooming mode (pc or 3do); 'step' is an alias for 'pc' and 'smooth' +is an alias for '3do'. Default is 3do. Slower machine owners can set it +to 'pc' to get better performance in melee. + + -s (or --scanlines) + +Simulates interlaced displays. + + -g (or --gamma) + +Sets gamma correction. 1.0 causes no change (unless your graphics card +is originally set to a different value). Higher than 1.0 makes the +image brighter, lower than 1.0 makes it darker. + + -p (or --fps) + +Print fps information in the status window. + + -C (or --configdir) + +Set the directory where the game will store the config data. + + -n (or --contentdir) + +Set the directory where the game will seek its data. + + -l (or --logfile) + +Set a file to receive the diagnostic information that would otherwise go +to the console. + + -h (or --help) + +Display a help message. + + -M (or --musicvol) + +Set music volume (0-100). + + -S (or --sfxvol) + +Set sound effects volume (0-100). + + -T (or --speechvol) + +Set speech volume (0-100). If set to 0, the game runs in 'no speech' +mode and the oscilloscope reacts to the music. + + -m 3do (or --music 3do) + +Use the 3DO remixed soundtrack for songs that were in fact remixed. +The default. + + -m pc (or --music pc) + +Use the .MOD based PC soundtrack everywhere. + + -q (or --audioquality) + +Can be "high", "medium", or "low". Specifies how nice the audio +sounds. Slower machines should lower the audio quality. + + --addon <addon> (no short version) + +Replace <addon> by the name of an add-on to enable in the game. See +the section 'ADD-ONS' below for details. + + --sound (no short version) + +Can be "openal", "mixsdl" or "none". Specifies which driver/mixer +to use. "openal" is only available when it has been compiled in. +It may produce higher-quality sound and will probably be faster, +but it is not very stable on linux platforms, and may not work +well with some sound cards. +Use "none" as a last resort if you cannot get other drivers to work, +or if you have no soundcard. + + --stereosfx (no short version) + +Enables positional sound effects in melee. Currently works only when +using openal. + + -u (or --nosubtitles) + +Disables subtitles. + + --cscan pc + +Use PC style planet information when scanning (text). Default. + + --cscan 3do + +Use 3DO style planet information when scanning (pictograms). + + --menu pc + +Use PC style menus (text) and 'CREW'/'BATT' in melee instead of icons. +Default. + + --menu 3do + +Use 3DO style menus (pictograms). + + --font pc + +Use PC style fonts and colors. +Default. + + --font 3do + +Use 3DO style fonts and colors. + + --scroll pc +Scroll voice-over/subtitles 1 page at a time when using left/right arrow keys +Default. + + --scroll 3do +Scroll voice-over/subtitles smoothly while holding down left/right arrow keys + + -i 3do (or --intro 3do) + +Use the 3DO intro and ending movies (if you have them). +The default. + + -i pc (or --intro pc) + +Use the PC intro and ending sequences and slide shows. These will be also +played if you do not have 3DO movies, regardless of -i option. + + --shield pc + +Use PC style static slave shield graphic. +Default. + + --shield 3do + +Use 3DO style throbbing slave shield graphic. This somewhat increases the +load on CPU while in orbit. Do not use if your CPU cannot handle that. + + --safe (no short version) + +Start the game in safe mode. Safe mode will ignore stored user settings, +like resolution, fullscreen mode, sound driver, etc. This is useful if +you have somehow wrecked your configuration files and cannot get to the +in-game setup menu to change the settings. + + +NOT OFFICIALLY SUPPORTED OPTIONS + +The following options may not exist in all builds and can change without +notice at any time. + + --accel (no short version) + +Can be "none", "detect", "mmx", "3dnow", "sse" (also "altivec" if/when +added; or other platforms). Specifies which platform accelerations +to use for graphics and sound, if any. All specific platform code can +only be used when compiled in. + + --netport1 <port> (no short version) + --netport2 <port> (no short version) + +Specifies the default port that the bottom or top player respectively +will connect to or accept incoming connections on. If this parameter +is not specified, 21837 will be used. This value can be changed later +in the SuperMelee Net menu. Your firewall needs to be set up to allow +TCP connections from/to the used port. + + --nethost1 <host> (no short version) + --nethost2 <host> (no short version) + +Specifies the default name or ip number of the host to connect to for +the bottom or player. If this parameter is not specified, UQM will +not attempt an outgoing connection, but instead listen for an incoming +connection. + + --netdelay (no short version) + +Set the default input delay (in frames). See the Super Melee section +for details. + + + BUG REPORTS + +After several years of enthusiastic testing, UQM has dramatically +improved its stability, but it is still beta software, and bugs +certainly still lurk. Upon finding a problem, we'd like you to report +it, but before you do, please do the following: + +- Try to isolate what causes it: "Crashes with a null dereference + about half the time when firing and taunting with a Pkunk" is better + than "Melee doesn't work." If the game crashes, notice what error + is produced; if the game hangs, check to see if the game-exit key + (F12) works. + +- Go to the bug database at http://bugs.uqm.stack.nl/ + and post a report of the problem there. Search the database first if + it has been already posted; if we get many duplicate reports, processing + them eats our time from actual development. If it's been reported, and + you have more information, feel free to confirm that you've reproduced it + by adding a comment to the report. If ten people have already confirmed it, + though, it's probably best to treat it as duly reported. + +- Whenever possible, for bugs that only occur under certain conditions, + include a save game with your bug report that duplicates the bug. + In the case of a crash, a stack trace can be very helpful for us too. + If you don't know what a stack trace is, don't worry about it. + +- If your issue is more like "support request" than bug report and you + want help from other users, then posting it to our forum might be + more appropriate: http://uqm.stack.nl/forum/ + + + + THE STORY SO FAR + +For the past decade, Earth and the rest of the Alliance of Free Stars +has fought the Ur-Quan and their Hierarchy of Battle Thralls. In the +course of the War, the Earthlings discovered a factory world by the +'Precursors' - an impossibly advanced that disappeared tens of +thousands of years ago. This colony, Unzervalt (aka Vela I), lost all +contact with Earth shortly after landfall. + +You are Captain Zelnick, a human that was born on Unzervalt and who +possesses a remarkable knack for Precursor technology. You were the +one who worked out how to activate the Precursor installation. + +It was a factory for building starships. However, Unzervalt is +mineral-poor, and there were not enough materials available to +construct a complete vessel. Your task is to command this craft, the +Vindicator, and return to Earth to tell them of the abandoned colony. +Also, if the War with the Ur-Quan continues, you must fight for Earth +and the Alliance as best you can. + +There is a great deal more to this story. Asking Starbase Commander +Hayes for background information will give you most of it. + + INTERPLANETARY EXPLORATION + +When in a Solar system, use the thrust and steering controls to move +about the system. Intersecting a planet will move you to the +planetary system; flying over a planet or moon will then put you into +orbit. From there you can talk to the inhabitants, or, if the planet +is uninhabited, send a lander down to gather minerals, investigate +energy readings, or capture life forms. + + PLANET LANDING + +To land on a planet, you need to achieve orbit, then fill a planet +lander with crew and send them down. You will usually want to scan +the planet first. Mineral scans will indicate easily harvestable +mineral ores and other resources. Energy scans will indicate unusual +installations, which will effectively always be worth investigating. +Biological scans will show where life forms are on the surface. + +Minerals are necessary for building up and maintaining your flagship, +so harvest them wherever you can. There are nine varieties, each +color coded: + +COMMON ELEMENTS (carbon, nitrogen) are cyan. Worth 1 resource unit +(RU) per unit. + +CORROSIVES (chlorine, iodine) are red. 2 RU per unit. + +BASE METALS (iron, tin) are grey. These are common, and usually worth +harvesting, but not terribly valuable. 3 RU per unit. + +NOBLE GASSES (argon, xenon) are blue. 4 RU per unit. + +RARE EARTHS (lanthanum, ytterbium) are green. 5 RU per unit. + +PRECIOUS ELEMENTS (gold, silver) are yellow. 6 RU per unit. + +RADIOACTIVES (uranium, astatine) are orange. 8 RU per unit. + +EXOTICS (antimatter, magnetic monopoles) are purple, and a princely 25 +RU per cargo unit. + +Minerals may be unloaded at Earth Starbase by talking to Commander +Hayes, which will give you RU that you may spend to upgrade your +flagship. + +However, there are many hazards on planetary surfaces. Life forms are +often hostile, and need to be subdued with your stunner or evaded. +Earthquakes (expanding circles) can hurt your crew, lightning may +crisp them, or lava flows and hotspots can fry them. Be careful, +especially on hotter or more seismically and atmospherically active +worlds. If your crew level starts dropping dramatically, flee quickly +with the ESCAPE key! + +Stunned life forms may be captured and analyzed by your planet +landers. The information you gain from this may not be immediately +useful, but it will eventually come in handy. + +Landing on a planet costs fuel, and the heavier the planet, the more +fuel it requires. Make sure you don't spend so much fuel exploring +planets that you can't get back to Sol! + + INTERSTELLAR TRAVEL + +When you leave a solar system, you will push up into HyperSpace. In +HyperSpace you can travel great distances quickly, but you must +continuously thrust to move. Otherwise, you will gradually slow to a +stop. + +While you can fly about in HyperSpace just like you do in a star +system, the Galaxy is LARGE, and you will usually want to use the +Auto-Pilot. To use the Auto-Pilot, select "Starmap" on the menu. +This will show you a map of the quadrant (the galactic Core is in the +upper right corner). To fly to a location, move the cursor there and +press Enter. Then press Space to engage the Auto-Pilot. + + DIPLOMACY + +When you encounter an alien starship, you will usually get a picture +of their task force and a chance to choose between conversation and +fighting. If you choose to fight, you will transition immediately to +space combat (below). Otherwise, you will talk first. If talks go +poorly, space combat will likely ensue. + +If the task force shows ships streaming off in all directions, you +have reached a fortified world, and there are an unlimited number of +starships facing you. You cannot win such a fight - if combat ensues, +you will need to warp out. + + SPACE COMBAT + +When combat begins, you are prompted to select a ship from your task +force. A one-on-one space combat then begins, and continues until +either the enemy fleet is destroyed (in which case you salvage the +wrecks and continue the game), your flagship is destroyed (ending the +game), or your flagship warps out of combat (consuming 5 fuel units +but ending the encounter). + +Each ship has two major stats: Crew and Combat Battery. Crew are +effectively hit points. Getting hit by weapons kills crew, and if all +crew are eliminated, the craft is destroyed. Firing weapons typically +requires energy from the combat batteries, which is replaced over +time. The precise speed of energy regeneration and cost of weapons +fire varies by ship. + +Space flight is *mostly* inertial (you'll drift if you stop +thrusting), but each ship has a maximum velocity that can only be +exceeding by "gravity whipping" around the planet. Don't hit the +planet unless you want to take LOTS of damage. + +Each ship has a primary and secondary weapon mode, unique to that +race's craft. The descriptions of those follow. + + SHIP DESCRIPTIONS + + Androsynth Guardian +Primary weapon: Fires homing acid bubble clouds. +Secondary weapon: Transforms into the 'Blazer', a comet that does +considerable damage by ramming its opponents. + + Ariloulaleelay Skiff +Primary weapon: Auto-aiming, short-range laser +Secondary weapon: Random teleport +Note: The Skiff is inertia-less, and stops instantly when thrust is +removed. + + Chenjesu Broodhome +Primary weapon: Crystal Shard. Will travel until the fire button is +released, then shatters. +Secondary weapon: De-energizing Offensive Guided Interceptor. +Launches an autonomous DOGI that rams the opponent to drain their +combat batteries. + + Chmmr Avatar +Primary weapon: Immensely powerful short-range laser +Secondary weapon: Tractor beam. +Note: Has three orbiting "ZapSats" that attack anything that gets in +range. + + Druuge Mauler +Primary weapon: Long range, high-recoil cannon +Secondary weapon: Sets one crew on fire to gain combat energy. + + Earthling Cruiser +Primary weapon: Homing nuclear missile +Secondary weapon: Point-defense laser + + Ilwrath Avenger +Primary weapon: Short-range flamethrower +Secondary weapon: Cloaking device + + Kohr-Ah Marauder +Primary weapon: Spinning blades that stop and home when the fire +button is released +Secondary weapon: Fiery Ring of Inevitable and Eternal Destruction +(F.R.I.E.D.), a short-range corona of energy that blocks shots and +inflicts lots of damage + + Melnorme Trader +Primary weapon: Charged shot. The longer the fire button is held, the +stronger the shot. +Secondary weapon: Confusion beam that scrambles enemy controls. + + Mmrnmhrm X-Form +Primary weapon: Lasers (X-form) or homing missiles (Y-form). +Secondary weapon: Switch between X-Form and Y-Form. + + Mycon Podship +Primary weapon: Homing Plasmoid. +Secondary weapon: Regenerate 4 crew. + + Orz Nemesis +Primary weapon: Howitzer cannon. +Secondary weapon: Secondary with left and right arrows rotates the +primary cannon. Secondary with Primary launches space marines that +invade the enemy ship and kill their crew. + + Pkunk Fury +Primary weapon: Three-way cannon +Secondary weapon: Fling insults at opponent. This is the only way the +Pkunk can regenerate combat energy. +Note: On occasion, a destroyed Fury will be resurrected with full fuel +and power. + + Shofixti Scout +Primary weapon: Energy Dart. +Secondary weapon: Glory Device. When pressed three times, the ship +will self-destruct, inflicting vast damage on nearby vessels. + + Slylandro Probe +Primary weapon: Lighting weapon. +Secondary weapon: Absorb a nearby asteroid and convert to combat +power. This is the only way the Probe can recharge. +Note: The Probe is inertia-less and always in motion. Pressing thrust +will reverse its direction. + + Spathi Eluder +Primary weapon: Simple forward cannon. +Secondary weapon: Backward Utilized Tracking Torpedo (B.U.T.T.), a +homing missile fired from the rear of the vessel. + + Supox Blade +Primary weapon: Forward firing glob weapon +Secondary weapon: Secondary + left or right will cause you to drift +laterally, while Secondary + thrust will make you fly backwards. This +cancels your current velocity, so be careful! + + Syreen Penetrator +Primary weapon: Particle Beam Stiletto. +Secondary weapon: "Syreen Call" - psychic attack that induces enemy +crew to jump ship, where you (or your opponent) may capture them to +add to your complement + + Thraddash Torch +Primary weapon: Straightforward blaster cannon. +Secondary weapon: Afterburner. The afterburner exhaust does more +damage then the blaster, so use it as a weapon! + + Umgah Drone +Primary weapon: Anti-Matter cone. Does not require combat batteries to use. +Secondary weapon: Fly backwards suddenly and at high speed. +Note: The Drone only recharges batteries if you do not fire for a long +time, and then the energy all returns in one lump. + + Ur-Quan Dreadnought +Primary weapon: Fusion Blast. +Secondary weapon: Launches autonomous fighters to harrass the enemy. +When they run low on fuel, they will fly back to the Dreadnought. +Catch them before they expire. Each fighter requires one crew to +pilot it, so take care not to weaken the core ship. + + Utwig Jugger +Primary weapon: Six-shot cannon. Requires no combat battery energy to fire. +Secondary weapon: Force shield. Absorbing hits re-energizes your +batteries. When the batteries are exhausted, the shield is +permanently disabled until combat ends. + + VUX Intruder +Primary weapon: Gigawatt laser. +Secondary weapon: Limpet mines that track enemy ships and slow them +down dramatically if they hit. + + Yehat Terminator +Primary weapon: Twin autocannons. +Secondary weapon: Force shield. + + Zoq-Fot-Pik Stinger +Primary weapon: Anti-matter spray gun. +Secondary weapon: "Tongue attack", a point-blank range attack that +does grievous damage. + + SUPER MELEE + +Super Melee mode is pure combat. It's designed to let you hone your +skills for the full game, or to challenge your friends to fleet +matches. Selecting "Super Melee!" from the main menu will bring you +to the super melee main screen. + +This screen is dominated by the fleet design screen. Move the cursor +over a ship slot and press ENTER to change the ship assignment, or +press DELETE to remove the ship. You may select the fleet name and +press ENTER to edit the fleet name to something of your choice. The +number next to the fleet name lists the fleet strength; this is simply +the sum of the point values of all ships in the fleet. + +The right hand side of the screen has buttons for managing the battle. +Each side has four buttons associated with it: LOAD, SAVE, CONTROL, +and NET. The LOAD and SAVE buttons let you load and save fleets. A +variety of fleets of various strengths are pre-defined, and you may +add your own by saving fleets you design. + +The CONTROL button has one of five settings. HUMAN CONTROL puts the +fleet under the control of a human player. (The precise controls for +that player are set in the Setup menu, but the bottom player's +controls are always the same as the full game's controls.) Then there +are three levels of computer control: + + - WEAK CYBORG is not a particularly good shot, and will only use + special weapons if the ship absolutely requires the special weapon + to function at all (Pkunk, Slylandro). This difficulty level only + appears in the full game when fighting crippled ships. + + - GOOD CYBORG will actually use its special weapon, but it's still + not much of a threat. The Good cyborg provides a gentle + introduction to Star Control combat if you are unfamiliar with the + gameplay. However, you will soon wish to switch to... + + - AWESOME CYBORG. The AI will fully exploit each ship's abilities, + and is also a tolerably good shot, compensating for inertia and + choosing its shots. Enemies you meet in the full game are almost + always piloted at this level. If a battle is giving you trouble + in the full game, this is the setting you want. + +The last control option is NETWORK CONTROL, which will be set if that +side is controlled by a non-local opponent. To set up a network game, +push the NET button on the side you wish to be under your opponent's +control. + +In order to connect, you must agree on a port (the default is 21837, +which should not require any change) and set a net delay in frames. +To compensate for network lag, a keypress or keyrelease will only take +effect after this many frames. While higher values make your ship +seem to respond more sluggishly, they give the keypress information +more time to reach the remote party. If the game stutters, this is +because it is waiting for this keypress information to arrive, which +is an indication that the input delay is too low. Super Melee runs at +24 frames per second, each frame delayed will delay the input by about +42ms. The delay used is the maximum of the desired value for both +parties. The default is 2. Values lower than 4 are typically +acceptable in terms of responsiveness. Future versions may +automatically decide on the best value to use. + +Once the port and delay are set, one player must select the first +option (Wait for incoming connection), while the other enters his +opponent's hostname or IP address into the Host field and then pushes +"Connect." Once the connection is established, the control scheme for +the remote player will flip to NETWORK CONTROL to register the +connection. To disconnect, change it away back to one of the HUMAN or +CYBORG options. Once connected, you are both free to edit your fleets +to provide a properly balanced battle. + +Once all fleets are in readiness, press the BATTLE button in the +center right. (In a network game, both players must select it with no +intervening fleet edits. Moving away from BATTLE or having your +opponent change their fleet will cancel your readiness state, and you +will need to reselect the BATTLE button.) When all players are ready, +the battle begins. + +The ship selection screen is much as it would be in the full game, +with two notable exceptions: a question mark in the upper right allows +you to select a new ship randomly from those remaining, and a red X +allows you to exit the combat entirely. (It is also possible to exit +the melee at any time by pressing F10, just as one can exit anything.) +If nobody quits, the combat will continue until one side has been +completely destroyed. At this point, both fleets are shown so that +one may compare initial and remaining fleet strengths. Press a key to +return to the melee menu. + +To return to the main menu after finishing with Super Melee mode, push +the QUIT button in the lower right. + + GENERAL GAME CONTROLS SUMMARY + +F1 or PAUSE Pause game +F10 Exit game +F11 Toggle between fullscreen and windowed mode + + FULL GAME CONTROLS SUMMARY + + Space flight + +UP Thrust +LEFT and RIGHT: Steer +SPACE or RIGHT SHIFT: Main menu + + Menus + +Arrow Keys: Scroll through selections +ENTER or RIGHT CTRL: Make selection +SPACE or RIGHT SHIFT: Up one level + or ESCAPE + + Conversations + +LEFT and RIGHT: Rewind/Forward +UP and DOWN: Scroll through selections +ENTER or RIGHT CTRL: Make selection +SPACE or RIGHT SHIFT: Skip, Show/Hide summary + + Star Map + +Arrow Keys: Move the crosshair +ENTER or RIGHT CTRL: Select destination +SPACE or RIGHT SHIFT: Main menu +Keypad +: Zoom in +Keypad -: Zoom out +/ (not on the keypad): Begin search. + (Type star or constellation name to + find matches) +TAB: Jump to next match. + + Space Combat + +UP: Thrust +LEFT and RIGHT: Steer +RIGHT CTRL or ENTER: Fire Primary Weapon +RIGHT SHIFT: Fire Secondary Weapon +ESCAPE: Emergency Warp Escape + + + Planet Exploration + +UP: Forward +LEFT and RIGHT: Steer +RIGHT CTRL or ENTER: Fire stun bolt +RIGHT SHIFT or ESCAPE: Blast off + + + MELEE CONTROLS SUMMARY + + Top Player + +W: Thrust +A and D: Steer +V: Fire Primary Weapon +B: Fire Secondary Weapon + + Bottom Player + +UP or ENTER: Thrust +LEFT and RIGHT: Steer +RIGHT CTRL or ENTER: Fire Primary Weapon +RIGHT SHIFT: Fire Secondary Weapon + + +These controls are configurable from the Setup Menu. You may define +up to six "Input Templates" and assign a template to either or both +players. Some commonly used key configurations are pre-defined, as +well as popular variants. To change key bindings, select the binding +you wish to change and press ENTER. At the dialog box, press the key +(or joystick gesture) that you wish to assign to this action. + + + SAVED GAMES + +The saved games are kept in your personal directory for uqm data. +This directory is automatically created the first time you start the +game. The location of this directory varies per system. + +On Microsoft Windows systems this is a folder named 'uqm' in the +application data folder for the current user. +This is usually in one of the following locations: +- "C:\Windows\Application Data\" + (Windows 95, 98, SE without separate users) +- "C:\Windows\Profiles\YourName\Application Data\" + (Windows 95/98/SE with separate users) +- "C:\Documents and Settings\YourName\Application Data\" + (Windows NT/2k/XP) +The "Application Data" folder may be hidden. You can tell Windows to display +hidden files and folders in the Folder Options dialog, which you can +find in the Tools menu of any folder window. + +On Unix systems this personal uqm data is stored in "~/.uqm". + +You will generally only need this if you intend to transfer savegames +to another computer. Note that currently games saved on an PowerPC Mac +will not work on a PC (or an Intel Mac), and vice versa. AMD64 and +Intel savegames may be safely transferred. + + + ADD-ONS + +As of version 0.3, The Ur-Quan Masters has basic support for add-on +packages. Though it is not very elaborate yet, you can install some +content add-ons. Add-ons created for UQM releases prior to v0.7 are not +compatible with this release. To continue using your current add-ons, +you will have to obtain or create new add-on packages. + +Inside the directory where the content is installed, in the content/ +directory, there is a directory 'addons/'. In this directory, you can +place add-on packages, like 3domusic, 3dovoice, remix and others, or +create new directories with .zip files to be used in addition to the +standard content .zip files. Each add-on must contain at least one .rmp +file to tell the game which resources the add-on provides. +When you specify the command-line option '--addon <addon>', the .zip files +inside the directory content/addons/<addon> will be included +in the game. '--addon' may be specified more than once to enable multiple +add-ons. + +Unlike previous releases, 3domusic and 3dovoice are now standard add-ons, +and can be turned on and off from the in-game setup menu. +The Precursors UQM Remix project is intended to be used as an add-on. +If you install UQM 0.7 from the Windows installer, the remix packs +are available as options. The remix add-on can also be turned on and off +from the in-game setup menu. diff --git a/doc/users/unixinstall b/doc/users/unixinstall new file mode 100644 index 0000000..f08e26f --- /dev/null +++ b/doc/users/unixinstall @@ -0,0 +1,45 @@ +This document describes the installation procedure for a installation from +source on a Linux or BSD platform. + +1. +First, make sure all the required libraries are installed. +They are listed in the file INSTALL in the top dir. + + +2. +If you haven't done so already, download the content .uqm files packages +that you want, from where you got this source package. +You'll need uqm-0.7.0-content.uqm; uqm-0.7.0-3domusic.uqm (music from the 3DO +version) and uqm-0.7.0-voice.uqm (spoken alien dialogs) are optional. + +Put the uqm-0.7.0-content.uqm in the directory content/packages/ which exists +in the top directory of the source tree (the dir with (among others) +COPYING, src/, and build.var.in). +Put the optional music and voice packages in the content/addons/ directory. + + +3. +Run './build.sh uqm' +Change settings in the menu if you want. +The source building process will start, and when it ends, you should have +a file 'uqm' in the source dir (or uqm-debug if you selected a debug build). +You can try it out from this dir by typing './uqm' (or './uqm-debug'). + + +4. +Run './build.sh uqm install', and be patient. +Depending on what installation location you selected in the configuration +menu, you might need root permissions here. + + +5. +Done. +You can start the game now with the command 'uqm'. +You may also delete the source (with the .uqm files you put in +content/) if you want. + + +If you want to recompile with other options, you can use +'./build.sh uqm config' to reconfigure; you might need to do +'./build.sh uqm depend' afterwards. + diff --git a/doc/users/uqm.6 b/doc/users/uqm.6 new file mode 100644 index 0000000..9d9b38b --- /dev/null +++ b/doc/users/uqm.6 @@ -0,0 +1,985 @@ +.\" (C) 1992, 1993, 2002 Toys for Bob, Inc. +.\" The documentation may be used freely under the terms of the +.\" Creative Commons Attribution Attribution 2.0 license, +.\" available at http://creativecommons.org/licenses/by/2.0/ +.\" +.\" The content may also be copied freely as part of a distribution of +.\" The Ur-Quan Masters. +.Dd October 28, 2014 +.Dt UQM 6 +.Os +.Sh NAME +.Nm uqm +.Nd The Ur\(hyQuan Masters \(en space exploration game +.Sh SYNOPSIS +.Nm uqm +.Op Fl bcCfghklMnopqsSTuwx +.Op Fl i Ar style +.Op Fl m Ar soundtrack +.Op Fl r Ar resolution +.Op Fl -addon Ar addon +.Op Fl -cscan Ar style +.Op Fl -font Ar font +.Op Fl -menu Ar style +.Op Fl -safe +.Op Fl -scroll Ar style +.Op Fl -shield Ar style +.Op Fl -sound +.Op Fl -stereosfx +.Sh DESCRIPTION +.Nm uqm +is a port of the epic space game The Ur\(hyQuan Masters. +.Pp +The default settings for an +.Nm uqm +install are 3DO music, 640\(mu480 windowed mode, and pure SDL graphics drivers. +You may pass various command line options to customize your experience. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl b , Fl -meleezoom Ar mode +Melee zooming mode +.Po +.Sy pc +or +.Sy 3do +.Pc ; +.Sy step +is an alias for +.Sy pc +and +.Sy smooth +is an alias for +.Sy 3do . +Default is +.Sy 3do . +Slower machine owners can set it to +.Sy pc +to get better performance in melee. +.It Fl C Ar dir , Fl -configdir Ar dir +Sets the directory where the game will store the config data. +.It Fl c Ar mode , Fl -scale Ar mode +Graphics scaling mode +.Po +.Cm bilinear , +.Cm biadapt , +.Cm biadv , +.Cm triscan , +.Cm hq +or +.Cm none +.Pc . +Default is +.Cm none . +Try these to get smoother graphics, at a performance cost. +.It Fl f , Fl -fullscreen +Uses full screen mode. +The opposite of +.Fl w . +.It Fl g Ar val , Fl -gamma Ar val +Sets gamma correction. +1.0 causes no change +(unless your graphics card is originally set to a different value). +Higher than 1.0 makes the image brighter, lower than 1.0 makes it darker. +.It Fl h , Fl -help +Display a help message. +.It Fl i Ar style , Fl -intro Ar style +With +.Cm 3do , +use the 3DO intro and ending movies (if you have them). +With +.Cm pc , +use the PC intro and ending sequences and slide shows. +Defaults to +.Cm 3do . +Regardless of which option is selected, the PC sequences will be used if you do +not have the 3DO movies. +.It Fl k , Fl -keepaspectratio +Keep 4:3 aspect ratio when using custom resolutions. +.It Fl l Ar file , Fl -logfile Ar file +Set a file to receive the diagnostic information that would otherwise go to the +console. +.It Fl M Ar volume , Fl -musicvol Ar volume +Set music volume (0\(en100). +.It Fl m Ar soundtrack , Fl -music Ar soundtrack +Select either the 3DO remixed soundtrack with +.Cm 3do +or the .MOD\(hybased PC soundtrack with +.Cm pc . +Defaults to +.Cm 3do +for songs that were in fact remixed. +.It Fl n Ar dir , Fl -contentdir Ar dir +Set the directory where the game will seek its data. +.It Fl o , Fl -opengl +Use OpenGL drivers. +This produces higher\(hyquality graphics, and may be faster as well \(en +but it also may not work on older cards. +It also permits use of any screen resolution. +The opposite of +.Fl x . +.It Fl p , Fl -fps +Print fps information in the status window. +.It Fl q Ar setting , Fl -audioquality Ar setting +Can be +.Cm high , +.Cm medium , +or +.Cm low . +Specifies how nice the audio sounds. +Slower machines should lower the audio quality. +.It Fl r Ar resolution , Fl -res Ar resolution +Sets the screen resolution. +Unless +.Fl -opengl +is set, the only valid values are +.Dq 640x480 +and +.Dq 320x240 . +.It Fl S Ar volume , Fl -sfxvol Ar volume +Set sound effects volume (0\(en100). +.It Fl s , Fl -scanlines +Simulates interlaced displays. +.It Fl T Ar volume , Fl -speechvol Ar volume +Set speech volume (0\(en100). +If set to 0, the game runs in +.Sq no speech +mode and the oscilloscope reacts to the music. +.It Fl u , Fl -nosubtitles +Disables subtitles. +.It Fl w , Fl -windowed +Displays the game in a window. +The opposite of +.Fl f . +.It Fl x , Fl -nogl +Do not use OpenGL drivers. +This is more likely to run on systems with poor or no 3D acceleration, +and is often faster, especially on older or less well supported cards. +Only the 320\(mu240 and 640\(mu480 resolutions are available when not using +OpenGL. +The opposite of +.Fl o . +.It Fl -addon Ar name +Enable the named add\(hyon in the game. +See the +.Sx ADD\(hyONS +section for details. +.It Fl -cscan Ar style +When scanning planets, display information using text +.Pq with Cm pc +or pictograms +.Pq with Cm 3do . +Defaults to +.Cm pc . +.It Fl -font Ar style +Use PC\(hystyle fonts and colors +.Pq with Cm pc +or 3DO\(hystyle +.Pq with Cm 3do . +Defaults to +.Cm pc . +.It Fl -menu Ar style +In menus, display options as text +.Pq with Cm pc +or pictograms +.Pq with Cm 3do . +Defaults to +.Cm pc . +.It Fl -safe +Start the game in safe mode. +Safe mode will ignore stored user settings, +like resolution, fullscreen mode, sound driver, etc. +This is useful if you have somehow wrecked your configuration files and cannot +get to the in\(hygame setup menu to change the settings. +.It Fl -scroll Ar style +Using the left/right arrow keys, +scroll voiceovers and subtitles one page at a time +.Pq with Cm pc +or smoothly +.Pq with Cm 3do . +Defaults to +.Cm pc . +.It Fl -shield Ar style +Use the CPU\(hyintensive, 3DO\(hystyle throbbing slave shield graphic +.Pq with Cm 3do +or the PC\(hystyle static slave shield graphic +.Pq with Cm pc . +Defaults to +.Cm pc . +.It Fl -sound Ar driver +Specifies which sound driver/mixer to use. +Can be +.Cm openal , +.Cm mixsdl , +or +.Cm none . +.Cm openal +is only available when it has been compiled in. +It may produce higher\(hyquality sound and will probably be faster, +but it is not very stable on Linux platforms, +and may not work well with some sound cards. +Use +.Cm none +as a last resort if you cannot get other drivers to work, +or if you have no sound card. +.It Fl -stereosfx +Enables positional sound effects in melee. +Currently works only when using openal. +.El +.Sh STARTING THE GAME +Simply invoke the +.Nm uqm +program to run the game. +After a splash screen, you will see the main menu, which has five options: +.Bl -tag -width "Super Melee!" +.It New Game +Begins a new Full Game. +This is a galaxy\(hyspanning space adventure full of diplomacy, exploration, +combat, high treason, and low cunning. +The introductory cutscenes will set the scene; the below section +.Sx THE STORY SO FAR +provides more extensive backstory for the curious. +.It Load Game +Restores a Full Game session that was saved earlier. +.It Super Melee! +Puts the game in Super Melee mode, where you may hone your space combat skills +or challenge your friends to fleet battles. +See the +.Sx SUPER MELEE +section below for details on this game mode. +.It Setup +Lets you configure many options to customize your play experience. +Most options will take effect once you exit the setup menu; +a few specially marked options require you to restart +.Nm uqm . +Setup options are preserved across sessions. +.It Quit +Exits the program. +.El +.Sh CONTROLS SUMMARY +.Ss General Game Controls +.Bl -tag -width "F1 or Pause" -compact +.It Cm F1 No or Cm Pause +Pause game +.It Cm F10 +Exit game +.It Cm F11 +Toggle between fullscreen and windowed mode +.El +.Ss Full Game Controls +Space flight: +.Bl -tag -width "Space or Right Shift" -compact +.It Cm Up +Thrust +.It Cm Left No and Cm Right +Steer +.It Cm Space No or Cm Right Shift +Main Menu +.El +.Pp +Menus: +.Bl -tag -width "Space or Right Shift or Escape" -compact +.It Arrow keys +Scroll through selections +.It Cm Enter No or Cm Right Ctrl +Make selection +.It Cm Space No or Cm Right Shift No or Cm Escape +Up one level +.El +.Pp +Conversations: +.Bl -tag -width "Space or Right Shift" -compact +.It Cm Left No and Cm Right +Rewind/Forward +.It Cm Up No and Cm Down +Scroll through selections +.It Cm Enter No or Cm Right Ctrl +Make selection +.It Cm Space No or Cm Right Shift +Skip, Show/Hide summary +.El +.Pp +Star Map: +.Bl -tag -width "Space or Right Shift" -compact +.It Arrow Keys +Move the crosshair +.It Cm Enter No or Cm Right Ctrl +Select destination +.It Cm Space No or Cm Right Shift +Main menu +.It Keypad Cm + +Zoom in +.It Keypad Cm - +Zoom out +.It Cm / +Begin search. +(Type star or constellation name to find matches) +.It Cm Tab +Jump to next match +.El +.Pp +Space Combat: +.Bl -tag -width "Right Ctrl or Enter" -compact +.It Cm Up +Thrust +.It Cm Left No and Cm Right +Steer +.It Cm Right Ctrl No or Cm Enter +Fire Primary Weapon +.It Cm Right Shift +Fire Secondary Weapon +.It Cm Escape +Emergency Warp Escape +.El +.Pp +Planet Exploration: +.Bl -tag -width "Right Shift or Escape" -compact +.It Cm Up +Forward +.It Cm Left No and Cm Right +Steer +.It Cm Right Ctrl No or Cm Enter +Fire stun bolt +.It Cm Right Shift No or Cm Escape +Blast off +.El +.Ss Melee Controls +Top Player: +.Bl -tag -width "A and D" -compact +.It Cm W +Thrust +.It Cm A No and Cm D +Steer +.It Cm V +Fire Primary Weapon +.It Cm B +Fire Secondary Weapon +.El +.Pp +Bottom Player: +.Bl -tag -width "Right Ctrl or Enter" -compact +.It Cm Up No or Cm Enter +Thrust +.It Cm Left No and Cm Right +Steer +.It Cm Right Ctrl No or Cm Enter +Fire Primary Weapon +.It Cm Right Shift +Fire Secondary Weapon +.El +.Pp +These controls are configurable from the Setup Menu. +You may define up to six +.Dq Input Templates +and assign a template to either or both players. +Some commonly used key configurations are pre\(hydefined, +as well as popular variants. +To change key bindings, select the binding you wish to change and press +.Cm Enter . +At the dialog box, press the key (or joystick gesture) +that you wish to assign to this action. +.Sh SAVED GAMES +The saved games are kept in your personal directory for +.Nm uqm +data. +This directory is automatically created the first time you start the game. +On Unix systems this personal +.Nm uqm +data is stored in +.Pa ~/.uqm . +.Pp +You will generally only need to know this if you intend to transfer savegames +to another computer. +.Sh INTERPLANETARY EXPLORATION +When in a Solar system, +use the thrust and steering controls to move about the system. +Intersecting a planet will move you to the planetary system; +flying over a planet or moon will then put you into orbit. +From there you can talk to the inhabitants, or, if the planet is uninhabited, +send a lander down to gather minerals, investigate energy readings, +or capture life forms. +.Sh PLANET LANDING +To land on a planet, you need to achieve orbit, +then fill a planet lander with crew and send them down. +You will usually want to scan the planet first. +Mineral scans will indicate easily harvestable mineral ores and other +resources. +Energy scans will indicate unusual installations, +which will effectively always be worth investigating. +Biological scans will show where life forms are on the surface. +.Pp +Minerals are necessary for building up and maintaining your flagship, so +harvest them wherever you can. +There are nine varieties, each color coded: +.Bl -bullet +.It +.Em Common elements +(carbon, nitrogen) are cyan. +Worth 1 resource unit (RU) per unit. +.It +.Em Corrosives +(chlorine, iodine) are red. +2 RU per unit. +.It +.Em Base metals +(iron, tin) are grey. +These are common, and usually worth harvesting, but not terribly valuable. +3 RU per unit. +.It +.Em Noble gases +(argon, xenon) are blue. +4 RU per unit. +.It +.Em Rare earths +(lanthanum, ytterbium) are green. +5 RU per unit. +.It +.Em Precious elements +(gold, silver) are yellow. +6 RU per unit. +.It +.Em Radioactives +(uranium, astatine) are orange. +8 RU per unit. +.It +.Em Exotics +(antimatter, magnetic monopoles) are purple, +and a princely 25 RU per cargo unit. +.El +.Pp +Minerals may be unloaded at Earth Starbase by talking to Commander Hayes, +which will give you RU that you may spend to upgrade your flagship. +.Pp +However, there are many hazards on planetary surfaces. +Life forms are often hostile, and need to be subdued with your stunner or +evaded. +Earthquakes (expanding circles) can hurt your crew, +lightning may crisp them, or lava flows and hotspots can fry them. +Be careful, +especially on hotter or more seismically and atmospherically active worlds. +If your crew level starts dropping dramatically, +flee quickly with the +.Cm Escape +key! +.Pp +Stunned life forms may be captured and analyzed by your planet landers. +The information you gain from this may not be immediately useful, +but it will eventually come in handy. +.Pp +Landing on a planet costs fuel, and the heavier the planet, +the more fuel it requires. +Make sure you don\(cqt spend so much fuel exploring planets that you can\(cqt +get back to Sol! +.Sh INTERSTELLAR TRAVEL +When you leave a solar system, you will push up into HyperSpace. +In HyperSpace you can travel great distances quickly, +but you must continuously thrust to move. +Otherwise, you will gradually slow to a stop. +.Pp +While you can fly about in HyperSpace just like you do in a star system, +the Galaxy is +.Em Large , +and you will usually want to use the Auto-Pilot. +To use the Auto-Pilot, select +.Dq Starmap +on the menu. +This will show you a map of the quadrant +(the galactic Core is in the upper right corner). +To fly to a location, move the cursor there and press +.Cm Enter . +Then press +.Cm Space +to engage the Auto-Pilot. +.Sh DIPLOMACY +When you encounter an alien starship, you will usually get a picture of their +task force and a chance to choose between conversation and fighting. +If you choose to fight, you will transition immediately to space combat +(below). +Otherwise, you will talk first. +If talks go poorly, space combat will likely ensue. +.Pp +If the task force shows ships streaming off in all directions, you have reached +a fortified world, and there are an unlimited number of starships facing you. +You cannot win such a fight \(en if combat ensues, you will need to warp out. +.Sh SPACE COMBAT +When combat begins, you are prompted to select a ship from your task force. +A one-on-one space combat then begins, and continues until either the enemy +fleet is destroyed (in which case you salvage the wrecks and continue the +game), your flagship is destroyed (ending the game), or your flagship warps +out of combat (consuming 5 fuel units but ending the encounter). +.Pp +Each ship has two major stats: Crew and Combat Battery. +Crew are effectively hit points. +Getting hit by weapons kills crew, and if all crew are eliminated, +the craft is destroyed. +Firing weapons typically requires energy from the combat batteries, +which is replaced over time. +The precise speed of energy regeneration and cost of weapons fire varies by +ship. +.Pp +Space flight is +.Em mostly +inertial (you\(cqll drift if you stop thrusting), +but each ship has a maximum velocity that can only be exceeding by +.Dq gravity whipping +around the planet. +Don\(cqt hit the planet unless you want to take +.Em lots +of damage. +.Pp +Each ship has a primary and secondary weapon mode, +unique to that race\(cqs craft. +The descriptions of those follow. +.Ss Ship Descriptions +.Bl -ohang +.It Androsynth Guardian +.Bl -inset -compact +.It Primary weapon: +Fires homing acid bubble clouds. +.It Secondary weapon: +Transforms into the +.Sq Blazer , +a comet that does considerable damage by ramming its opponents. +.El +.It Ariloulaleelay Skiff +.Bl -inset -compact +.It Primary weapon: +Auto\(hyaiming, short\(hyrange laser. +.It Secondary weapon: +Random teleport. +.It Note: +The Skiff is inertia-less, and stops instantly when thrust is removed. +.El +.It Chenjesu Broodhome +.Bl -inset -compact +.It Primary weapon: +Crystal Shard. +Travels until the fire button is released, then shatters. +.It Secondary weapon: +De\(hyenergizing Offensive Guided Interceptor. +Launches an autonomous DOGI that rams the opponent to drain their combat +batteries. +.El +.It Chmmr Avatar +.Bl -inset -compact +.It Primary weapon: +Immensely powerful short-range laser. +.It Secondary weapon: +Tractor beam. +.It Note: +Has three orbiting +.Dq ZapSats +that attack anything that gets in range. +.El +.It Druuge Mauler +.Bl -inset -compact +.It Primary weapon: +Long range, high\(hyrecoil cannon. +.It Secondary weapon: +Sets one crew on fire to gain combat energy. +.El +.It Earthling Cruiser +.Bl -inset -compact +.It Primary weapon: +Homing nuclear missile. +.It Secondary weapon: +Point-defense laser. +.El +.It Ilwrath Avenger +.Bl -inset -compact +.It Primary weapon: +Short\(hyrange flamethrower. +.It Secondary weapon: +Cloaking device. +.El +.It Kohr\(hyAh Marauder +.Bl -inset -compact +.It Primary weapon: +Spinning blades that stop and home when the fire button is released. +.It Secondary weapon: +Fiery Ring of Inevitable and Eternal Destruction (F.R.I.E.D.), a short\(hyrange +corona of energy that blocks shots and inflicts lots of damage. +.El +.It Melnorme Trader +.Bl -inset -compact +.It Primary weapon: +Charged shot. +The longer the fire button is held, the stronger the shot. +.It Secondary weapon: +Confusion beam that scrambles enemy controls. +.El +.It Mmrnmhrm X\(hyForm +.Bl -inset -compact +.It Primary weapon: +Lasers (X-form) or homing missiles (Y-form). +.It Secondary weapon: +Switch between X-Form and Y-Form. +.El +.It Mycon Podship +.Bl -inset -compact +.It Primary weapon: +Homing Plasmoid. +.It Secondary weapon: +Regenerate 4 crew. +.El +.It Orz Nemesis +.Bl -inset -compact +.It Primary weapon: +Howitzer cannon. +.It Secondary weapon: +Secondary with left and right arrows rotates the primary cannon. +Secondary with Primary launches space marines that invade the enemy ship and +kill their crew. +.El +.It Pkunk Fury +.Bl -inset -compact +.It Primary weapon: +Three\(hyway cannon. +.It Secondary weapon: +Fling insults at opponent. +This is the only way the Pkunk can regenerate combat energy. +.It Note: +On occasion, a destroyed Fury will be resurrected with full fuel and power. +.El +.It Shofixti Scout +.Bl -inset -compact +.It Primary weapon: +Energy Dart. +.It Secondary weapon: +Glory Device. +When pressed three times, the ship will self\(hydestruct, +inflicting vast damage on nearby vessels. +.El +.It Slylandro Probe +.Bl -inset -compact +.It Primary weapon: +Lighting weapon. +.It Secondary weapon: +Absorb a nearby asteroid and convert to combat power. +This is the only way the Probe can recharge. +.It Note: +The Probe is inertia\(hyless and always in motion. +Pressing thrust will reverse its direction. +.El +.It Spathi Eluder +.Bl -inset -compact +.It Primary weapon: +Simple forward cannon. +.It Secondary weapon: +Backward Utilized Tracking Torpedo (B.U.T.T.), +a homing missile fired from the rear of the vessel. +.El +.It Supox Blade +.Bl -inset -compact +.It Primary weapon: +Forward firing glob weapon. +.It Secondary weapon: +Secondary + left or right will cause you to drift laterally, +while Secondary + thrust will make you fly backwards. +This cancels your current velocity, so be careful! +.El +.It Syreen Penetrator +.Bl -inset -compact +.It Primary weapon: +Particle Beam Stiletto. +.It Secondary weapon: +.Dq Syreen Call +\(en psychic attack that induces enemy crew to jump ship, +where you (or your opponent) may capture them to add to your complement. +.El +.It Thraddash Torch +.Bl -inset -compact +.It Primary weapon: +Straightforward blaster cannon. +.It Secondary weapon: +Afterburner. +The afterburner exhaust does more damage then the blaster, +so use it as a weapon! +.El +.It Umgah Drone +.Bl -inset -compact +.It Primary weapon: +Anti\(hyMatter cone. +Does not require combat batteries to use. +.It Secondary weapon: +Fly backwards suddenly and at high speed. +.It Note: +The Drone only recharges batteries if you do not fire for a long time, +and then the energy all returns in one lump. +.El +.It Ur\(hyQuan Dreadnought +.Bl -inset -compact +.It Primary weapon: +Fusion Blast. +.It Secondary weapon: +Launches autonomous fighters to harass the enemy. +When they run low on fuel, they will fly back to the Dreadnought. +Catch them before they expire. +Each fighter requires one crew to pilot it, +so take care not to weaken the core ship. +.El +.It Utwig Jugger +.Bl -inset -compact +.It Primary weapon: +Six\(hyshot cannon. +Requires no combat battery energy to fire. +.It Secondary weapon: +Force shield. +Absorbing hits re\(hyenergizes your batteries. +When the batteries are exhausted, +the shield is permanently disabled until combat ends. +.El +.It VUX Intruder +.Bl -inset -compact +.It Primary weapon: +Gigawatt laser. +.It Secondary weapon: +Limpet mines that track enemy ships and slow them down dramatically if they +hit. +.El +.It Yehat Terminator +.Bl -inset -compact +.It Primary weapon: +Twin autocannons. +.It Secondary weapon: +Force shield. +.El +.It Zoq\(hyFot\(hyPik Stinger +.Bl -inset -compact +.It Primary weapon: +Anti\(hymatter spray gun. +.It Secondary weapon: +.Dq Tongue attack , +a point\(hyblank range attack that does grievous damage. +.El +.El +.Sh SUPER MELEE +Super Melee mode is pure combat. +It\(cqs designed to let you hone your skills for the full game, +or to challenge your friends to fleet matches. +Selecting +.Dq Super Melee! +from the main menu will bring you to the super melee main screen. +.Pp +This screen is dominated by the fleet design screen. +Move the cursor over a ship slot and press +.Cm Enter +to change the ship assignment, or press +.Cm Delete +to remove the ship. +You may select the fleet name and press +.Cm Enter +to edit the fleet name to something of your choice. +The number next to the fleet name lists the fleet strength; +this is simply the sum of the point values of all ships in the fleet. +.Pp +The right hand side of the screen has buttons for managing the battle. +Each side has four buttons associated with it: +.Cm LOAD , +.Cm SAVE , +.Cm CONTROL , +and +.Cm NET . +The +.Cm LOAD +and +.Cm SAVE +buttons let you load and save fleets. +A variety of fleets of various strengths are pre\(hydefined, +and you may add your own by saving fleets you design. +.Pp +The +.Cm Control +button has one of five settings. +.Cm Human Control +puts the fleet under the control of a human player. +(The precise controls for that player are set in the Setup menu, but the bottom +player\(cqs controls are always the same as the full game\(cqs controls.) +Then there are three levels of computer control: +.Bl -bullet +.It +.Cm Weak Cyborg +is not a particularly good shot, and will only use special weapons if the ship +absolutely requires the special weapon to function at all (Pkunk, Slylandro). +This difficulty level only appears in the full game when fighting crippled +ships. +.It +.Cm Good Cyborg +will actually use its special weapon, but it\(cqs still not much of a threat. +The Good cyborg provides a gentle introduction to Star Control combat if you +are unfamiliar with the gameplay. +However, you will soon wish to switch to... +.It +.Cm Awesome Cyborg . +The AI will fully exploit each ship\(cqs abilities, and is also a tolerably +good shot, compensating for inertia and choosing its shots. +Enemies you meet in the full game are almost always piloted at this level. +If a battle is giving you trouble in the full game, +this is the setting you want. +.El +.Pp +The last control option is +.Cm Network Control , +which will be set if that side is controlled by a non\(hylocal opponent. +To set up a network game, push the +.Cm Net +button on the side you wish to be under your opponent\(hys control. +.Pp +In order to connect, you must agree on a port (the default is 21837, +which should not require any change) and set a net delay in frames. +To compensate for network lag, +a keypress or keyrelease will only take effect after this many frames. +While higher values make your ship seem to respond more sluggishly, +they give the keypress information more time to reach the remote party. +If the game stutters, this is because it is waiting for this keypress +information to arrive, which is an indication that the input delay is too low. +Super Melee runs at 24 frames per second, +each frame delayed will delay the input by about 42\ ms. +The delay used is the maximum of the desired value for both parties. +The default is 2. +Values lower than 4 are typically acceptable in terms of responsiveness. +Future versions may automatically decide on the best value to use. +.Pp +Once the port and delay are set, one player must select the first option +(Wait for incoming connection), while the other enters his opponent\(hys +hostname or IP address into the Host field and then pushes +.Dq Connect . +Once the connection is established, the control scheme for the remote player +will flip to +.Cm Network Control +to register the connection. +To disconnect, change it away back to one of the +.Cm Human +or +.Cm Cyborg options. +Once connected, +you are both free to edit your fleets to provide a properly balanced battle. +.Pp +Once all fleets are in readiness, press the +.Cm Battle +button in the center right. +(In a network game, both players must select it with no intervening fleet +edits. +Moving away from +.Cm Battle +or having your opponent change their fleet will cancel your readiness state, +and you will need to reselect the +.Cm Battle +button.) +When all players are ready, the battle begins. +.Pp +The ship selection screen is much as it would be in the full game, with two +notable exceptions: a question mark in the upper right allows you to select a +new ship randomly from those remaining, +and a red X allows you to exit the combat entirely. +(It is also possible to exit the melee at any time by pressing +.Cm F10 , +just as one can exit anything.) +If nobody quits, +the combat will continue until one side has been completely destroyed. +At this point, both fleets are shown so that one may compare initial and +remaining fleet strengths. +Press a key to return to the melee menu. +.Pp +To return to the main menu after finishing with Super Melee mode, push the +.Cm Quit +button in the lower right. +.Sh THE STORY SO FAR +For the past decade, Earth and the rest of the Alliance of Free Stars has +fought the Ur\(hyQuan and their Hierarchy of Battle Thralls. +In the course of the War, the Earthlings discovered a factory world by the +.Sq Precursors +\(en an impossibly advanced that disappeared tens of thousands of years ago. +This colony, Unzervalt (aka Vela I), +lost all contact with Earth shortly after landfall. +.Pp +You are Captain Zelnick, a human who was born on Unzervalt and who possesses a +remarkable knack for Precursor technology. +You were the one who worked out how to activate the Precursor installation. +.Pp +It was a factory for building starships. +However, Unzervalt is mineral\(hypoor, +and there were not enough materials available to construct a complete vessel. +Your task is to command this craft, the Vindicator, +and return to Earth to tell them of the abandoned colony. +Also, if the War with the Ur\(hyQuan continues, +you must fight for Earth and the Alliance as best you can. +.Pp +There is a great deal more to this story. +Asking Starbase Commander Hayes for background information will give you most +of it. +.Sh ADD\(hyONS +.Nm uqm +has basic support for add\(hyon packages. +Though it is not very elaborate yet, you can install some content add\(hyons. +Add\(hyons created for UQM releases prior to v0.7 are not compatible with this +release. +.Pp +Inside the directory where the content is installed, in the +.Pa content/ +directory, there is a directory +.Pa addons/ . +In this directory, you can place add\(hyon packages, like +.Sy 3domusic , +.Sy 3dovoice , +.Sy remix +and others, or create new directories with .zip files to be used in +addition te the standard content .zip files. +Each add\(hyon must contain at least one .rmp file to tell the game which +resources the add\(hyon provides. +When you specify the command\(hy line option +.Fl -addon Ar addon , +the .zip files inside the directory +.Pa content/addons/ Ns Ar addon +will be included in the game. +.Fl -addon +may be specified more than once to enable multiple add\(hyons. +.Pp +.Sy 3domusic , +.Sy 3dovoice , +and +.Sy remix +are intended to be used as add\(hyons, +and can be turned on and off from the in\(hygame setup menu. +.Sh BUGS +After several years of enthusiastic testing, +.Nm uqm +has dramatically improved its stability, but it is still beta software, +and bugs certainly still lurk. +Upon finding a problem, we\(cqd like you to report it, +but before you do, please do the following: +.Bl -bullet +.It +Try to isolate what causes it: +.Do +Crashes with a null dereference about half the time when firing and +taunting with a Pkunk +.Dc +is better than +.Dq Melee doesn\(cqt work . +If the game crashes, notice what error is produced; +if the game hangs, check to see if the game\(hyexit key +.Pq Cm F12 +works. +.It +Go to the +.Lk http://bugs.uqm.stack.nl/ "bug database" +and post a report of the problem there. +Search the database first to see if it has been already posted; if we get many +duplicate reports, processing them eats our time from actual development. +If it\(cqs been reported, and you have more information, feel free to confirm +that you\(cqve reproduced it by adding a comment to the report. +If ten people have already confirmed it, though, +it\(cqs probably best to treat it as duly reported. +.It +Whenever possible, for bugs that only occur under certain conditions, +include a save game with your bug report that duplicates the bug. +In the case of a crash, a stack trace can be very helpful for us too. +If you don\(cqt know what a stack trace is, don\(cqt worry about it. +.It +If your issue is more like +.Dq support request +than bug report and you want help from other users, +then it might be more appropriate to post it to +.Lk http://uqm.stack.nl/forum/ "our forum" . +.El |