# Release Notes for JFShadowWarrior

Release date: 9 October 2005
Official website

## New Features and Improvements

- A number of crash bugs have been fixed. Also, missing save game symbols from the previous release should be fixed in this release. Still, if the game reports missing symbols, please let me know.
- OpenGL voxels. You'll know them when you see them.
- Keys, mouse buttons, and video mode settings are configurable via in-game menus now. There are still the more advanced configuration features to be added yet, but they can still be adjusted via the external setup program for now.
- Improvements to the customisation facility to allow more options to be altered.

## Known Issues

- Multiplayer is not fully functional yet. Peer-to-peer mode appears to work fine, but master-slave mode is broken and has been disabled for this release.
- There are two rendering bugs I am aware of that will be fixed in a subsequent release:
  1. Level 1: the viewscreen to drive the silver key to the collection area is not working properly in GL Polymost mode, giving just a static texture. Switch to 8-bit mode temporarily to complete this section of the level.
  2. Level 2: in the pool of water at the end of the map which opens up a magic portal showing the next level, the sector-over-sector effect in the view beyond the portal malfunctions giving a shimmering sky area in the view.

## Save Help

I have written a new compiler and system-independent framework for saving and restoring the pointer information contained in Shadow Warrior's internal objects, and this has required a large amount of manual processing of the source code to pick out the data and functions in the game that need to be saved to disk. Because of this, I have quite likely missed some functions or data that are on a rare occasion required to properly save a game. If this happens, you will see a message after the save operation that reads:

    There was a problem saving. See "Save Help" section of release notes.

When this message is displayed, the game creates a file named `savegame symbols missing.txt` in the game directory containing information I require to be able to add the missing symbols into the game code for future saves. If you see the message, please send the file to me at jonof@edgenetwork.org so I may update the game.

## Customisation File Format

Historically, the modifications and total conversions for Shadow Warrior have been forced to resort to hacking the game executable with a hex editor to replace the names of maps and the episode title information. For this port I have introduced a customisation script file that is loaded on startup which achieves the same purpose as the EXE hacks once did. Customisation of weapon ammunition counts and other similar things will be added in the future as the need arises.

The customisation file should be named `SWCUSTOM.TXT` for the game to find it. The contents of the file may consist of these directives. Comments can be used by prefixing the text with a double forward-slash (C++ style), `//`, or surrounding the text with `/*` (comment here) `*/` (C style).

map number { ... }
level number { ... }
  Selects the map to change the information of. number is a value in the range of 1 to 29. Levels 1 to 4 are the shareware maps. level is a synonym for map. The brace-enclosed block may contain these directives:
  title title
  name title
  description title
    Sets the new title of the level to title. name and description are synonyms for title.
  filename filename
  file filename
  fn filename
  levelname filename
    Sets the new map file name to filename. file, fn, and levelname are synonyms for filename.
  song filename
  music filename
  songname filename
    Sets the new MIDI file name to filename. music and songname are synonyms for song.
  cdatrack tracknum
  cdtrack tracknum
    Sets the Red-Book CD track number to tracknum. cdtrack is a synonym for cdatrack.
  besttime seconds
  partime seconds
    Sets the "best" and "par" times of the level respectively. seconds is the new par time given as a count of seconds.
episode number { ... }
  Selects the episode to change the information of. number is a value in the range of 1 to 2. The brace-enclosed block may contain these directives:
  title title
  name title
  description title
    Sets the new title of the episode to title. name and description are synonyms for title.
  subtitle subtitle
    Sets the new subtitle of the episode to subtitle.
skill number { ... }
  Selects the skill level to change the information of. number is a value in the range of 1 to 4. The brace-enclosed block may contain this directive:
  title title
  name title
  description title
    Sets the new title of the skill level to title. name and description are synonyms for title.
inventory number { ... }
  Selects the inventory item to change the information of. number is either a symbol or number from this table. It is recommended that the symbolic names be used rather than the numeric codes.

  Symbol | Number | Inventory item
  --- | --- | ---
  INV_ARMOR | 1 | Conventional armour vest
  INV_KEVLAR | 2 | Kevlar armour vest
  INV_SM_MEDKIT | 3 | Pickup medkit
  INV_FORTUNE | 4 | Fortune cookie
  INV_MEDKIT | 5 | Portable medkit
  INV_GAS_BOMB | 6 | Gas bomb
  INV_FLASH_BOMB | 7 | Flash bomb
  INV_CALTROPS | 8 | Caltrops
  INV_NIGHT_VIS | 9 | Night vision goggles
  INV_REPAIR_KIT | 10 | Repair kit
  INV_SMOKE_BOMB | 11 | Smoke bomb

  The brace-enclosed block may contain these directives:
  title title
  name title
  description title
    Sets the new name of the inventory item to title. name and description are synonyms for title.
  amount amount
    Sets the quantity of the item that will be added to the player's inventory.
weapon number { ... }
  Selects the weapon to change the information of. number is either a symbol or number from this table. It is recommended that the symbolic names be used rather than the numeric codes.

  Symbol | Number | Weapon name | Customisable properties (see note 1)
  --- | --- | --- | ---
  WPN_FIST | 1 | Fists | damage
  WPN_SWORD | 2 | Sword | damage
  WPN_SHURIKEN | 3 | Shurikens | weapon name and pickup, damage
  WPN_STICKYBOMB | 4 | Sticky bombs | weapon name and pickup, damage
  WPN_UZI | 5 | Uzi submachine gun | weapon/ammo name and pickup, damage
  WPN_MISSILE | 6 | Rocket launcher | weapon/ammo name and pickup, damage
  WPN_NUKE | 7 | Nuclear warhead, heat seeker card (see note 2) | weapon/ammo name and pickup, damage
  WPN_GRENADE | 8 | Grenade launcher | weapon/ammo name and pickup, damage
  WPN_RAILGUN | 9 | Rail gun | weapon/ammo name and pickup, damage
  WPN_SHOTGUN | 10 | Riot gun | weapon/ammo name and pickup, damage
  WPN_HOTHEAD | 11 | Guardian head | weapon name and pickup, damage
  WPN_HEART | 12 | Ripper heart | weapon name and pickup, damage
  WPN_HOTHEAD_NAPALM | 13 | Guardian head napalm (secondary attack) | damage
  WPN_HOTHEAD_RING | 14 | Guardian head ring (tertiary attack) | damage

  Note 1: Only some properties of particular weapons can be changed. Changing other properties not mentioned in the table will have no effect.

  Note 2: The heat seeker card name and pickup amount is stored as the ammunition information of the nuclear warhead.

  The brace-enclosed block may contain these directives:
  title title
  name title
  description title
    Sets the new name of the weapon to title. name and description are synonyms for title.
  ammoname name
    Sets the new name of the ammunition for the weapon to name.
  maxammo amount
    Sets the maximum amount of ammunition that can be carried for the weapon to amount.
  mindamage min
  maxdamage max
    Sets the minimum and/or maximum damage factors for the weapon to min and max respectively.
  pickup amount
    Sets the amount of ammunition to be added when picking up ammunition for the weapon to amount.
  weaponpickup amount
    Sets the amount of ammunition to be added when picking up the weapon to amount.

Here is a fictitious example:

    level 1 {
        title    "My Neat Map"
        filename "neatmap.map"
        song     "coolsong.mid"
        cdatrack 4
        besttime 1800    // half an hour
        partime  3600    // an hour
    }

    episode 1 {
        title    "My Neat Episode"
        subtitle "One level of lameness"
    }

    skill 1 {
        title  "Don't hurt me"
    }

    inventory INV_ARMOR {
        name   "Chain mail"
        amount 25
    }

    weapon WPN_UZI {
        name      "Pea shooter"
        ammoname  "Pebbles"
        maxammo   500
        mindamage 1
        maxdamage 2
        pickup    100
        weaponpickup 25
    }

## DEF-file Language

Documentation of the DEF file language can now be found on my website as the information there is common to all JFBuild-based ports.

## Map Hack scripts

"Map Hack" scripts are files that override certain aspects of a map file when it is rendered in OpenGL Polymost mode. Currently they allow for angle adjustment on sprites, and the ability to prevent particular sprites from being drawn as a model. These are useful for making small corrections to ornamental sprites in a way that doesn't require modifying the original map.

The game will automatically load a map hack script whenever a map is loaded. The script should have the same base name as the original .MAP file, but with an .MHK extension. The map hack language is described below. It uses the same parser as DEF files, so you can use comments in the same way.

sprite number
  Begins a sprite definition. number is the sprite number to affect. You can find this in the Build editor by highlighting the sprite in 2D mode and pressing Control+Tab. The next group of commands describe the changes to make to the sprite.
  notmd
  notmd2
  notmd3
    Prevents the sprite from being drawn as a model. It gets drawn as a regular sprite instead. notmd2 and notmd3 are synonyms for notmd.
  nomdanim
  nomd2anim
  nomd3anim
    Prevents model animation from playing if the sprite is being drawn as a model. nomd2anim and nomd3anim are synonyms for nomdanim.
  angleoff angle
  angoff angle
    Adds angle to the angle of the sprite just before it is rendered. This is good for fixing up things like toilet sprites that are facing the wrong way. angoff is a synonym for angleoff.

Here is an example map hack script:

    // Map hack file for JFDuke3D
    // Level: E1L2.MAP (Original Atomic Edition version)
    // Prepared by jonof@edgenetwork.org

    // Invisible switch behind hand dryer in toilet of porn shop
    sprite 191 notmd2

    // Invisible switches on telephones near billiards room in club
    sprite 254 notmd2
    sprite 517 notmd2

    // Toilet in restroom in club
    sprite 478 angoff -512

## Hightile

This release features the "Hightile" texturing improvements to Polymost. Hightile allows Polymost to use true-colour textures instead of the artwork in the game's usual .ART file.

Replacement textures can be saved as JPEG, PNG (alpha channel supported), TGA, BMP, CEL, GIF, and PCX formats. Hightile uses Ken Silverman's picture library to provide rapid picture file loading.

Hightile textures are defined in the SW.DEF file. See the DEF-file language reference for information on how to specify Hightile textures.

### Limitations to Hightile

- Hightile will squash or stretch the replacement to fit in the dimensions of the original tile it replaces. Artists should keep their replacements in the same ratio as the original tile for the art to not look distorted.

## Extra GRP and ZIP file support

JFShadowWarrior (and JFBuild games in general) can load extra game resources from a GRP or ZIP file.

Use the "/g" command-line switch to specify the ZIP or GRP to load. eg. `SW.EXE /gMYFILE.ZIP`

## Polymost

Polymost is a full 3D implementation of the Build engine renderer, with hardware acceleration capability, and perspective in six degrees of freedom. In Ken's own words (copied from POLYMOST.C in my Build engine source distribution):

    "POLYMOST" code written by Ken Silverman
    Ken Silverman's official web site: http://www.advsys.net/ken

    Motivation:
    When 3D Realms released the Duke Nukem 3D source code, I thought somebody would do a OpenGL or
    Direct3D port. Well, after a few months passed, I saw no sign of somebody working on a true
    hardware-accelerated port of Build, just people saying it wasn't possible. Eventually, I realized
    the only way this was going to happen was for me to do it myself. First, I needed to port Build to
    Windows. I could have done it myself, but instead I thought I'd ask my Australian buddy, Jonathon
    Fowler, if he would upgrade his Windows port to my favorite compiler (MSVC) - which he did. Once
    that was done, I was ready to start the "POLYMOST" project.

    About:
    This source file is basically a complete rewrite of the entire rendering part of the Build engine.
    There are small pieces in ENGINE.C to activate this code, and other minor hacks in other source
    files, but most of it is in here. If you're looking for polymost-related code in the other source
    files, you should find most of them by searching for either "polymost" or "rendmode". Speaking of
    rendmode, there are now 4 rendering modes in Build:

        rendmode 0: The original code I wrote from 1993-1997
        rendmode 1: Solid-color rendering: my debug code before I did texture mapping
        rendmode 2: Software rendering before I started the OpenGL code (Note: this is just a quick
                    hack to make testing easier - it's not optimized to my usual standards!)
        rendmode 3: The OpenGL code

    The original Build engine did hidden surface removal by using a vertical span buffer on the tops
    and bottoms of walls. This worked nice back in the day, but it it's not suitable for a polygon
    engine. So I decided to write a brand new hidden surface removal algorithm - using the same idea
    as the original Build - but one that worked with vectors instead of already rasterized data.

Polymost is the default renderer choice for any video mode with a colour depth greater than 256 colours.

NOTE: If your computer does not have an OpenGL graphics card, Polymost in OpenGL mode will most likely use the default Windows OpenGL rasterising facility which does all rendering in software. This may be extremely slow. If your Windows installation doesn't have any form of OpenGL rendering ability, Polymost will probably crash.

NOTE 2: OpenGL Polymost has been tested on an nVidia Riva TNT 16MB, an nVidia GeForce2 GTS 32MB, an nVidia GeForce4 Ti4600 128MB, an nVidia GeForce 6800GT 256MB, an ATi Radeon Mobility 9000 64MB, and a 3D-Labs Oxygen GVX420 128MB (minor texturing issues).

## Console Commands

This is a list of console commands and variables and their purpose:

dumpbuildinfo
  Displays the compilation information for the game when it was built.
echo <text...>
  Displays to the console what is passed as parameters to the command.
fileinfo <filename>
  Displays some information about a given file, eg. size, CRC-32 checksum.
glinfo
  Displays some information about the OpenGL driver.
glredbluemode <0 or 1>
  Enables or disables the red-blue stereovision mode in OpenGL. This mode is experimental at this time. We know the flicker is nasty and the menu background will mix into the screen. To avoid the menu bug, run the game in fullscreen mode and type "glredbluemode 1" AFTER beginning the game. Sorry, there is no way to change parallax or separation. Do not contact us about bugs with this mode... if you do, we'll think twice about documenting hidden features in future releases. :P
gltextureanisotropy <level>
  Sets the OpenGL anisotropic filtering level.
gltexturemode <mode-number>
  Sets the OpenGL texturing mode. Valid values are:

  0 | GL_NEAREST (looks rather like the original software renderer)
  1 | GL_LINEAR
  2 | GL_NEAREST_MIPMAP_NEAREST
  3 | GL_LINEAR_MIPMAP_NEAREST (bilinear)
  4 | GL_NEAREST_MIPMAP_LINEAR
  5 | GL_LINEAR_MIPMAP_LINEAR (trilinear)

glusetexcompr <0 or 1>
  Enables or disables the use of OpenGL texture compression for hightile textures. You need to use 'restartvid' to apply any changes to this value.
help <name>
  Displays a help message for a particular console variable or command.
listsymbols
  Displays the names of all commands and variables available in the console.
novoxmips <0 or 1>
  Disables or enables the use of voxel mipmaps to improve voxel visual quality.
osdrows <num>
  Sets the number of visible lines of the console when it is open.
screencaptureformat <0 or 1>
  0 = Targa, 1 = PCX
setrendermode <mode>
  Sets the current Polymost render mode.
usegoodalpha <0 or 1>
  If 1, a lower alpha cutoff value is used when rendering textures with transparency, which gives better looking transparent textures at the expense of some sprites behind the transparent item potentially being invisible in certain circumstances. 0 is a more compatible value (and is the default) for this option but slight visual degradation will result.
usehightile <0 or 1>
  Disables or enables the use of Hightile textures in GL Polymost mode if any are defined.
usemodels <0 or 1>
  Disables or enables the use of 3D models in GL Polymost mode if any are defined.
usevoxels <0 or 1>
  Disables or enables the use of voxels in the classic renderer if any are defined.