Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
tools:bsp2_format [2012/12/22 13:49] Spirittools:bsp2_format [2015/08/28 18:11] (current) – moved to http://quakewiki.org/wiki/BSP2 Spirit
Line 1: Line 1:
-====== The BSP2 Format ====== +Moved to http://quakewiki.org/wiki/BSP2
- +
-When the Remakequake project's maps started exceeding the original Quake BSP map limits again and again they started drafting a new flavour of the BSP29 map file format with extended limits. The goal was to make as few changes as possible. No new features were introduced. It was called BSP2. Internally it is also known as BSP29a. +
- +
-The finalised BSP2 format uses the magic number BSP2 and has the following limits: TODO, why are those numbers nowhere to be found :( +
- +
-First map releases (TODO which RMQ demos?) used an early version with the magic number 2PSB and still had node BBox sizes being ''short''. This file format is supported by the respective RMQ engine releases and FTEQW. +
- +
-==== Engines with BSP2 support ==== +
-  * Darkplaces +
-  * FTEQW +
-  * Quakeforge +
- +
-==== Compilers with BSP2 support ==== +
-  * hmap2 uses BSP2 automatically if needed. +
-<WRAP center round todo 60%> +
-Does this create PSB2 or BSP2? +
-  * RMQ's TxQBSP2, WVisBSP2 and LightBSP2. Available in http://icculus.org/remakequake/RMQSDKJan2012.zip +
-</WRAP> +
- +
-==== Adding support to your engine/toolchain ==== +
-MH has written "BSP2 for Engine Coders.txt" which you can find in the BSP2Tools directory in http://icculus.org/remakequake/RMQSDKJan2012.zip . This file is quoted below. Do not copy and paste from here, there might be formatting/encoding issues. +
- +
-<blockquote>BSP2 for Engine Coders +
- +
-The objective of BSP2 is to address some limits in the stock BSP29 format.  While many engines have boosted limits, there remain some cases where the on-disk format enforces a hard limit of 64k.  During the course of RMQ development these cases were hit on a number of occasions; it was clear that we were exceeding the capabilities of the Quake formats and that a more robust and general solution was needed. +
- +
-Alternatives such as Half-Life BSP, Quake II BSP, Quake III BSP or others were  considered but rejected on grounds of legal issues, not actually doing anything to fix this problem, enforcing too many changes in the content creation pipeline (such as changing your map editor) and enforcing too many (and too complex) changes in engine +
-code. +
- +
-BSP2 will coexist peacefully with BSP29 so far as is possible; minimal changes are required to engine code (the largest by far being in the loader), the .map format remains exactly the same, and - while new map compiling tools are needed - the changes to these tools are also extremely minimal and can be made in the order of 30 minutes or so per tool. +
- +
-BSP2 is not a radical revision of the format.  You won't find RGB lightmaps, detail brushes, 32-bit textures or any such major overhaul here.  These are left for other already standardised ways of providing such content.  It's sole objective is to overcome limits that prevent content creators from fully realising their visions.  By choosing this approach it is hoped that the path to implementing  BSP2 support in as many engines +
-who's authors choose to do so is as eased as is possible, and dependencies on other features (such as RGB lightmaps) are not an obstacle. +
- +
--------------------------------------------------------------------------------------------------------------- +
- +
-This document outlines the requirements for implementing RMQ BSP2 support in your engine.  Because all engine codebases are different I am not going to provide a set of copy-and-paste code but instead will give a fairly high-level overview of the changes required.  The exception is where I give the new on-disk structs for BSP2 in full. +
- +
-The basic steps are: +
- +
-- Change the in-memory formats for certain BSP structs.\\  +
-- Detect the version.\\  +
-- Implement the loaders. +
- +
--------------------------------------------------------------------------------------------------------------- +
-Changing the in-memory formats +
- +
-This is a simple matter of switching the in-memory formats from using short (or unsigned short) to int (or unsigned int) as appropriate.  It is non-destructive, will enable you to use the very same in-memory formats for both BSP29 and BSP2, and can be done even if you don't intend to implement BSP2 (or don't intend to implement it yet).  Memory usage will go up a little, but this should not be a problem unless you still need to run on an 8 MB machine. +
- +
-In general, an on-disk struct name is prefixed by "d" and an in-memory struct name is prefixed by "m" (there are some few exceptions) - see bspfile.h and model.h/gl_model.h for further info. +
- +
-You will need to implement your own mclipnode_t struct as stock ID Quake uses dclipnode_t for both on-disk and in-memory.  See FitzQuake 0.85 for an example of this. +
- +
-One side-effect of this is that some ASM code in world.c will need to be switched to the equivalent C function; this should not cause a noticeable performance hit for most people. +
- +
--------------------------------------------------------------------------------------------------------------- +
-Detecting the version +
- +
-The BSP2 version is defined as (('B' << 24) | ('S' << 16) | ('P' << 8) | '2') using the same endianness convention as stock BSP29. +
- +
-Once we have identified this we are almost ready to load the file, but first we must define some new structs in bspfile.h (Note that the use of "29a" in the struct names is a historical artefact from an earlier working title for the format.  If you are building a map compiling tool you will also need to add dmarksurfaces29a as an unsigned int.): +
- +
-typedef struct +
-+
- int planenum; +
- int children[2]; // negative numbers are -(leafs+1), not nodes +
- short mins[3]; // for sphere culling +
- short maxs[3]; +
- unsigned int firstface; +
- unsigned int numfaces; // counting both sides +
-} dnode29a_t; +
- +
-typedef struct +
-+
- int planenum; +
- int children[2]; // negative numbers are contents +
-} dclipnode29a_t; +
- +
-typedef struct +
-+
- unsigned int v[2]; // vertex numbers +
-} dedge29a_t; +
- +
-typedef struct +
-+
- int planenum; +
- int side; +
- +
- int firstedge; // we must support > 64k edges +
- int numedges; +
- int texinfo; +
- +
- // lighting info +
- byte styles[MAXLIGHTMAPS]; +
- int lightofs; // start of [numstyles*surfsize] samples +
-} dface29a_t; +
- +
-typedef struct +
-+
- int contents; +
- int visofs; // -1 = no visibility info +
- +
- short mins[3]; // for frustum culling +
- short maxs[3]; +
- +
- unsigned int firstmarksurface; +
- unsigned int nummarksurfaces; +
- +
- byte ambient_level[NUM_AMBIENTS]; +
-} dleaf29a_t; +
- +
--------------------------------------------------------------------------------------------------------------- +
-Implementing the Loaders +
- +
-From here the only major remaining change is to implement new versions of certain brushmodel loading functions to support BSP2.  The functions that need new versions are: +
- +
-- Mod_LoadEdges\\  +
-- Mod_LoadFaces\\  +
-- Mod_LoadNodes\\  +
-- Mod_LoadLeafs\\  +
-- Mod_LoadClipnodes\\  +
-- Mod_LoadMarksurfaces +
- +
-For each of these functions the "in" pointer changes to the new version of the struct, and anything that was previously loaded as a "LittleShort" is now loaded as a "LittleLong" In some cases the loading function may be significantly simpler than the older one as you will not need to cast to unsigned short and nor will you need to implement any workaround for counts above 32k. +
- +
-You may find it easier and cleaner to split some functions into two or even three separate parts, with different parts being common for both versions, dedicated to BSP29 or dedicated to BSP2.  This is almost certainly the case with Mod_LoadFaces. +
- +
--------------------------------------------------------------------------------------------------------------- +
-License +
- +
-This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. +
- +
-This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +
- +
-See the GNU General Public License for more details. +
- +
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. +
-</blockquote> +
- +
-Sources: +
- +
-  * http://mhquake.blogspot.de/2011/09/updates-for-13th-september-2011.html +
-  * #qc+