Moved modified HL SDK to trunk

This commit is contained in:
Scott Ehlert
2006-08-27 02:22:59 +00:00
parent 28c4ea4fec
commit 30235e05e5
900 changed files with 344676 additions and 0 deletions

View File

@ -0,0 +1,48 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "cmdlib.h"
#include "mathlib.h"
#include "bspfile.h"
void main (int argc, char **argv)
{
int i;
char source[1024];
int size;
FILE *f;
printf( "bspinfo.exe v2.1 (%s)\n", __DATE__ );
printf ("---- bspinfo ----\n" );
if (argc == 1)
Error ("usage: bspinfo bspfile [bspfiles]");
for (i=1 ; i<argc ; i++)
{
printf ("---------------------\n");
strcpy (source, argv[i]);
DefaultExtension (source, ".bsp");
f = fopen (source, "rb");
if (f)
{
size = filelength (f);
fclose (f);
}
else
size = 0;
printf ("%s: %i\n", source, size);
LoadBSPFile (source);
PrintBSPFileSizes ();
printf ("---------------------\n");
}
}

View File

@ -0,0 +1,124 @@
# Microsoft Developer Studio Project File - Name="bspinfo" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=bspinfo - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "bspinfo.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "bspinfo.mak" CFG="bspinfo - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "bspinfo - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "bspinfo - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/SDKSrc/Tools/utils/bspinfo", HUGBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "bspinfo - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /GX /O2 /I "..\..\common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "bspinfo - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\Debug"
# PROP Intermediate_Dir ".\Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /Gm /GX /ZI /Od /I "..\..\common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
!ENDIF
# Begin Target
# Name "bspinfo - Win32 Release"
# Name "bspinfo - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\..\common\bspfile.c
# End Source File
# Begin Source File
SOURCE=..\bspinfo.c
# End Source File
# Begin Source File
SOURCE=..\..\common\cmdlib.c
# End Source File
# Begin Source File
SOURCE=..\..\common\scriplib.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=..\..\common\bspfile.h
# End Source File
# Begin Source File
SOURCE=..\..\common\cmdlib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\scriplib.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@ -0,0 +1,37 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "bspinfo"=.\bspinfo.dsp - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/SDKSrc/Tools/utils/bspinfo", HUGBAAAA
.
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
begin source code control
"$/SDKSrc/Tools/utils/bspinfo", HUGBAAAA
.
end source code control
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@ -0,0 +1,233 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="bspinfo"
ProjectGUID="{3C4A2904-EBE0-4891-BA16-8CA6D63C0639}"
SccProjectName="&quot;$/SDKSrc/Tools/utils/bspinfo&quot;, HUGBAAAA"
SccLocalPath=".">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/bspinfo.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/bspinfo.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/bspinfo.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/bspinfo.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
RuntimeLibrary="5"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/bspinfo.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/bspinfo.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/bspinfo.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/bspinfo.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90">
<File
RelativePath="..\..\common\bspfile.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\bspinfo.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\cmdlib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd">
<File
RelativePath="..\..\common\bspfile.h">
</File>
<File
RelativePath="..\..\common\cmdlib.h">
</File>
<File
RelativePath="..\..\common\scriplib.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,321 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="bspinfo"
ProjectGUID="{3C4A2904-EBE0-4891-BA16-8CA6D63C0639}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/bspinfo.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/bspinfo.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
SuppressStartupBanner="true"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/bspinfo.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\Release/bspinfo.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/bspinfo.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/bspinfo.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/bspinfo.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/bspinfo.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
>
<File
RelativePath="..\..\common\bspfile.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\bspinfo.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\cmdlib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd"
>
<File
RelativePath="..\..\common\bspfile.h"
>
</File>
<File
RelativePath="..\..\common\cmdlib.h"
>
</File>
<File
RelativePath="..\..\common\scriplib.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,709 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "cmdlib.h"
#include "mathlib.h"
#include "bspfile.h"
#include "scriplib.h"
//=============================================================================
int nummodels;
dmodel_t dmodels[MAX_MAP_MODELS];
int dmodels_checksum;
int visdatasize;
byte dvisdata[MAX_MAP_VISIBILITY];
int dvisdata_checksum;
int lightdatasize;
byte dlightdata[MAX_MAP_LIGHTING];
int dlightdata_checksum;
int texdatasize;
byte dtexdata[MAX_MAP_MIPTEX]; // (dmiptexlump_t)
int dtexdata_checksum;
int entdatasize;
char dentdata[MAX_MAP_ENTSTRING];
int dentdata_checksum;
int numleafs;
dleaf_t dleafs[MAX_MAP_LEAFS];
int dleafs_checksum;
int numplanes;
dplane_t dplanes[MAX_MAP_PLANES];
int dplanes_checksum;
int numvertexes;
dvertex_t dvertexes[MAX_MAP_VERTS];
int dvertexes_checksum;
int numnodes;
dnode_t dnodes[MAX_MAP_NODES];
int dnodes_checksum;
int numtexinfo;
texinfo_t texinfo[MAX_MAP_TEXINFO];
int texinfo_checksum;
int numfaces;
dface_t dfaces[MAX_MAP_FACES];
int dfaces_checksum;
int numclipnodes;
dclipnode_t dclipnodes[MAX_MAP_CLIPNODES];
int dclipnodes_checksum;
int numedges;
dedge_t dedges[MAX_MAP_EDGES];
int dedges_checksum;
int nummarksurfaces;
unsigned short dmarksurfaces[MAX_MAP_MARKSURFACES];
int dmarksurfaces_checksum;
int numsurfedges;
int dsurfedges[MAX_MAP_SURFEDGES];
int dsurfedges_checksum;
int num_entities;
entity_t entities[MAX_MAP_ENTITIES];
/*
===============
FastChecksum
===============
*/
int FastChecksum(void *buffer, int bytes)
{
int checksum = 0;
while( bytes-- )
checksum = _rotl(checksum, 4) ^ *((char *)buffer)++;
return checksum;
}
/*
===============
CompressVis
===============
*/
int CompressVis (byte *vis, byte *dest)
{
int j;
int rep;
int visrow;
byte *dest_p;
dest_p = dest;
visrow = (numleafs + 7)>>3;
for (j=0 ; j<visrow ; j++)
{
*dest_p++ = vis[j];
if (vis[j])
continue;
rep = 1;
for ( j++; j<visrow ; j++)
if (vis[j] || rep == 255)
break;
else
rep++;
*dest_p++ = rep;
j--;
}
return dest_p - dest;
}
/*
===================
DecompressVis
===================
*/
void DecompressVis (byte *in, byte *decompressed)
{
int c;
byte *out;
int row;
row = (numleafs+7)>>3;
out = decompressed;
do
{
if (*in)
{
*out++ = *in++;
continue;
}
c = in[1];
in += 2;
while (c)
{
*out++ = 0;
c--;
}
} while (out - decompressed < row);
}
//=============================================================================
/*
=============
SwapBSPFile
Byte swaps all data in a bsp file.
=============
*/
void SwapBSPFile (qboolean todisk)
{
int i, j, c;
dmodel_t *d;
dmiptexlump_t *mtl;
// models
for (i=0 ; i<nummodels ; i++)
{
d = &dmodels[i];
for (j=0 ; j<MAX_MAP_HULLS ; j++)
d->headnode[j] = LittleLong (d->headnode[j]);
d->visleafs = LittleLong (d->visleafs);
d->firstface = LittleLong (d->firstface);
d->numfaces = LittleLong (d->numfaces);
for (j=0 ; j<3 ; j++)
{
d->mins[j] = LittleFloat(d->mins[j]);
d->maxs[j] = LittleFloat(d->maxs[j]);
d->origin[j] = LittleFloat(d->origin[j]);
}
}
//
// vertexes
//
for (i=0 ; i<numvertexes ; i++)
{
for (j=0 ; j<3 ; j++)
dvertexes[i].point[j] = LittleFloat (dvertexes[i].point[j]);
}
//
// planes
//
for (i=0 ; i<numplanes ; i++)
{
for (j=0 ; j<3 ; j++)
dplanes[i].normal[j] = LittleFloat (dplanes[i].normal[j]);
dplanes[i].dist = LittleFloat (dplanes[i].dist);
dplanes[i].type = LittleLong (dplanes[i].type);
}
//
// texinfos
//
for (i=0 ; i<numtexinfo ; i++)
{
for (j=0 ; j<8 ; j++)
texinfo[i].vecs[0][j] = LittleFloat (texinfo[i].vecs[0][j]);
texinfo[i].miptex = LittleLong (texinfo[i].miptex);
texinfo[i].flags = LittleLong (texinfo[i].flags);
}
//
// faces
//
for (i=0 ; i<numfaces ; i++)
{
dfaces[i].texinfo = LittleShort (dfaces[i].texinfo);
dfaces[i].planenum = LittleShort (dfaces[i].planenum);
dfaces[i].side = LittleShort (dfaces[i].side);
dfaces[i].lightofs = LittleLong (dfaces[i].lightofs);
dfaces[i].firstedge = LittleLong (dfaces[i].firstedge);
dfaces[i].numedges = LittleShort (dfaces[i].numedges);
}
//
// nodes
//
for (i=0 ; i<numnodes ; i++)
{
dnodes[i].planenum = LittleLong (dnodes[i].planenum);
for (j=0 ; j<3 ; j++)
{
dnodes[i].mins[j] = LittleShort (dnodes[i].mins[j]);
dnodes[i].maxs[j] = LittleShort (dnodes[i].maxs[j]);
}
dnodes[i].children[0] = LittleShort (dnodes[i].children[0]);
dnodes[i].children[1] = LittleShort (dnodes[i].children[1]);
dnodes[i].firstface = LittleShort (dnodes[i].firstface);
dnodes[i].numfaces = LittleShort (dnodes[i].numfaces);
}
//
// leafs
//
for (i=0 ; i<numleafs ; i++)
{
dleafs[i].contents = LittleLong (dleafs[i].contents);
for (j=0 ; j<3 ; j++)
{
dleafs[i].mins[j] = LittleShort (dleafs[i].mins[j]);
dleafs[i].maxs[j] = LittleShort (dleafs[i].maxs[j]);
}
dleafs[i].firstmarksurface = LittleShort (dleafs[i].firstmarksurface);
dleafs[i].nummarksurfaces = LittleShort (dleafs[i].nummarksurfaces);
dleafs[i].visofs = LittleLong (dleafs[i].visofs);
}
//
// clipnodes
//
for (i=0 ; i<numclipnodes ; i++)
{
dclipnodes[i].planenum = LittleLong (dclipnodes[i].planenum);
dclipnodes[i].children[0] = LittleShort (dclipnodes[i].children[0]);
dclipnodes[i].children[1] = LittleShort (dclipnodes[i].children[1]);
}
//
// miptex
//
if (texdatasize)
{
mtl = (dmiptexlump_t *)dtexdata;
if (todisk)
c = mtl->nummiptex;
else
c = LittleLong(mtl->nummiptex);
mtl->nummiptex = LittleLong (mtl->nummiptex);
for (i=0 ; i<c ; i++)
mtl->dataofs[i] = LittleLong(mtl->dataofs[i]);
}
//
// marksurfaces
//
for (i=0 ; i<nummarksurfaces ; i++)
dmarksurfaces[i] = LittleShort (dmarksurfaces[i]);
//
// surfedges
//
for (i=0 ; i<numsurfedges ; i++)
dsurfedges[i] = LittleLong (dsurfedges[i]);
//
// edges
//
for (i=0 ; i<numedges ; i++)
{
dedges[i].v[0] = LittleShort (dedges[i].v[0]);
dedges[i].v[1] = LittleShort (dedges[i].v[1]);
}
}
dheader_t *header;
int CopyLump (int lump, void *dest, int size)
{
int length, ofs;
length = header->lumps[lump].filelen;
ofs = header->lumps[lump].fileofs;
if (length % size)
Error ("LoadBSPFile: odd lump size");
memcpy (dest, (byte *)header + ofs, length);
return length / size;
}
/*
=============
LoadBSPFile
=============
*/
void LoadBSPFile (char *filename)
{
int i;
//
// load the file header
//
LoadFile (filename, (void **)&header);
// swap the header
for (i=0 ; i< sizeof(dheader_t)/4 ; i++)
((int *)header)[i] = LittleLong ( ((int *)header)[i]);
if (header->version != BSPVERSION)
Error ("%s is version %i, not %i", filename, header->version, BSPVERSION);
nummodels = CopyLump (LUMP_MODELS, dmodels, sizeof(dmodel_t));
numvertexes = CopyLump (LUMP_VERTEXES, dvertexes, sizeof(dvertex_t));
numplanes = CopyLump (LUMP_PLANES, dplanes, sizeof(dplane_t));
numleafs = CopyLump (LUMP_LEAFS, dleafs, sizeof(dleaf_t));
numnodes = CopyLump (LUMP_NODES, dnodes, sizeof(dnode_t));
numtexinfo = CopyLump (LUMP_TEXINFO, texinfo, sizeof(texinfo_t));
numclipnodes = CopyLump (LUMP_CLIPNODES, dclipnodes, sizeof(dclipnode_t));
numfaces = CopyLump (LUMP_FACES, dfaces, sizeof(dface_t));
nummarksurfaces = CopyLump (LUMP_MARKSURFACES, dmarksurfaces, sizeof(dmarksurfaces[0]));
numsurfedges = CopyLump (LUMP_SURFEDGES, dsurfedges, sizeof(dsurfedges[0]));
numedges = CopyLump (LUMP_EDGES, dedges, sizeof(dedge_t));
texdatasize = CopyLump (LUMP_TEXTURES, dtexdata, 1);
visdatasize = CopyLump (LUMP_VISIBILITY, dvisdata, 1);
lightdatasize = CopyLump (LUMP_LIGHTING, dlightdata, 1);
entdatasize = CopyLump (LUMP_ENTITIES, dentdata, 1);
free (header); // everything has been copied out
//
// swap everything
//
SwapBSPFile (false);
dmodels_checksum = FastChecksum( dmodels, nummodels*sizeof(dmodels[0]) );
dvertexes_checksum = FastChecksum( dvertexes, numvertexes*sizeof(dvertexes[0]) );
dplanes_checksum = FastChecksum( dplanes, numplanes*sizeof(dplanes[0]) );
dleafs_checksum = FastChecksum( dleafs, numleafs*sizeof(dleafs[0]) );
dnodes_checksum = FastChecksum( dnodes, numnodes*sizeof(dnodes[0]) );
texinfo_checksum = FastChecksum( texinfo, numtexinfo*sizeof(texinfo[0]) );
dclipnodes_checksum = FastChecksum( dclipnodes, numclipnodes*sizeof(dclipnodes[0]) );
dfaces_checksum = FastChecksum( dfaces, numfaces*sizeof(dfaces[0]) );
dmarksurfaces_checksum = FastChecksum( dmarksurfaces, nummarksurfaces*sizeof(dmarksurfaces[0]) );
dsurfedges_checksum = FastChecksum( dsurfedges, numsurfedges*sizeof(dsurfedges[0]) );
dedges_checksum = FastChecksum( dedges, numedges*sizeof(dedges[0]) );
dtexdata_checksum = FastChecksum( dtexdata, numedges*sizeof(dtexdata[0]) );
dvisdata_checksum = FastChecksum( dvisdata, visdatasize*sizeof(dvisdata[0]) );
dlightdata_checksum = FastChecksum( dlightdata, lightdatasize*sizeof(dlightdata[0]) );
dentdata_checksum = FastChecksum( dentdata, entdatasize*sizeof(dentdata[0]) );
}
//============================================================================
FILE *wadfile;
dheader_t outheader;
void AddLump (int lumpnum, void *data, int len)
{
lump_t *lump;
lump = &header->lumps[lumpnum];
lump->fileofs = LittleLong( ftell(wadfile) );
lump->filelen = LittleLong(len);
SafeWrite (wadfile, data, (len+3)&~3);
}
/*
=============
WriteBSPFile
Swaps the bsp file in place, so it should not be referenced again
=============
*/
void WriteBSPFile (char *filename)
{
header = &outheader;
memset (header, 0, sizeof(dheader_t));
SwapBSPFile (true);
header->version = LittleLong (BSPVERSION);
wadfile = SafeOpenWrite (filename);
SafeWrite (wadfile, header, sizeof(dheader_t)); // overwritten later
AddLump (LUMP_PLANES, dplanes, numplanes*sizeof(dplane_t));
AddLump (LUMP_LEAFS, dleafs, numleafs*sizeof(dleaf_t));
AddLump (LUMP_VERTEXES, dvertexes, numvertexes*sizeof(dvertex_t));
AddLump (LUMP_NODES, dnodes, numnodes*sizeof(dnode_t));
AddLump (LUMP_TEXINFO, texinfo, numtexinfo*sizeof(texinfo_t));
AddLump (LUMP_FACES, dfaces, numfaces*sizeof(dface_t));
AddLump (LUMP_CLIPNODES, dclipnodes, numclipnodes*sizeof(dclipnode_t));
AddLump (LUMP_MARKSURFACES, dmarksurfaces, nummarksurfaces*sizeof(dmarksurfaces[0]));
AddLump (LUMP_SURFEDGES, dsurfedges, numsurfedges*sizeof(dsurfedges[0]));
AddLump (LUMP_EDGES, dedges, numedges*sizeof(dedge_t));
AddLump (LUMP_MODELS, dmodels, nummodels*sizeof(dmodel_t));
AddLump (LUMP_LIGHTING, dlightdata, lightdatasize);
AddLump (LUMP_VISIBILITY, dvisdata, visdatasize);
AddLump (LUMP_ENTITIES, dentdata, entdatasize);
AddLump (LUMP_TEXTURES, dtexdata, texdatasize);
fseek (wadfile, 0, SEEK_SET);
SafeWrite (wadfile, header, sizeof(dheader_t));
fclose (wadfile);
}
//============================================================================
#define ENTRIES(a) (sizeof(a)/sizeof(*(a)))
#define ENTRYSIZE(a) (sizeof(*(a)))
ArrayUsage( char *szItem, int items, int maxitems, int itemsize )
{
float percentage = maxitems ? items * 100.0 / maxitems : 0.0;
printf("%-12s %7i/%-7i %7i/%-7i (%4.1f%%)",
szItem, items, maxitems, items * itemsize, maxitems * itemsize, percentage );
if ( percentage > 80.0 )
printf( "VERY FULL!\n" );
else if ( percentage > 95.0 )
printf( "SIZE DANGER!\n" );
else if ( percentage > 99.9 )
printf( "SIZE OVERFLOW!!!\n" );
else
printf( "\n" );
return items * itemsize;
}
GlobUsage( char *szItem, int itemstorage, int maxstorage )
{
float percentage = maxstorage ? itemstorage * 100.0 / maxstorage : 0.0;
printf("%-12s [variable] %7i/%-7i (%4.1f%%)",
szItem, itemstorage, maxstorage, percentage );
if ( percentage > 80.0 )
printf( "VERY FULL!\n" );
else if ( percentage > 95.0 )
printf( "SIZE DANGER!\n" );
else if ( percentage > 99.9 )
printf( "SIZE OVERFLOW!!!\n" );
else
printf( "\n" );
return itemstorage;
}
/*
=============
PrintBSPFileSizes
Dumps info about current file
=============
*/
void PrintBSPFileSizes (void)
{
int numtextures = texdatasize ? ((dmiptexlump_t*)dtexdata)->nummiptex : 0;
int totalmemory = 0;
printf("\n");
printf("Object names Objects/Maxobjs Memory / Maxmem Fullness\n" );
printf("------------ --------------- --------------- --------\n" );
totalmemory += ArrayUsage( "models", nummodels, ENTRIES(dmodels), ENTRYSIZE(dmodels) );
totalmemory += ArrayUsage( "planes", numplanes, ENTRIES(dplanes), ENTRYSIZE(dplanes) );
totalmemory += ArrayUsage( "vertexes", numvertexes, ENTRIES(dvertexes), ENTRYSIZE(dvertexes) );
totalmemory += ArrayUsage( "nodes", numnodes, ENTRIES(dnodes), ENTRYSIZE(dnodes) );
totalmemory += ArrayUsage( "texinfos", numtexinfo, ENTRIES(texinfo), ENTRYSIZE(texinfo) );
totalmemory += ArrayUsage( "faces", numfaces, ENTRIES(dfaces), ENTRYSIZE(dfaces) );
totalmemory += ArrayUsage( "clipnodes", numclipnodes, ENTRIES(dclipnodes), ENTRYSIZE(dclipnodes) );
totalmemory += ArrayUsage( "leaves", numleafs, ENTRIES(dleafs), ENTRYSIZE(dleafs) );
totalmemory += ArrayUsage( "marksurfaces", nummarksurfaces,ENTRIES(dmarksurfaces), ENTRYSIZE(dmarksurfaces) );
totalmemory += ArrayUsage( "surfedges", numsurfedges, ENTRIES(dsurfedges), ENTRYSIZE(dsurfedges) );
totalmemory += ArrayUsage( "edges", numedges, ENTRIES(dedges), ENTRYSIZE(dedges) );
totalmemory += GlobUsage( "texdata", texdatasize, sizeof(dtexdata) );
totalmemory += GlobUsage( "lightdata", lightdatasize, sizeof(dlightdata) );
totalmemory += GlobUsage( "visdata", visdatasize, sizeof(dvisdata) );
totalmemory += GlobUsage( "entdata", entdatasize, sizeof(dentdata) );
printf( "=== Total BSP file data space used: %d bytes ===\n", totalmemory );
}
/*
=================
ParseEpair
=================
*/
epair_t *ParseEpair (void)
{
epair_t *e;
e = malloc (sizeof(epair_t));
memset (e, 0, sizeof(epair_t));
if (strlen(token) >= MAX_KEY-1)
Error ("ParseEpar: token too long");
e->key = copystring(token);
GetToken (false);
if (strlen(token) >= MAX_VALUE-1)
Error ("ParseEpar: token too long");
e->value = copystring(token);
return e;
}
/*
================
ParseEntity
================
*/
qboolean ParseEntity (void)
{
epair_t *e;
entity_t *mapent;
if (!GetToken (true))
return false;
if (strcmp (token, "{") )
Error ("ParseEntity: { not found");
if (num_entities == MAX_MAP_ENTITIES)
Error ("num_entities == MAX_MAP_ENTITIES");
mapent = &entities[num_entities];
num_entities++;
do
{
if (!GetToken (true))
Error ("ParseEntity: EOF without closing brace");
if (!strcmp (token, "}") )
break;
e = ParseEpair ();
e->next = mapent->epairs;
mapent->epairs = e;
} while (1);
return true;
}
/*
================
ParseEntities
Parses the dentdata string into entities
================
*/
void ParseEntities (void)
{
num_entities = 0;
ParseFromMemory (dentdata, entdatasize);
while (ParseEntity ())
{
}
}
/*
================
UnparseEntities
Generates the dentdata string from all the entities
================
*/
void UnparseEntities (void)
{
char *buf, *end;
epair_t *ep;
char line[2048];
int i;
buf = dentdata;
end = buf;
*end = 0;
for (i=0 ; i<num_entities ; i++)
{
ep = entities[i].epairs;
if (!ep)
continue; // ent got removed
strcat (end,"{\n");
end += 2;
for (ep = entities[i].epairs ; ep ; ep=ep->next)
{
sprintf (line, "\"%s\" \"%s\"\n", ep->key, ep->value);
strcat (end, line);
end += strlen(line);
}
strcat (end,"}\n");
end += 2;
if (end > buf + MAX_MAP_ENTSTRING)
Error ("Entity text too long");
}
entdatasize = end - buf + 1;
}
void SetKeyValue (entity_t *ent, char *key, char *value)
{
epair_t *ep;
for (ep=ent->epairs ; ep ; ep=ep->next)
if (!strcmp (ep->key, key) )
{
free (ep->value);
ep->value = copystring(value);
return;
}
ep = malloc (sizeof(*ep));
ep->next = ent->epairs;
ent->epairs = ep;
ep->key = copystring(key);
ep->value = copystring(value);
}
char *ValueForKey (entity_t *ent, char *key)
{
epair_t *ep;
for (ep=ent->epairs ; ep ; ep=ep->next)
if (!strcmp (ep->key, key) )
return ep->value;
return "";
}
vec_t FloatForKey (entity_t *ent, char *key)
{
char *k;
k = ValueForKey (ent, key);
return atof(k);
}
void GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
{
char *k;
double v1, v2, v3;
k = ValueForKey (ent, key);
// scanf into doubles, then assign, so it is vec_t size independent
v1 = v2 = v3 = 0;
sscanf (k, "%lf %lf %lf", &v1, &v2, &v3);
vec[0] = v1;
vec[1] = v2;
vec[2] = v3;
}

View File

@ -0,0 +1,332 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// upper design bounds
#define MAX_MAP_HULLS 4
#define MAX_MAP_MODELS 400
#define MAX_MAP_BRUSHES 4096
#define MAX_MAP_ENTITIES 1024
#define MAX_MAP_ENTSTRING (128*1024)
#define MAX_MAP_PLANES 32767
#define MAX_MAP_NODES 32767 // because negative shorts are contents
#define MAX_MAP_CLIPNODES 32767 //
#define MAX_MAP_LEAFS 8192
#define MAX_MAP_VERTS 65535
#define MAX_MAP_FACES 65535
#define MAX_MAP_MARKSURFACES 65535
#define MAX_MAP_TEXINFO 8192
#define MAX_MAP_EDGES 256000
#define MAX_MAP_SURFEDGES 512000
#define MAX_MAP_TEXTURES 512
#define MAX_MAP_MIPTEX 0x200000
#define MAX_MAP_LIGHTING 0x200000
#define MAX_MAP_VISIBILITY 0x200000
#define MAX_MAP_PORTALS 65536
// key / value pair sizes
#define MAX_KEY 32
#define MAX_VALUE 1024
//=============================================================================
#define BSPVERSION 30
#define TOOLVERSION 2
typedef struct
{
int fileofs, filelen;
} lump_t;
#define LUMP_ENTITIES 0
#define LUMP_PLANES 1
#define LUMP_TEXTURES 2
#define LUMP_VERTEXES 3
#define LUMP_VISIBILITY 4
#define LUMP_NODES 5
#define LUMP_TEXINFO 6
#define LUMP_FACES 7
#define LUMP_LIGHTING 8
#define LUMP_CLIPNODES 9
#define LUMP_LEAFS 10
#define LUMP_MARKSURFACES 11
#define LUMP_EDGES 12
#define LUMP_SURFEDGES 13
#define LUMP_MODELS 14
#define HEADER_LUMPS 15
typedef struct
{
float mins[3], maxs[3];
float origin[3];
int headnode[MAX_MAP_HULLS];
int visleafs; // not including the solid leaf 0
int firstface, numfaces;
} dmodel_t;
typedef struct
{
int version;
lump_t lumps[HEADER_LUMPS];
} dheader_t;
typedef struct
{
int nummiptex;
int dataofs[4]; // [nummiptex]
} dmiptexlump_t;
#define MIPLEVELS 4
typedef struct miptex_s
{
char name[16];
unsigned width, height;
unsigned offsets[MIPLEVELS]; // four mip maps stored
} miptex_t;
typedef struct
{
float point[3];
} dvertex_t;
// 0-2 are axial planes
#define PLANE_X 0
#define PLANE_Y 1
#define PLANE_Z 2
// 3-5 are non-axial planes snapped to the nearest
#define PLANE_ANYX 3
#define PLANE_ANYY 4
#define PLANE_ANYZ 5
typedef struct
{
float normal[3];
float dist;
int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
} dplane_t;
#define CONTENTS_EMPTY -1
#define CONTENTS_SOLID -2
#define CONTENTS_WATER -3
#define CONTENTS_SLIME -4
#define CONTENTS_LAVA -5
#define CONTENTS_SKY -6
#define CONTENTS_ORIGIN -7 // removed at csg time
#define CONTENTS_CLIP -8 // changed to contents_solid
#define CONTENTS_CURRENT_0 -9
#define CONTENTS_CURRENT_90 -10
#define CONTENTS_CURRENT_180 -11
#define CONTENTS_CURRENT_270 -12
#define CONTENTS_CURRENT_UP -13
#define CONTENTS_CURRENT_DOWN -14
#define CONTENTS_TRANSLUCENT -15
// !!! if this is changed, it must be changed in asm_i386.h too !!!
typedef struct
{
int planenum;
short children[2]; // negative numbers are -(leafs+1), not nodes
short mins[3]; // for sphere culling
short maxs[3];
unsigned short firstface;
unsigned short numfaces; // counting both sides
} dnode_t;
typedef struct
{
int planenum;
short children[2]; // negative numbers are contents
} dclipnode_t;
typedef struct texinfo_s
{
float vecs[2][4]; // [s/t][xyz offset]
int miptex;
int flags;
} texinfo_t;
#define TEX_SPECIAL 1 // sky or slime, no lightmap or 256 subdivision
// note that edge 0 is never used, because negative edge nums are used for
// counterclockwise use of the edge in a face
typedef struct
{
unsigned short v[2]; // vertex numbers
} dedge_t;
#define MAXLIGHTMAPS 4
typedef struct
{
short planenum;
short side;
int firstedge; // we must support > 64k edges
short numedges;
short texinfo;
// lighting info
byte styles[MAXLIGHTMAPS];
int lightofs; // start of [numstyles*surfsize] samples
} dface_t;
#define AMBIENT_WATER 0
#define AMBIENT_SKY 1
#define AMBIENT_SLIME 2
#define AMBIENT_LAVA 3
#define NUM_AMBIENTS 4 // automatic ambient sounds
// leaf 0 is the generic CONTENTS_SOLID leaf, used for all solid areas
// all other leafs need visibility info
typedef struct
{
int contents;
int visofs; // -1 = no visibility info
short mins[3]; // for frustum culling
short maxs[3];
unsigned short firstmarksurface;
unsigned short nummarksurfaces;
byte ambient_level[NUM_AMBIENTS];
} dleaf_t;
//============================================================================
#ifndef QUAKE_GAME
#define ANGLE_UP -1
#define ANGLE_DOWN -2
// the utilities get to be lazy and just use large static arrays
extern int nummodels;
extern dmodel_t dmodels[MAX_MAP_MODELS];
extern int dmodels_checksum;
extern int visdatasize;
extern byte dvisdata[MAX_MAP_VISIBILITY];
extern int dvisdata_checksum;
extern int lightdatasize;
extern byte dlightdata[MAX_MAP_LIGHTING];
extern int dlightdata_checksum;
extern int texdatasize;
extern byte dtexdata[MAX_MAP_MIPTEX]; // (dmiptexlump_t)
extern int dtexdata_checksum;
extern int entdatasize;
extern char dentdata[MAX_MAP_ENTSTRING];
extern int dentdata_checksum;
extern int numleafs;
extern dleaf_t dleafs[MAX_MAP_LEAFS];
extern int dleafs_checksum;
extern int numplanes;
extern dplane_t dplanes[MAX_MAP_PLANES];
extern int dplanes_checksum;
extern int numvertexes;
extern dvertex_t dvertexes[MAX_MAP_VERTS];
extern int dvertexes_checksum;
extern int numnodes;
extern dnode_t dnodes[MAX_MAP_NODES];
extern int dnodes_checksum;
extern int numtexinfo;
extern texinfo_t texinfo[MAX_MAP_TEXINFO];
extern int texinfo_checksum;
extern int numfaces;
extern dface_t dfaces[MAX_MAP_FACES];
extern int dfaces_checksum;
extern int numclipnodes;
extern dclipnode_t dclipnodes[MAX_MAP_CLIPNODES];
extern int dclipnodes_checksum;
extern int numedges;
extern dedge_t dedges[MAX_MAP_EDGES];
extern int dedges_checksum;
extern int nummarksurfaces;
extern unsigned short dmarksurfaces[MAX_MAP_MARKSURFACES];
extern int dmarksurfaces_checksum;
extern int numsurfedges;
extern int dsurfedges[MAX_MAP_SURFEDGES];
extern int dsurfedges_checksum;
int FastChecksum(void *buffer, int bytes);
void DecompressVis (byte *in, byte *decompressed);
int CompressVis (byte *vis, byte *dest);
void LoadBSPFile (char *filename);
void WriteBSPFile (char *filename);
void PrintBSPFileSizes (void);
//===============
typedef struct epair_s
{
struct epair_s *next;
char *key;
char *value;
} epair_t;
typedef struct
{
vec3_t origin;
int firstbrush;
int numbrushes;
epair_t *epairs;
} entity_t;
extern int num_entities;
extern entity_t entities[MAX_MAP_ENTITIES];
void ParseEntities (void);
void UnparseEntities (void);
void SetKeyValue (entity_t *ent, char *key, char *value);
char *ValueForKey (entity_t *ent, char *key);
// will return "" if not present
vec_t FloatForKey (entity_t *ent, char *key);
void GetVectorForKey (entity_t *ent, char *key, vec3_t vec);
epair_t *ParseEpair (void);
#endif

1040
hlsdk/utils/common/cmdlib.c Normal file

File diff suppressed because it is too large Load Diff

158
hlsdk/utils/common/cmdlib.h Normal file
View File

@ -0,0 +1,158 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// cmdlib.h
#ifndef __CMDLIB__
#define __CMDLIB__
#if defined _MSC_VER && _MSC_VER >= 1400
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif
#pragma warning(disable: 4996) // deprecated functions
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>
#include <stdarg.h>
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef __CMDUTIL__
#define __CMDUTIL__
#ifndef _NOENUMQBOOL
typedef enum {false, true} qboolean;
#else
typedef int qboolean;
#undef true
#undef false
#define true 1
#define false 0
#endif
typedef unsigned char byte;
#endif
// the dec offsetof macro doesn't work very well...
#define myoffsetof(type,identifier) ((size_t)&((type *)0)->identifier)
// set these before calling CheckParm
extern int myargc;
extern char **myargv;
void COM_FixSlashes( char *pname );
char *strupr (char *in);
char *strlower (char *in);
int Q_strncasecmp (char *s1, char *s2, int n);
int Q_strcasecmp (char *s1, char *s2);
void Q_getwd (char *out);
int filelength (FILE *f);
int FileTime (char *path);
void Q_mkdir (char *path);
extern char qdir[1024];
extern char gamedir[1024];
void SetQdirFromPath (char *path);
char *ExpandArg (char *path); // from cmd line
char *ExpandPath (char *path); // from scripts
char *ExpandPathAndArchive (char *path);
double I_FloatTime (void);
void Error (char *error, ...);
int CheckParm (char *check);
FILE *SafeOpenWrite (char *filename);
FILE *SafeOpenRead (char *filename);
void SafeRead (FILE *f, void *buffer, int count);
void SafeWrite (FILE *f, void *buffer, int count);
int LoadFile (char *filename, void **bufferptr);
void SaveFile (char *filename, void *buffer, int count);
void DefaultExtension (char *path, char *extension);
void DefaultPath (char *path, char *basepath);
void StripFilename (char *path);
void StripExtension (char *path);
void ExtractFilePath (char *path, char *dest);
void ExtractFileBase (char *path, char *dest);
void ExtractFileExtension (char *path, char *dest);
int ParseNum (char *str);
short BigShort (short l);
short LittleShort (short l);
int BigLong (int l);
int LittleLong (int l);
float BigFloat (float l);
float LittleFloat (float l);
long flen(FILE* f);
char *COM_Parse (char *data);
extern char com_token[1024];
extern qboolean com_eof;
char *copystring(char *s);
void CRC_Init(unsigned short *crcvalue);
void CRC_ProcessByte(unsigned short *crcvalue, byte data);
unsigned short CRC_Value(unsigned short crcvalue);
void CreatePath (char *path);
void QCopyFile (char *from, char *to);
extern qboolean archive;
extern char archivedir[1024];
extern qboolean verbose;
void qprintf (char *format, ...);
typedef struct
{
char name[56];
int filepos, filelen;
} packfile_t;
typedef struct
{
char id[4];
int dirofs;
int dirlen;
} packheader_t;
void ListPak(char* pakname);
#endif
#ifdef __cplusplus
}
#endif

744
hlsdk/utils/common/lbmlib.c Normal file
View File

@ -0,0 +1,744 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// lbmlib.c
#include <WINDOWS.H>
#include <STDIO.H>
#include "cmdlib.h"
#include "lbmlib.h"
/*
============================================================================
LBM STUFF
============================================================================
*/
#define FORMID ('F'+('O'<<8)+((int)'R'<<16)+((int)'M'<<24))
#define ILBMID ('I'+('L'<<8)+((int)'B'<<16)+((int)'M'<<24))
#define PBMID ('P'+('B'<<8)+((int)'M'<<16)+((int)' '<<24))
#define BMHDID ('B'+('M'<<8)+((int)'H'<<16)+((int)'D'<<24))
#define BODYID ('B'+('O'<<8)+((int)'D'<<16)+((int)'Y'<<24))
#define CMAPID ('C'+('M'<<8)+((int)'A'<<16)+((int)'P'<<24))
bmhd_t bmhd;
int Align (int l)
{
if (l&1)
return l+1;
return l;
}
/*
================
=
= LBMRLEdecompress
=
= Source must be evenly aligned!
=
================
*/
byte *LBMRLEDecompress (byte *source,byte *unpacked, int bpwidth)
{
int count;
byte b,rept;
count = 0;
do
{
rept = *source++;
if (rept > 0x80)
{
rept = (rept^0xff)+2;
b = *source++;
memset(unpacked,b,rept);
unpacked += rept;
}
else if (rept < 0x80)
{
rept++;
memcpy(unpacked,source,rept);
unpacked += rept;
source += rept;
}
else
rept = 0; // rept of 0x80 is NOP
count += rept;
} while (count<bpwidth);
if (count>bpwidth)
Error ("Decompression exceeded width!\n");
return source;
}
#define BPLANESIZE 128
byte bitplanes[9][BPLANESIZE]; // max size 1024 by 9 bit planes
/*
=================
=
= MungeBitPlanes8
=
= This destroys the bit plane data!
=
=================
*/
void MungeBitPlanes8 (int width, byte *dest)
{
*dest=width; // shut up the compiler warning
Error ("MungeBitPlanes8 not rewritten!");
#if 0
asm les di,[dest]
asm mov si,-1
asm mov cx,[width]
mungebyte:
asm inc si
asm mov dx,8
mungebit:
asm shl [BYTE PTR bitplanes + BPLANESIZE*7 +si],1
asm rcl al,1
asm shl [BYTE PTR bitplanes + BPLANESIZE*6 +si],1
asm rcl al,1
asm shl [BYTE PTR bitplanes + BPLANESIZE*5 +si],1
asm rcl al,1
asm shl [BYTE PTR bitplanes + BPLANESIZE*4 +si],1
asm rcl al,1
asm shl [BYTE PTR bitplanes + BPLANESIZE*3 +si],1
asm rcl al,1
asm shl [BYTE PTR bitplanes + BPLANESIZE*2 +si],1
asm rcl al,1
asm shl [BYTE PTR bitplanes + BPLANESIZE*1 +si],1
asm rcl al,1
asm shl [BYTE PTR bitplanes + BPLANESIZE*0 +si],1
asm rcl al,1
asm stosb
asm dec cx
asm jz done
asm dec dx
asm jnz mungebit
asm jmp mungebyte
done:
#endif
}
void MungeBitPlanes4 (int width, byte *dest)
{
*dest=width; // shut up the compiler warning
Error ("MungeBitPlanes4 not rewritten!");
#if 0
asm les di,[dest]
asm mov si,-1
asm mov cx,[width]
mungebyte:
asm inc si
asm mov dx,8
mungebit:
asm xor al,al
asm shl [BYTE PTR bitplanes + BPLANESIZE*3 +si],1
asm rcl al,1
asm shl [BYTE PTR bitplanes + BPLANESIZE*2 +si],1
asm rcl al,1
asm shl [BYTE PTR bitplanes + BPLANESIZE*1 +si],1
asm rcl al,1
asm shl [BYTE PTR bitplanes + BPLANESIZE*0 +si],1
asm rcl al,1
asm stosb
asm dec cx
asm jz done
asm dec dx
asm jnz mungebit
asm jmp mungebyte
done:
#endif
}
void MungeBitPlanes2 (int width, byte *dest)
{
*dest=width; // shut up the compiler warning
Error ("MungeBitPlanes2 not rewritten!");
#if 0
asm les di,[dest]
asm mov si,-1
asm mov cx,[width]
mungebyte:
asm inc si
asm mov dx,8
mungebit:
asm xor al,al
asm shl [BYTE PTR bitplanes + BPLANESIZE*1 +si],1
asm rcl al,1
asm shl [BYTE PTR bitplanes + BPLANESIZE*0 +si],1
asm rcl al,1
asm stosb
asm dec cx
asm jz done
asm dec dx
asm jnz mungebit
asm jmp mungebyte
done:
#endif
}
void MungeBitPlanes1 (int width, byte *dest)
{
*dest=width; // shut up the compiler warning
Error ("MungeBitPlanes1 not rewritten!");
#if 0
asm les di,[dest]
asm mov si,-1
asm mov cx,[width]
mungebyte:
asm inc si
asm mov dx,8
mungebit:
asm xor al,al
asm shl [BYTE PTR bitplanes + BPLANESIZE*0 +si],1
asm rcl al,1
asm stosb
asm dec cx
asm jz done
asm dec dx
asm jnz mungebit
asm jmp mungebyte
done:
#endif
}
int LoadBMP (const char* szFile, BYTE** ppbBits, BYTE** ppbPalette)
{
int i, rc = 0;
FILE *pfile = NULL;
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
RGBQUAD rgrgbPalette[256];
ULONG cbBmpBits;
BYTE* pbBmpBits;
byte *pb, *pbPal = NULL;
ULONG cbPalBytes;
ULONG biTrueWidth;
// Bogus parameter check
if (!(ppbPalette != NULL && ppbBits != NULL))
{ fprintf(stderr, "invalid BMP file\n"); rc = -1000; goto GetOut; }
// File exists?
if ((pfile = fopen(szFile, "rb")) == NULL)
{ fprintf(stderr, "unable to open BMP file\n"); rc = -1; goto GetOut; }
// Read file header
if (fread(&bmfh, sizeof bmfh, 1/*count*/, pfile) != 1)
{ rc = -2; goto GetOut; }
// Bogus file header check
if (!(bmfh.bfReserved1 == 0 && bmfh.bfReserved2 == 0))
{ rc = -2000; goto GetOut; }
// Read info header
if (fread(&bmih, sizeof bmih, 1/*count*/, pfile) != 1)
{ rc = -3; goto GetOut; }
// Bogus info header check
if (!(bmih.biSize == sizeof bmih && bmih.biPlanes == 1))
{ fprintf(stderr, "invalid BMP file header\n"); rc = -3000; goto GetOut; }
// Bogus bit depth? Only 8-bit supported.
if (bmih.biBitCount != 8)
{ fprintf(stderr, "BMP file not 8 bit\n"); rc = -4; goto GetOut; }
// Bogus compression? Only non-compressed supported.
if (bmih.biCompression != BI_RGB)
{ fprintf(stderr, "invalid BMP compression type\n"); rc = -5; goto GetOut; }
// Figure out how many entires are actually in the table
if (bmih.biClrUsed == 0)
{
bmih.biClrUsed = 256;
cbPalBytes = (1 << bmih.biBitCount) * sizeof( RGBQUAD );
}
else
{
cbPalBytes = bmih.biClrUsed * sizeof( RGBQUAD );
}
// Read palette (bmih.biClrUsed entries)
if (fread(rgrgbPalette, cbPalBytes, 1/*count*/, pfile) != 1)
{ rc = -6; goto GetOut; }
// convert to a packed 768 byte palette
pbPal = malloc(768);
if (pbPal == NULL)
{ rc = -7; goto GetOut; }
pb = pbPal;
// Copy over used entries
for (i = 0; i < (int)bmih.biClrUsed; i++)
{
*pb++ = rgrgbPalette[i].rgbRed;
*pb++ = rgrgbPalette[i].rgbGreen;
*pb++ = rgrgbPalette[i].rgbBlue;
}
// Fill in unused entires will 0,0,0
for (i = bmih.biClrUsed; i < 256; i++)
{
*pb++ = 0;
*pb++ = 0;
*pb++ = 0;
}
// Read bitmap bits (remainder of file)
cbBmpBits = bmfh.bfSize - ftell(pfile);
pb = malloc(cbBmpBits);
if (fread(pb, cbBmpBits, 1/*count*/, pfile) != 1)
{ rc = -7; goto GetOut; }
pbBmpBits = malloc(cbBmpBits);
// data is actually stored with the width being rounded up to a multiple of 4
biTrueWidth = (bmih.biWidth + 3) & ~3;
// reverse the order of the data.
pb += (bmih.biHeight - 1) * biTrueWidth;
for(i = 0; i < bmih.biHeight; i++)
{
memmove(&pbBmpBits[biTrueWidth * i], pb, biTrueWidth);
pb -= biTrueWidth;
}
pb += biTrueWidth;
free(pb);
bmhd.w = (WORD)bmih.biWidth;
bmhd.h = (WORD)bmih.biHeight;
// Set output parameters
*ppbPalette = pbPal;
*ppbBits = pbBmpBits;
GetOut:
if (pfile)
fclose(pfile);
return rc;
}
int WriteBMPfile (char *szFile, byte *pbBits, int width, int height, byte *pbPalette)
{
int i, rc = 0;
FILE *pfile = NULL;
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
RGBQUAD rgrgbPalette[256];
ULONG cbBmpBits;
BYTE* pbBmpBits;
byte *pb, *pbPal = NULL;
ULONG cbPalBytes;
ULONG biTrueWidth;
// Bogus parameter check
if (!(pbPalette != NULL && pbBits != NULL))
{ rc = -1000; goto GetOut; }
// File exists?
if ((pfile = fopen(szFile, "wb")) == NULL)
{ rc = -1; goto GetOut; }
biTrueWidth = ((width + 3) & ~3);
cbBmpBits = biTrueWidth * height;
cbPalBytes = 256 * sizeof( RGBQUAD );
// Bogus file header check
bmfh.bfType = MAKEWORD( 'B', 'M' );
bmfh.bfSize = sizeof bmfh + sizeof bmih + cbBmpBits + cbPalBytes;
bmfh.bfReserved1 = 0;
bmfh.bfReserved2 = 0;
bmfh.bfOffBits = sizeof bmfh + sizeof bmih + cbPalBytes;
// Write file header
if (fwrite(&bmfh, sizeof bmfh, 1/*count*/, pfile) != 1)
{ rc = -2; goto GetOut; }
// Size of structure
bmih.biSize = sizeof bmih;
// Width
bmih.biWidth = biTrueWidth;
// Height
bmih.biHeight = height;
// Only 1 plane
bmih.biPlanes = 1;
// Only 8-bit supported.
bmih.biBitCount = 8;
// Only non-compressed supported.
bmih.biCompression = BI_RGB;
bmih.biSizeImage = 0;
// huh?
bmih.biXPelsPerMeter = 0;
bmih.biYPelsPerMeter = 0;
// Always full palette
bmih.biClrUsed = 256;
bmih.biClrImportant = 0;
// Write info header
if (fwrite(&bmih, sizeof bmih, 1/*count*/, pfile) != 1)
{ rc = -3; goto GetOut; }
// convert to expanded palette
pb = pbPalette;
// Copy over used entries
for (i = 0; i < (int)bmih.biClrUsed; i++)
{
rgrgbPalette[i].rgbRed = *pb++;
rgrgbPalette[i].rgbGreen = *pb++;
rgrgbPalette[i].rgbBlue = *pb++;
rgrgbPalette[i].rgbReserved = 0;
}
// Write palette (bmih.biClrUsed entries)
cbPalBytes = bmih.biClrUsed * sizeof( RGBQUAD );
if (fwrite(rgrgbPalette, cbPalBytes, 1/*count*/, pfile) != 1)
{ rc = -6; goto GetOut; }
pbBmpBits = malloc(cbBmpBits);
pb = pbBits;
// reverse the order of the data.
pb += (height - 1) * width;
for(i = 0; i < bmih.biHeight; i++)
{
memmove(&pbBmpBits[biTrueWidth * i], pb, width);
pb -= width;
}
// Write bitmap bits (remainder of file)
if (fwrite(pbBmpBits, cbBmpBits, 1/*count*/, pfile) != 1)
{ rc = -7; goto GetOut; }
free(pbBmpBits);
GetOut:
if (pfile)
fclose(pfile);
return rc;
}
/*
=================
=
= LoadLBM
=
=================
*/
void LoadLBM (char *filename, byte **picture, byte **palette)
{
byte *LBMbuffer, *picbuffer, *cmapbuffer;
int y,p,planes;
byte *LBM_P, *LBMEND_P;
byte *pic_p;
byte *body_p;
unsigned rowsize;
int formtype,formlength;
int chunktype,chunklength;
void (*mungecall) (int, byte *);
// qiet compiler warnings
picbuffer = NULL;
cmapbuffer = NULL;
mungecall = NULL;
//
// load the LBM
//
LoadFile (filename, (void **)&LBMbuffer);
//
// parse the LBM header
//
LBM_P = LBMbuffer;
if ( *(int *)LBMbuffer != LittleLong(FORMID) )
Error ("No FORM ID at start of file!\n");
LBM_P += 4;
formlength = BigLong( *(int *)LBM_P );
LBM_P += 4;
LBMEND_P = LBM_P + Align(formlength);
formtype = LittleLong(*(int *)LBM_P);
if (formtype != ILBMID && formtype != PBMID)
Error ("Unrecognized form type: %c%c%c%c\n", formtype&0xff
,(formtype>>8)&0xff,(formtype>>16)&0xff,(formtype>>24)&0xff);
LBM_P += 4;
//
// parse chunks
//
while (LBM_P < LBMEND_P)
{
chunktype = LBM_P[0] + (LBM_P[1]<<8) + (LBM_P[2]<<16) + (LBM_P[3]<<24);
LBM_P += 4;
chunklength = LBM_P[3] + (LBM_P[2]<<8) + (LBM_P[1]<<16) + (LBM_P[0]<<24);
LBM_P += 4;
switch ( chunktype )
{
case BMHDID:
memcpy (&bmhd,LBM_P,sizeof(bmhd));
bmhd.w = BigShort(bmhd.w);
bmhd.h = BigShort(bmhd.h);
bmhd.x = BigShort(bmhd.x);
bmhd.y = BigShort(bmhd.y);
bmhd.pageWidth = BigShort(bmhd.pageWidth);
bmhd.pageHeight = BigShort(bmhd.pageHeight);
break;
case CMAPID:
cmapbuffer = malloc (768);
memset (cmapbuffer, 0, 768);
memcpy (cmapbuffer, LBM_P, chunklength);
break;
case BODYID:
body_p = LBM_P;
pic_p = picbuffer = malloc (bmhd.w*bmhd.h);
if (formtype == PBMID)
{
//
// unpack PBM
//
for (y=0 ; y<bmhd.h ; y++, pic_p += bmhd.w)
{
if (bmhd.compression == cm_rle1)
body_p = LBMRLEDecompress ((byte *)body_p
, pic_p , bmhd.w);
else if (bmhd.compression == cm_none)
{
memcpy (pic_p,body_p,bmhd.w);
body_p += Align(bmhd.w);
}
}
}
else
{
//
// unpack ILBM
//
planes = bmhd.nPlanes;
if (bmhd.masking == ms_mask)
planes++;
rowsize = (bmhd.w+15)/16 * 2;
switch (bmhd.nPlanes)
{
case 1:
mungecall = MungeBitPlanes1;
break;
case 2:
mungecall = MungeBitPlanes2;
break;
case 4:
mungecall = MungeBitPlanes4;
break;
case 8:
mungecall = MungeBitPlanes8;
break;
default:
Error ("Can't munge %i bit planes!\n",bmhd.nPlanes);
}
for (y=0 ; y<bmhd.h ; y++, pic_p += bmhd.w)
{
for (p=0 ; p<planes ; p++)
if (bmhd.compression == cm_rle1)
body_p = LBMRLEDecompress ((byte *)body_p
, bitplanes[p] , rowsize);
else if (bmhd.compression == cm_none)
{
memcpy (bitplanes[p],body_p,rowsize);
body_p += rowsize;
}
mungecall (bmhd.w , pic_p);
}
}
break;
}
LBM_P += Align(chunklength);
}
free (LBMbuffer);
*picture = picbuffer;
*palette = cmapbuffer;
}
/*
============================================================================
WRITE LBM
============================================================================
*/
/*
==============
=
= WriteLBMfile
=
==============
*/
void WriteLBMfile (char *filename, byte *data, int width, int height, byte *palette)
{
byte *lbm, *lbmptr;
int *formlength, *bmhdlength, *cmaplength, *bodylength;
int length;
bmhd_t basebmhd;
lbm = lbmptr = malloc (width*height+1000);
//
// start FORM
//
*lbmptr++ = 'F';
*lbmptr++ = 'O';
*lbmptr++ = 'R';
*lbmptr++ = 'M';
formlength = (int*)lbmptr;
lbmptr+=4; // leave space for length
*lbmptr++ = 'P';
*lbmptr++ = 'B';
*lbmptr++ = 'M';
*lbmptr++ = ' ';
//
// write BMHD
//
*lbmptr++ = 'B';
*lbmptr++ = 'M';
*lbmptr++ = 'H';
*lbmptr++ = 'D';
bmhdlength = (int *)lbmptr;
lbmptr+=4; // leave space for length
memset (&basebmhd,0,sizeof(basebmhd));
basebmhd.w = BigShort((short)width);
basebmhd.h = BigShort((short)height);
basebmhd.nPlanes = (BYTE)BigShort(8);
basebmhd.xAspect = (BYTE)BigShort(5);
basebmhd.yAspect = (BYTE)BigShort(6);
basebmhd.pageWidth = BigShort((short)width);
basebmhd.pageHeight = BigShort((short)height);
memcpy (lbmptr,&basebmhd,sizeof(basebmhd));
lbmptr += sizeof(basebmhd);
length = lbmptr-(byte *)bmhdlength-4;
*bmhdlength = BigLong(length);
if (length&1)
*lbmptr++ = 0; // pad chunk to even offset
//
// write CMAP
//
*lbmptr++ = 'C';
*lbmptr++ = 'M';
*lbmptr++ = 'A';
*lbmptr++ = 'P';
cmaplength = (int *)lbmptr;
lbmptr+=4; // leave space for length
memcpy (lbmptr,palette,768);
lbmptr += 768;
length = lbmptr-(byte *)cmaplength-4;
*cmaplength = BigLong(length);
if (length&1)
*lbmptr++ = 0; // pad chunk to even offset
//
// write BODY
//
*lbmptr++ = 'B';
*lbmptr++ = 'O';
*lbmptr++ = 'D';
*lbmptr++ = 'Y';
bodylength = (int *)lbmptr;
lbmptr+=4; // leave space for length
memcpy (lbmptr,data,width*height);
lbmptr += width*height;
length = lbmptr-(byte *)bodylength-4;
*bodylength = BigLong(length);
if (length&1)
*lbmptr++ = 0; // pad chunk to even offset
//
// done
//
length = lbmptr-(byte *)formlength-4;
*formlength = BigLong(length);
if (length&1)
*lbmptr++ = 0; // pad chunk to even offset
//
// write output file
//
SaveFile (filename, lbm, lbmptr-lbm);
free (lbm);
}

View File

@ -0,0 +1,57 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// lbmlib.h
typedef unsigned char UBYTE;
#ifndef _WINDOWS_
typedef short WORD;
#endif
typedef unsigned short UWORD;
typedef long LONG;
typedef enum
{
ms_none,
ms_mask,
ms_transcolor,
ms_lasso
} mask_t;
typedef enum
{
cm_none,
cm_rle1
} compress_t;
typedef struct
{
UWORD w,h;
WORD x,y;
UBYTE nPlanes;
UBYTE masking;
UBYTE compression;
UBYTE pad1;
UWORD transparentColor;
UBYTE xAspect,yAspect;
WORD pageWidth,pageHeight;
} bmhd_t;
extern bmhd_t bmhd; // will be in native byte order
void LoadLBM (char *filename, byte **picture, byte **palette);
int LoadBMP (const char* szFile, byte** ppbBits, byte** ppbPalette);
void WriteLBMfile (char *filename, byte *data, int width, int height
, byte *palette);
int WriteBMPfile (char *szFile, byte *pbBits, int width, int height, byte *pbPalette);

View File

@ -0,0 +1,351 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// mathlib.c -- math primitives
#pragma warning( disable : 4244 )
#pragma warning( disable : 4237 )
#pragma warning( disable : 4305 )
#include "cmdlib.h"
#include "mathlib.h"
vec3_t vec3_origin = {0,0,0};
double VectorLength(vec3_t v)
{
int i;
double length;
length = 0;
for (i=0 ; i< 3 ; i++)
length += v[i]*v[i];
length = sqrt (length); // FIXME
return length;
}
int VectorCompare (vec3_t v1, vec3_t v2)
{
int i;
for (i=0 ; i<3 ; i++)
if (fabs(v1[i]-v2[i]) > EQUAL_EPSILON)
return false;
return true;
}
vec_t Q_rint (vec_t in)
{
return floor (in + 0.5);
}
void VectorMA (vec3_t va, double scale, vec3_t vb, vec3_t vc)
{
vc[0] = va[0] + scale*vb[0];
vc[1] = va[1] + scale*vb[1];
vc[2] = va[2] + scale*vb[2];
}
void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross)
{
cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
cross[1] = v1[2]*v2[0] - v1[0]*v2[2];
cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
}
vec_t _DotProduct (vec3_t v1, vec3_t v2)
{
return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
}
void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out)
{
out[0] = va[0]-vb[0];
out[1] = va[1]-vb[1];
out[2] = va[2]-vb[2];
}
void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out)
{
out[0] = va[0]+vb[0];
out[1] = va[1]+vb[1];
out[2] = va[2]+vb[2];
}
void _VectorCopy (vec3_t in, vec3_t out)
{
out[0] = in[0];
out[1] = in[1];
out[2] = in[2];
}
void _VectorScale (vec3_t v, vec_t scale, vec3_t out)
{
out[0] = v[0] * scale;
out[1] = v[1] * scale;
out[2] = v[2] * scale;
}
vec_t VectorNormalize (vec3_t v)
{
int i;
double length;
if ( fabs(v[1] - 0.000215956) < 0.0001)
i=1;
length = 0;
for (i=0 ; i< 3 ; i++)
length += v[i]*v[i];
length = sqrt (length);
if (length == 0)
return 0;
for (i=0 ; i< 3 ; i++)
v[i] /= length;
return length;
}
void VectorInverse (vec3_t v)
{
v[0] = -v[0];
v[1] = -v[1];
v[2] = -v[2];
}
void ClearBounds (vec3_t mins, vec3_t maxs)
{
mins[0] = mins[1] = mins[2] = 99999;
maxs[0] = maxs[1] = maxs[2] = -99999;
}
void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs)
{
int i;
vec_t val;
for (i=0 ; i<3 ; i++)
{
val = v[i];
if (val < mins[i])
mins[i] = val;
if (val > maxs[i])
maxs[i] = val;
}
}
void AngleMatrix (const vec3_t angles, float (*matrix)[4] )
{
float angle;
float sr, sp, sy, cr, cp, cy;
angle = angles[2] * (Q_PI*2 / 360);
sy = sin(angle);
cy = cos(angle);
angle = angles[1] * (Q_PI*2 / 360);
sp = sin(angle);
cp = cos(angle);
angle = angles[0] * (Q_PI*2 / 360);
sr = sin(angle);
cr = cos(angle);
// matrix = (Z * Y) * X
matrix[0][0] = cp*cy;
matrix[1][0] = cp*sy;
matrix[2][0] = -sp;
matrix[0][1] = sr*sp*cy+cr*-sy;
matrix[1][1] = sr*sp*sy+cr*cy;
matrix[2][1] = sr*cp;
matrix[0][2] = (cr*sp*cy+-sr*-sy);
matrix[1][2] = (cr*sp*sy+-sr*cy);
matrix[2][2] = cr*cp;
matrix[0][3] = 0.0;
matrix[1][3] = 0.0;
matrix[2][3] = 0.0;
}
void AngleIMatrix (const vec3_t angles, float matrix[3][4] )
{
float angle;
float sr, sp, sy, cr, cp, cy;
angle = angles[2] * (Q_PI*2 / 360);
sy = sin(angle);
cy = cos(angle);
angle = angles[1] * (Q_PI*2 / 360);
sp = sin(angle);
cp = cos(angle);
angle = angles[0] * (Q_PI*2 / 360);
sr = sin(angle);
cr = cos(angle);
// matrix = (Z * Y) * X
matrix[0][0] = cp*cy;
matrix[0][1] = cp*sy;
matrix[0][2] = -sp;
matrix[1][0] = sr*sp*cy+cr*-sy;
matrix[1][1] = sr*sp*sy+cr*cy;
matrix[1][2] = sr*cp;
matrix[2][0] = (cr*sp*cy+-sr*-sy);
matrix[2][1] = (cr*sp*sy+-sr*cy);
matrix[2][2] = cr*cp;
matrix[0][3] = 0.0;
matrix[1][3] = 0.0;
matrix[2][3] = 0.0;
}
void R_ConcatTransforms (const float in1[3][4], const float in2[3][4], float out[3][4])
{
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] +
in1[0][2] * in2[2][0];
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] +
in1[0][2] * in2[2][1];
out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] +
in1[0][2] * in2[2][2];
out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] +
in1[0][2] * in2[2][3] + in1[0][3];
out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] +
in1[1][2] * in2[2][0];
out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] +
in1[1][2] * in2[2][1];
out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] +
in1[1][2] * in2[2][2];
out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] +
in1[1][2] * in2[2][3] + in1[1][3];
out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] +
in1[2][2] * in2[2][0];
out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] +
in1[2][2] * in2[2][1];
out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] +
in1[2][2] * in2[2][2];
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] +
in1[2][2] * in2[2][3] + in1[2][3];
}
void VectorRotate (const vec3_t in1, const float in2[3][4], vec3_t out)
{
out[0] = DotProduct(in1, in2[0]);
out[1] = DotProduct(in1, in2[1]);
out[2] = DotProduct(in1, in2[2]);
}
// rotate by the inverse of the matrix
void VectorIRotate (const vec3_t in1, const float in2[3][4], vec3_t out)
{
out[0] = in1[0]*in2[0][0] + in1[1]*in2[1][0] + in1[2]*in2[2][0];
out[1] = in1[0]*in2[0][1] + in1[1]*in2[1][1] + in1[2]*in2[2][1];
out[2] = in1[0]*in2[0][2] + in1[1]*in2[1][2] + in1[2]*in2[2][2];
}
void VectorTransform (const vec3_t in1, const float in2[3][4], vec3_t out)
{
out[0] = DotProduct(in1, in2[0]) + in2[0][3];
out[1] = DotProduct(in1, in2[1]) + in2[1][3];
out[2] = DotProduct(in1, in2[2]) + in2[2][3];
}
void AngleQuaternion( const vec3_t angles, vec4_t quaternion )
{
float angle;
float sr, sp, sy, cr, cp, cy;
// FIXME: rescale the inputs to 1/2 angle
angle = angles[2] * 0.5;
sy = sin(angle);
cy = cos(angle);
angle = angles[1] * 0.5;
sp = sin(angle);
cp = cos(angle);
angle = angles[0] * 0.5;
sr = sin(angle);
cr = cos(angle);
quaternion[0] = sr*cp*cy-cr*sp*sy; // X
quaternion[1] = cr*sp*cy+sr*cp*sy; // Y
quaternion[2] = cr*cp*sy-sr*sp*cy; // Z
quaternion[3] = cr*cp*cy+sr*sp*sy; // W
}
void QuaternionMatrix( const vec4_t quaternion, float (*matrix)[4] )
{
matrix[0][0] = 1.0 - 2.0 * quaternion[1] * quaternion[1] - 2.0 * quaternion[2] * quaternion[2];
matrix[1][0] = 2.0 * quaternion[0] * quaternion[1] + 2.0 * quaternion[3] * quaternion[2];
matrix[2][0] = 2.0 * quaternion[0] * quaternion[2] - 2.0 * quaternion[3] * quaternion[1];
matrix[0][1] = 2.0 * quaternion[0] * quaternion[1] - 2.0 * quaternion[3] * quaternion[2];
matrix[1][1] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[2] * quaternion[2];
matrix[2][1] = 2.0 * quaternion[1] * quaternion[2] + 2.0 * quaternion[3] * quaternion[0];
matrix[0][2] = 2.0 * quaternion[0] * quaternion[2] + 2.0 * quaternion[3] * quaternion[1];
matrix[1][2] = 2.0 * quaternion[1] * quaternion[2] - 2.0 * quaternion[3] * quaternion[0];
matrix[2][2] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[1] * quaternion[1];
}
void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt )
{
int i;
float omega, cosom, sinom, sclp, sclq;
// decide if one of the quaternions is backwards
float a = 0;
float b = 0;
for (i = 0; i < 4; i++) {
a += (p[i]-q[i])*(p[i]-q[i]);
b += (p[i]+q[i])*(p[i]+q[i]);
}
if (a > b) {
for (i = 0; i < 4; i++) {
q[i] = -q[i];
}
}
cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3];
if ((1.0 + cosom) > 0.00000001) {
if ((1.0 - cosom) > 0.00000001) {
omega = acos( cosom );
sinom = sin( omega );
sclp = sin( (1.0 - t)*omega) / sinom;
sclq = sin( t*omega ) / sinom;
}
else {
sclp = 1.0 - t;
sclq = t;
}
for (i = 0; i < 4; i++) {
qt[i] = sclp * p[i] + sclq * q[i];
}
}
else {
qt[0] = -p[1];
qt[1] = p[0];
qt[2] = -p[3];
qt[3] = p[2];
sclp = sin( (1.0 - t) * 0.5 * Q_PI);
sclq = sin( t * 0.5 * Q_PI);
for (i = 0; i < 3; i++) {
qt[i] = sclp * p[i] + sclq * qt[i];
}
}
}

View File

@ -0,0 +1,89 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#ifndef __MATHLIB__
#define __MATHLIB__
// mathlib.h
#include <math.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef DOUBLEVEC_T
typedef double vec_t;
#else
typedef float vec_t;
#endif
typedef vec_t vec3_t[3]; // x,y,z
typedef vec_t vec4_t[4]; // x,y,z,w
#define SIDE_FRONT 0
#define SIDE_ON 2
#define SIDE_BACK 1
#define SIDE_CROSS -2
#define Q_PI 3.14159265358979323846
extern vec3_t vec3_origin;
// Use this definition globally
#define ON_EPSILON 0.01
#define EQUAL_EPSILON 0.001
int VectorCompare (vec3_t v1, vec3_t v2);
#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
#define VectorFill(a,b) { (a)[0]=(b); (a)[1]=(b); (a)[2]=(b);}
#define VectorAvg(a) ( ( (a)[0] + (a)[1] + (a)[2] ) / 3 )
#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}
#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];}
#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];}
#define VectorScale(a,b,c) {(c)[0]=(b)*(a)[0];(c)[1]=(b)*(a)[1];(c)[2]=(b)*(a)[2];}
vec_t Q_rint (vec_t in);
vec_t _DotProduct (vec3_t v1, vec3_t v2);
void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out);
void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out);
void _VectorCopy (vec3_t in, vec3_t out);
void _VectorScale (vec3_t v, vec_t scale, vec3_t out);
double VectorLength(vec3_t v);
void VectorMA (vec3_t va, double scale, vec3_t vb, vec3_t vc);
void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross);
vec_t VectorNormalize (vec3_t v);
void VectorInverse (vec3_t v);
void ClearBounds (vec3_t mins, vec3_t maxs);
void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs);
void AngleMatrix (const vec3_t angles, float matrix[3][4] );
void AngleIMatrix (const vec3_t angles, float matrix[3][4] );
void R_ConcatTransforms (const float in1[3][4], const float in2[3][4], float out[3][4]);
void VectorIRotate (const vec3_t in1, const float in2[3][4], vec3_t out);
void VectorRotate (const vec3_t in1, const float in2[3][4], vec3_t out);
void VectorTransform (const vec3_t in1, const float in2[3][4], vec3_t out);
void AngleQuaternion( const vec3_t angles, vec4_t quaternion );
void QuaternionMatrix( const vec4_t quaternion, float (*matrix)[4] );
void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,36 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#ifndef _MOVIE_H_
#define _MOVIE_H_
/*
movie.h
definitions and such for dumping screen shots to make a movie
*/
typedef struct
{
unsigned long tag;
unsigned long size;
} movieblockheader_t;
typedef struct
{
short width;
short height;
short depth;
} movieframe_t;
#endif _MOVIE_H_

View File

@ -0,0 +1,708 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "cmdlib.h"
#include "mathlib.h"
#include "polylib.h"
int c_active_windings;
int c_peak_windings;
int c_winding_allocs;
int c_winding_points;
#define BOGUS_RANGE 8192
void pw(winding_t *w)
{
int i;
for (i=0 ; i<w->numpoints ; i++)
printf ("(%5.1f, %5.1f, %5.1f)\n",w->p[i][0], w->p[i][1],w->p[i][2]);
}
/*
=============
AllocWinding
=============
*/
winding_t *AllocWinding (int points)
{
winding_t *w;
int s;
c_winding_allocs++;
c_winding_points += points;
c_active_windings++;
if (c_active_windings > c_peak_windings)
c_peak_windings = c_active_windings;
s = sizeof(vec_t)*3*points + sizeof(int);
s += sizeof(vec_t) - sizeof(w->numpoints); // padding
w = malloc (s);
memset (w, 0, s);
return w;
}
void FreeWinding (winding_t *w)
{
c_active_windings--;
free (w);
}
/*
============
RemoveColinearPoints
============
*/
int c_removed;
void RemoveColinearPoints (winding_t *w)
{
int i, j, k;
vec3_t v1, v2;
int nump;
vec3_t p[MAX_POINTS_ON_WINDING];
nump = 0;
for (i=0 ; i<w->numpoints ; i++)
{
j = (i+1)%w->numpoints;
k = (i+w->numpoints-1)%w->numpoints;
VectorSubtract (w->p[j], w->p[i], v1);
VectorSubtract (w->p[i], w->p[k], v2);
VectorNormalize(v1);
VectorNormalize(v2);
if (DotProduct(v1, v2) < 1.0-ON_EPSILON)
{
VectorCopy (w->p[i], p[nump]);
nump++;
}
}
if (nump == w->numpoints)
return;
c_removed += w->numpoints - nump;
w->numpoints = nump;
memcpy (w->p, p, nump*sizeof(p[0]));
}
/*
============
WindingPlane
============
*/
void WindingPlane (winding_t *w, vec3_t normal, vec_t *dist)
{
vec3_t v1, v2;
VectorSubtract (w->p[1], w->p[0], v1);
VectorSubtract (w->p[2], w->p[0], v2);
CrossProduct (v2, v1, normal);
VectorNormalize (normal);
*dist = DotProduct (w->p[0], normal);
}
/*
=============
WindingArea
=============
*/
vec_t WindingArea (winding_t *w)
{
int i;
vec3_t d1, d2, cross;
vec_t total;
total = 0;
for (i=2 ; i<w->numpoints ; i++)
{
VectorSubtract (w->p[i-1], w->p[0], d1);
VectorSubtract (w->p[i], w->p[0], d2);
CrossProduct (d1, d2, cross);
total += 0.5 * VectorLength ( cross );
}
return total;
}
void WindingBounds (winding_t *w, vec3_t mins, vec3_t maxs)
{
vec_t v;
int i,j;
mins[0] = mins[1] = mins[2] = 99999;
maxs[0] = maxs[1] = maxs[2] = -99999;
for (i=0 ; i<w->numpoints ; i++)
{
for (j=0 ; j<3 ; j++)
{
v = w->p[i][j];
if (v < mins[j])
mins[j] = v;
if (v > maxs[j])
maxs[j] = v;
}
}
}
/*
=============
WindingCenter
=============
*/
void WindingCenter (winding_t *w, vec3_t center)
{
int i;
vec3_t d1, d2, cross;
float scale;
VectorCopy (vec3_origin, center);
for (i=0 ; i<w->numpoints ; i++)
VectorAdd (w->p[i], center, center);
scale = 1.0/w->numpoints;
VectorScale (center, scale, center);
}
/*
=================
BaseWindingForPlane
=================
*/
winding_t *BaseWindingForPlane (vec3_t normal, float dist)
{
int i, x;
vec_t max, v;
vec3_t org, vright, vup;
winding_t *w;
// find the major axis
max = -BOGUS_RANGE;
x = -1;
for (i=0 ; i<3; i++)
{
v = fabs(normal[i]);
if (v > max)
{
x = i;
max = v;
}
}
if (x==-1)
Error ("BaseWindingForPlane: no axis found");
VectorCopy (vec3_origin, vup);
switch (x)
{
case 0:
case 1:
vup[2] = 1;
break;
case 2:
vup[0] = 1;
break;
}
v = DotProduct (vup, normal);
VectorMA (vup, -v, normal, vup);
VectorNormalize (vup);
VectorScale (normal, dist, org);
CrossProduct (vup, normal, vright);
VectorScale (vup, 9000, vup);
VectorScale (vright, 9000, vright);
// project a really big axis aligned box onto the plane
w = AllocWinding (4);
VectorSubtract (org, vright, w->p[0]);
VectorAdd (w->p[0], vup, w->p[0]);
VectorAdd (org, vright, w->p[1]);
VectorAdd (w->p[1], vup, w->p[1]);
VectorAdd (org, vright, w->p[2]);
VectorSubtract (w->p[2], vup, w->p[2]);
VectorSubtract (org, vright, w->p[3]);
VectorSubtract (w->p[3], vup, w->p[3]);
w->numpoints = 4;
return w;
}
/*
==================
CopyWinding
==================
*/
winding_t *CopyWinding (winding_t *w)
{
int size;
winding_t *c;
size = (int)((winding_t *)0)->p[w->numpoints];
c = malloc (size);
memcpy (c, w, size);
return c;
}
/*
=============
ClipWinding
=============
*/
void ClipWinding (winding_t *in, vec3_t normal, vec_t dist,
winding_t **front, winding_t **back)
{
vec_t dists[MAX_POINTS_ON_WINDING+4];
int sides[MAX_POINTS_ON_WINDING+4];
int counts[3];
vec_t dot;
int i, j;
vec_t *p1, *p2;
vec3_t mid;
winding_t *f, *b;
int maxpts;
counts[0] = counts[1] = counts[2] = 0;
// determine sides for each point
for (i=0 ; i<in->numpoints ; i++)
{
dot = DotProduct (in->p[i], normal);
dot -= dist;
dists[i] = dot;
if (dot > ON_EPSILON)
sides[i] = SIDE_FRONT;
else if (dot < -ON_EPSILON)
sides[i] = SIDE_BACK;
else
{
sides[i] = SIDE_ON;
}
counts[sides[i]]++;
}
sides[i] = sides[0];
dists[i] = dists[0];
*front = *back = NULL;
if (!counts[0])
{
*back = CopyWinding (in);
return;
}
if (!counts[1])
{
*front = CopyWinding (in);
return;
}
maxpts = in->numpoints+4; // can't use counts[0]+2 because
// of fp grouping errors
*front = f = AllocWinding (maxpts);
*back = b = AllocWinding (maxpts);
for (i=0 ; i<in->numpoints ; i++)
{
p1 = in->p[i];
if (sides[i] == SIDE_ON)
{
VectorCopy (p1, f->p[f->numpoints]);
f->numpoints++;
VectorCopy (p1, b->p[b->numpoints]);
b->numpoints++;
continue;
}
if (sides[i] == SIDE_FRONT)
{
VectorCopy (p1, f->p[f->numpoints]);
f->numpoints++;
}
if (sides[i] == SIDE_BACK)
{
VectorCopy (p1, b->p[b->numpoints]);
b->numpoints++;
}
if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
continue;
// generate a split point
p2 = in->p[(i+1)%in->numpoints];
dot = dists[i] / (dists[i]-dists[i+1]);
for (j=0 ; j<3 ; j++)
{ // avoid round off error when possible
if (normal[j] == 1)
mid[j] = dist;
else if (normal[j] == -1)
mid[j] = -dist;
else
mid[j] = p1[j] + dot*(p2[j]-p1[j]);
}
VectorCopy (mid, f->p[f->numpoints]);
f->numpoints++;
VectorCopy (mid, b->p[b->numpoints]);
b->numpoints++;
}
if (f->numpoints > maxpts || b->numpoints > maxpts)
Error ("ClipWinding: points exceeded estimate");
if (f->numpoints > MAX_POINTS_ON_WINDING || b->numpoints > MAX_POINTS_ON_WINDING)
Error ("ClipWinding: MAX_POINTS_ON_WINDING");
}
/*
=============
ClipWindingNoCopy
=============
*/
void ClipWindingNoCopy (winding_t *in, vec3_t normal, vec_t dist,
winding_t **front, winding_t **back)
{
vec_t dists[MAX_POINTS_ON_WINDING+4];
int sides[MAX_POINTS_ON_WINDING+4];
int counts[3];
vec_t dot;
int i, j;
vec_t *p1, *p2;
vec3_t mid;
winding_t *f, *b;
int maxpts;
counts[0] = counts[1] = counts[2] = 0;
// determine sides for each point
for (i=0 ; i<in->numpoints ; i++)
{
dot = DotProduct (in->p[i], normal);
dot -= dist;
dists[i] = dot;
if (dot > ON_EPSILON)
sides[i] = SIDE_FRONT;
else if (dot < -ON_EPSILON)
sides[i] = SIDE_BACK;
else
{
sides[i] = SIDE_ON;
}
counts[sides[i]]++;
}
sides[i] = sides[0];
dists[i] = dists[0];
*front = *back = NULL;
if (!counts[0])
{
*back = in;
return;
}
if (!counts[1])
{
*front = in;
return;
}
maxpts = in->numpoints+4; // can't use counts[0]+2 because
// of fp grouping errors
*front = f = AllocWinding (maxpts);
*back = b = AllocWinding (maxpts);
for (i=0 ; i<in->numpoints ; i++)
{
p1 = in->p[i];
if (sides[i] == SIDE_ON)
{
VectorCopy (p1, f->p[f->numpoints]);
f->numpoints++;
VectorCopy (p1, b->p[b->numpoints]);
b->numpoints++;
continue;
}
if (sides[i] == SIDE_FRONT)
{
VectorCopy (p1, f->p[f->numpoints]);
f->numpoints++;
}
if (sides[i] == SIDE_BACK)
{
VectorCopy (p1, b->p[b->numpoints]);
b->numpoints++;
}
if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
continue;
// generate a split point
p2 = in->p[(i+1)%in->numpoints];
dot = dists[i] / (dists[i]-dists[i+1]);
for (j=0 ; j<3 ; j++)
{ // avoid round off error when possible
if (normal[j] == 1)
mid[j] = dist;
else if (normal[j] == -1)
mid[j] = -dist;
else
mid[j] = p1[j] + dot*(p2[j]-p1[j]);
}
VectorCopy (mid, f->p[f->numpoints]);
f->numpoints++;
VectorCopy (mid, b->p[b->numpoints]);
b->numpoints++;
}
if (f->numpoints > maxpts || b->numpoints > maxpts)
Error ("ClipWinding: points exceeded estimate");
if (f->numpoints > MAX_POINTS_ON_WINDING || b->numpoints > MAX_POINTS_ON_WINDING)
Error ("ClipWinding: MAX_POINTS_ON_WINDING");
}
/*
=============
ChopWindingNoFree
=============
*/
winding_t *ChopWindingNoFree (winding_t *in, vec3_t normal, vec_t dist)
{
vec_t dists[MAX_POINTS_ON_WINDING+4];
int sides[MAX_POINTS_ON_WINDING+4];
int counts[3];
vec_t dot;
int i, j;
vec_t *p1, *p2;
vec3_t mid;
winding_t *f;
int maxpts;
counts[0] = counts[1] = counts[2] = 0;
// determine sides for each point
for (i=0 ; i<in->numpoints ; i++)
{
dot = DotProduct (in->p[i], normal);
dot -= dist;
dists[i] = dot;
if (dot > ON_EPSILON)
sides[i] = SIDE_FRONT;
else if (dot < -ON_EPSILON)
sides[i] = SIDE_BACK;
else
{
sides[i] = SIDE_ON;
}
counts[sides[i]]++;
}
sides[i] = sides[0];
dists[i] = dists[0];
if (!counts[0])
return NULL;
if (!counts[1])
return in;
maxpts = in->numpoints+4; // can't use counts[0]+2 because
// of fp grouping errors
f = AllocWinding (maxpts);
for (i=0 ; i<in->numpoints ; i++)
{
p1 = in->p[i];
if (sides[i] == SIDE_ON)
{
VectorCopy (p1, f->p[f->numpoints]);
f->numpoints++;
continue;
}
if (sides[i] == SIDE_FRONT)
{
VectorCopy (p1, f->p[f->numpoints]);
f->numpoints++;
}
if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
continue;
// generate a split point
p2 = in->p[(i+1)%in->numpoints];
dot = dists[i] / (dists[i]-dists[i+1]);
for (j=0 ; j<3 ; j++)
{ // avoid round off error when possible
if (normal[j] == 1)
mid[j] = dist;
else if (normal[j] == -1)
mid[j] = -dist;
else
mid[j] = p1[j] + dot*(p2[j]-p1[j]);
}
VectorCopy (mid, f->p[f->numpoints]);
f->numpoints++;
}
if (f->numpoints > maxpts)
Error ("ClipWinding: points exceeded estimate");
if (f->numpoints > MAX_POINTS_ON_WINDING)
Error ("ClipWinding: MAX_POINTS_ON_WINDING");
return f;
}
/*
=================
ChopWinding
Returns the fragment of in that is on the front side
of the cliping plane. The original is freed.
=================
*/
winding_t *ChopWinding (winding_t *in, vec3_t normal, vec_t dist)
{
winding_t *f, *b;
ClipWinding (in, normal, dist, &f, &b);
FreeWinding (in);
if (b)
FreeWinding (b);
return f;
}
/*
=================
CheckWinding
=================
*/
void CheckWinding (winding_t *w)
{
int i, j;
vec_t *p1, *p2;
vec_t d, edgedist;
vec3_t dir, edgenormal, facenormal;
vec_t area;
vec_t facedist;
if (w->numpoints < 3)
Error ("CheckWinding: %i points",w->numpoints);
area = WindingArea(w);
if (area < 1)
Error ("CheckWinding: %f area", area);
WindingPlane (w, facenormal, &facedist);
for (i=0 ; i<w->numpoints ; i++)
{
p1 = w->p[i];
for (j=0 ; j<3 ; j++)
if (p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE)
Error ("CheckFace: BUGUS_RANGE: %f",p1[j]);
j = i+1 == w->numpoints ? 0 : i+1;
// check the point is on the face plane
d = DotProduct (p1, facenormal) - facedist;
if (d < -ON_EPSILON || d > ON_EPSILON)
Error ("CheckWinding: point off plane");
// check the edge isn't degenerate
p2 = w->p[j];
VectorSubtract (p2, p1, dir);
if (VectorLength (dir) < ON_EPSILON)
Error ("CheckWinding: degenerate edge");
CrossProduct (facenormal, dir, edgenormal);
VectorNormalize (edgenormal);
edgedist = DotProduct (p1, edgenormal);
edgedist += ON_EPSILON;
// all other points must be on front side
for (j=0 ; j<w->numpoints ; j++)
{
if (j == i)
continue;
d = DotProduct (w->p[j], edgenormal);
if (d > edgedist)
Error ("CheckWinding: non-convex");
}
}
}
/*
============
WindingOnPlaneSide
============
*/
int WindingOnPlaneSide (winding_t *w, vec3_t normal, vec_t dist)
{
qboolean front, back;
int i;
vec_t d;
front = false;
back = false;
for (i=0 ; i<w->numpoints ; i++)
{
d = DotProduct (w->p[i], normal) - dist;
if (d < -ON_EPSILON)
{
if (front)
return SIDE_CROSS;
back = true;
continue;
}
if (d > ON_EPSILON)
{
if (back)
return SIDE_CROSS;
front = true;
continue;
}
}
if (back)
return SIDE_BACK;
if (front)
return SIDE_FRONT;
return SIDE_ON;
}

View File

@ -0,0 +1,36 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
typedef struct
{
int numpoints;
vec3_t p[8]; // variable sized
} winding_t;
#define MAX_POINTS_ON_WINDING 128
winding_t *AllocWinding (int points);
vec_t WindingArea (winding_t *w);
void WindingCenter (winding_t *w, vec3_t center);
void ClipWinding (winding_t *in, vec3_t normal, vec_t dist,
winding_t **front, winding_t **back);
void ClipWindingNoCopy (winding_t *in, vec3_t normal, vec_t dist,
winding_t **front, winding_t **back);
winding_t *ChopWinding (winding_t *in, vec3_t normal, vec_t dist);
winding_t *ChopWindingNoFree (winding_t *in, vec3_t normal, vec_t dist);
winding_t *CopyWinding (winding_t *w);
winding_t *BaseWindingForPlane (vec3_t normal, float dist);
void CheckWinding (winding_t *w);
void WindingPlane (winding_t *w, vec3_t normal, vec_t *dist);
void RemoveColinearPoints (winding_t *w);
int WindingOnPlaneSide (winding_t *w, vec3_t normal, vec_t dist);
void FreeWinding (winding_t *w);
void WindingBounds (winding_t *w, vec3_t mins, vec3_t maxs);

View File

@ -0,0 +1,268 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// scriplib.c
#include "cmdlib.h"
#include "scriplib.h"
/*
=============================================================================
PARSING STUFF
=============================================================================
*/
typedef struct
{
char filename[1024];
char *buffer,*script_p,*end_p;
int line;
} script_t;
#define MAX_INCLUDES 8
script_t scriptstack[MAX_INCLUDES];
script_t *script;
int scriptline;
char token[MAXTOKEN];
qboolean endofscript;
qboolean tokenready; // only true if UnGetToken was just called
/*
==============
AddScriptToStack
==============
*/
void AddScriptToStack (char *filename)
{
int size;
script++;
if (script == &scriptstack[MAX_INCLUDES])
Error ("script file exceeded MAX_INCLUDES");
strcpy (script->filename, ExpandPath (filename) );
size = LoadFile (script->filename, (void **)&script->buffer);
printf ("entering %s\n", script->filename);
script->line = 1;
script->script_p = script->buffer;
script->end_p = script->buffer + size;
}
/*
==============
LoadScriptFile
==============
*/
void LoadScriptFile (char *filename)
{
script = scriptstack;
AddScriptToStack (filename);
endofscript = false;
tokenready = false;
}
/*
==============
ParseFromMemory
==============
*/
void ParseFromMemory (char *buffer, int size)
{
script = scriptstack;
script++;
if (script == &scriptstack[MAX_INCLUDES])
Error ("script file exceeded MAX_INCLUDES");
strcpy (script->filename, "memory buffer" );
script->buffer = buffer;
script->line = 1;
script->script_p = script->buffer;
script->end_p = script->buffer + size;
endofscript = false;
tokenready = false;
}
/*
==============
UnGetToken
Signals that the current token was not used, and should be reported
for the next GetToken. Note that
GetToken (true);
UnGetToken ();
GetToken (false);
could cross a line boundary.
==============
*/
void UnGetToken (void)
{
tokenready = true;
}
qboolean EndOfScript (qboolean crossline)
{
if (!crossline)
Error ("Line %i is incomplete\n",scriptline);
if (!strcmp (script->filename, "memory buffer"))
{
endofscript = true;
return false;
}
free (script->buffer);
if (script == scriptstack+1)
{
endofscript = true;
return false;
}
script--;
scriptline = script->line;
printf ("returning to %s\n", script->filename);
return GetToken (crossline);
}
/*
==============
GetToken
==============
*/
qboolean GetToken (qboolean crossline)
{
char *token_p;
if (tokenready) // is a token allready waiting?
{
tokenready = false;
return true;
}
if (script->script_p >= script->end_p)
return EndOfScript (crossline);
//
// skip space
//
skipspace:
while (*script->script_p <= 32)
{
if (script->script_p >= script->end_p)
return EndOfScript (crossline);
if (*script->script_p++ == '\n')
{
if (!crossline)
Error ("Line %i is incomplete\n",scriptline);
scriptline = script->line++;
}
}
if (script->script_p >= script->end_p)
return EndOfScript (crossline);
if (*script->script_p == ';' || *script->script_p == '#' || // semicolon and # is comment field
(*script->script_p == '/' && *((script->script_p)+1) == '/')) // also make // a comment field
{
if (!crossline)
Error ("Line %i is incomplete\n",scriptline);
while (*script->script_p++ != '\n')
if (script->script_p >= script->end_p)
return EndOfScript (crossline);
goto skipspace;
}
//
// copy token
//
token_p = token;
if (*script->script_p == '"')
{
// quoted token
script->script_p++;
while (*script->script_p != '"')
{
*token_p++ = *script->script_p++;
if (script->script_p == script->end_p)
break;
if (token_p == &token[MAXTOKEN])
Error ("Token too large on line %i\n",scriptline);
}
script->script_p++;
}
else // regular token
while ( *script->script_p > 32 && *script->script_p != ';')
{
*token_p++ = *script->script_p++;
if (script->script_p == script->end_p)
break;
if (token_p == &token[MAXTOKEN])
Error ("Token too large on line %i\n",scriptline);
}
*token_p = 0;
if (!strcmp (token, "$include"))
{
GetToken (false);
AddScriptToStack (token);
return GetToken (crossline);
}
return true;
}
/*
==============
TokenAvailable
Returns true if there is another token on the line
==============
*/
qboolean TokenAvailable (void)
{
char *search_p;
search_p = script->script_p;
if (search_p >= script->end_p)
return false;
while ( *search_p <= 32)
{
if (*search_p == '\n')
return false;
search_p++;
if (search_p == script->end_p)
return false;
}
if (*search_p == ';')
return false;
return true;
}

View File

@ -0,0 +1,33 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// scriplib.h
#ifndef __CMDLIB__
#include "cmdlib.h"
#endif
#define MAXTOKEN 512
extern char token[MAXTOKEN];
extern char *scriptbuffer,*script_p,*scriptend_p;
extern int grabbed;
extern int scriptline;
extern qboolean endofscript;
void LoadScriptFile (char *filename);
void ParseFromMemory (char *buffer, int size);
qboolean GetToken (qboolean crossline);
void UnGetToken (void);
qboolean TokenAvailable (void);

View File

@ -0,0 +1,330 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "cmdlib.h"
#define NO_THREAD_NAMES
#include "threads.h"
#define MAX_THREADS 64
int dispatch;
int workcount;
int oldf;
qboolean pacifier;
qboolean threaded;
/*
=============
GetThreadWork
=============
*/
int GetThreadWork (void)
{
int r;
int f;
ThreadLock ();
if (dispatch == workcount)
{
ThreadUnlock ();
return -1;
}
f = 10*dispatch / workcount;
if (f != oldf)
{
oldf = f;
if (pacifier)
printf ("%i...", f);
}
r = dispatch;
dispatch++;
ThreadUnlock ();
return r;
}
void (*workfunction) (int);
void ThreadWorkerFunction (int threadnum)
{
int work;
while (1)
{
work = GetThreadWork ();
if (work == -1)
break;
workfunction(work);
}
}
void RunThreadsOnIndividual (int workcnt, qboolean showpacifier, void(*func)(int))
{
workfunction = func;
RunThreadsOn (workcnt, showpacifier, ThreadWorkerFunction);
}
/*
===================================================================
WIN32
===================================================================
*/
#ifdef WIN32
#define USED
#include <windows.h>
int numthreads = -1;
CRITICAL_SECTION crit;
static int enter;
void ThreadSetDefault (void)
{
SYSTEM_INFO info;
if (numthreads == -1) // not set manually
{
GetSystemInfo (&info);
numthreads = info.dwNumberOfProcessors;
if (numthreads < 1 || numthreads > 32)
numthreads = 1;
}
qprintf ("%i threads\n", numthreads);
}
void ThreadLock (void)
{
if (!threaded)
return;
EnterCriticalSection (&crit);
if (enter)
Error ("Recursive ThreadLock\n");
enter = 1;
}
void ThreadUnlock (void)
{
if (!threaded)
return;
if (!enter)
Error ("ThreadUnlock without lock\n");
enter = 0;
LeaveCriticalSection (&crit);
}
/*
=============
RunThreadsOn
=============
*/
void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int))
{
int threadid[MAX_THREADS];
HANDLE threadhandle[MAX_THREADS];
int i;
int start, end;
start = I_FloatTime ();
dispatch = 0;
workcount = workcnt;
oldf = -1;
pacifier = showpacifier;
threaded = true;
//
// run threads in parallel
//
InitializeCriticalSection (&crit);
for (i=0 ; i<numthreads ; i++)
{
threadhandle[i] = CreateThread(
NULL, // LPSECURITY_ATTRIBUTES lpsa,
0, // DWORD cbStack,
(LPTHREAD_START_ROUTINE)func, // LPTHREAD_START_ROUTINE lpStartAddr,
(LPVOID)i, // LPVOID lpvThreadParm,
0, // DWORD fdwCreate,
&threadid[i]);
}
for (i=0 ; i<numthreads ; i++)
WaitForSingleObject (threadhandle[i], INFINITE);
DeleteCriticalSection (&crit);
threaded = false;
end = I_FloatTime ();
if (pacifier)
printf (" (%i)\n", end-start);
}
#endif
/*
===================================================================
OSF1
===================================================================
*/
#ifdef __osf__
#define USED
int numthreads = 4;
void ThreadSetDefault (void)
{
numthreads = 4;
}
#include <pthread.h>
pthread_mutex_t *my_mutex;
void ThreadLock (void)
{
if (my_mutex)
pthread_mutex_lock (my_mutex);
}
void ThreadUnlock (void)
{
if (my_mutex)
pthread_mutex_unlock (my_mutex);
}
/*
=============
RunThreadsOn
=============
*/
void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int))
{
int i;
pthread_t work_threads[MAX_THREADS];
pthread_addr_t status;
pthread_attr_t attrib;
pthread_mutexattr_t mattrib;
int start, end;
start = I_FloatTime ();
dispatch = 0;
workcount = workcnt;
oldf = -1;
pacifier = showpacifier;
threaded = true;
if (pacifier)
setbuf (stdout, NULL);
if (!my_mutex)
{
my_mutex = malloc (sizeof(*my_mutex));
if (pthread_mutexattr_create (&mattrib) == -1)
Error ("pthread_mutex_attr_create failed");
if (pthread_mutexattr_setkind_np (&mattrib, MUTEX_FAST_NP) == -1)
Error ("pthread_mutexattr_setkind_np failed");
if (pthread_mutex_init (my_mutex, mattrib) == -1)
Error ("pthread_mutex_init failed");
}
if (pthread_attr_create (&attrib) == -1)
Error ("pthread_attr_create failed");
if (pthread_attr_setstacksize (&attrib, 0x100000) == -1)
Error ("pthread_attr_setstacksize failed");
for (i=0 ; i<numthreads ; i++)
{
if (pthread_create(&work_threads[i], attrib
, (pthread_startroutine_t)func, (pthread_addr_t)i) == -1)
Error ("pthread_create failed");
}
for (i=0 ; i<numthreads ; i++)
{
if (pthread_join (work_threads[i], &status) == -1)
Error ("pthread_join failed");
}
threaded = false;
end = I_FloatTime ();
if (pacifier)
printf (" (%i)\n", end-start);
}
#endif
/*
=======================================================================
SINGLE THREAD
=======================================================================
*/
#ifndef USED
int numthreads = 1;
void ThreadSetDefault (void)
{
numthreads = 1;
}
void ThreadLock (void)
{
}
void ThreadUnlock (void)
{
}
/*
=============
RunThreadsOn
=============
*/
void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int))
{
int i;
int start, end;
dispatch = 0;
workcount = workcnt;
oldf = -1;
pacifier = showpacifier;
start = I_FloatTime ();
#ifdef NeXT
if (pacifier)
setbuf (stdout, NULL);
#endif
func(0);
end = I_FloatTime ();
if (pacifier)
printf (" (%i)\n", end-start);
}
#endif

View File

@ -0,0 +1,24 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
extern int numthreads;
void ThreadSetDefault (void);
int GetThreadWork (void);
void RunThreadsOnIndividual (int workcnt, qboolean showpacifier, void(*func)(int));
void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int));
void ThreadLock (void);
void ThreadUnlock (void);
#ifndef NO_THREAD_NAMES
#define RunThreadsOn(n,p,f) { if (p) printf("%-20s ", #f ":"); RunThreadsOn(n,p,f); }
#define RunThreadsOnIndividual(n,p,f) { if (p) printf("%-20s ", #f ":"); RunThreadsOnIndividual(n,p,f); }
#endif

180
hlsdk/utils/common/trilib.c Normal file
View File

@ -0,0 +1,180 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
//
// trilib.c: library for loading triangles from an Alias triangle file
//
#include <stdio.h>
#include "cmdlib.h"
#include "mathlib.h"
#include "trilib.h"
// on disk representation of a face
#define FLOAT_START 99999.0
#define FLOAT_END -FLOAT_START
#define MAGIC 123322
//#define NOISY 1
typedef struct {
float v[3];
} vector;
typedef struct
{
vector n; /* normal */
vector p; /* point */
vector c; /* color */
float u; /* u */
float v; /* v */
} aliaspoint_t;
typedef struct {
aliaspoint_t pt[3];
} tf_triangle;
void ByteSwapTri (tf_triangle *tri)
{
int i;
for (i=0 ; i<sizeof(tf_triangle)/4 ; i++)
{
((int *)tri)[i] = BigLong (((int *)tri)[i]);
}
}
void LoadTriangleList (char *filename, triangle_t **pptri, int *numtriangles)
{
FILE *input;
float start;
char name[256], tex[256];
int i, count, magic;
tf_triangle tri;
triangle_t *ptri;
int iLevel;
int exitpattern;
float t;
t = -FLOAT_START;
*((unsigned char *)&exitpattern + 0) = *((unsigned char *)&t + 3);
*((unsigned char *)&exitpattern + 1) = *((unsigned char *)&t + 2);
*((unsigned char *)&exitpattern + 2) = *((unsigned char *)&t + 1);
*((unsigned char *)&exitpattern + 3) = *((unsigned char *)&t + 0);
if ((input = fopen(filename, "rb")) == 0) {
fprintf(stderr,"reader: could not open file '%s'\n", filename);
exit(0);
}
iLevel = 0;
fread(&magic, sizeof(int), 1, input);
if (BigLong(magic) != MAGIC) {
fprintf(stderr,"File is not a Alias object separated triangle file, magic number is wrong.\n");
exit(0);
}
ptri = malloc (MAXTRIANGLES * sizeof(triangle_t));
*pptri = ptri;
while (feof(input) == 0) {
fread(&start, sizeof(float), 1, input);
*(int *)&start = BigLong(*(int *)&start);
if (*(int *)&start != exitpattern)
{
if (start == FLOAT_START) {
/* Start of an object or group of objects. */
i = -1;
do {
/* There are probably better ways to read a string from */
/* a file, but this does allow you to do error checking */
/* (which I'm not doing) on a per character basis. */
++i;
fread( &(name[i]), sizeof( char ), 1, input);
} while( name[i] != '\0' );
// indent();
// fprintf(stdout,"OBJECT START: %s\n",name);
fread( &count, sizeof(int), 1, input);
count = BigLong(count);
++iLevel;
if (count != 0) {
// indent();
// fprintf(stdout,"NUMBER OF TRIANGLES: %d\n",count);
i = -1;
do {
++i;
fread( &(tex[i]), sizeof( char ), 1, input);
} while( tex[i] != '\0' );
// indent();
// fprintf(stdout," Object texture name: '%s'\n",tex);
}
/* Else (count == 0) this is the start of a group, and */
/* no texture name is present. */
}
else if (start == FLOAT_END) {
/* End of an object or group. Yes, the name should be */
/* obvious from context, but it is in here just to be */
/* safe and to provide a little extra information for */
/* those who do not wish to write a recursive reader. */
/* Mia culpa. */
--iLevel;
i = -1;
do {
++i;
fread( &(name[i]), sizeof( char ), 1, input);
} while( name[i] != '\0' );
// indent();
// fprintf(stdout,"OBJECT END: %s\n",name);
continue;
}
}
//
// read the triangles
//
for (i = 0; i < count; ++i) {
int j;
fread( &tri, sizeof(tf_triangle), 1, input );
ByteSwapTri (&tri);
for (j=0 ; j<3 ; j++)
{
int k;
for (k=0 ; k<3 ; k++)
{
ptri->verts[j][k] = tri.pt[j].p.v[k];
}
}
ptri++;
if ((ptri - *pptri) >= MAXTRIANGLES)
Error ("Error: too many triangles; increase MAXTRIANGLES\n");
}
}
*numtriangles = ptri - *pptri;
fclose (input);
}

View File

@ -0,0 +1,21 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
//
// trilib.h: header file for loading triangles from an Alias triangle file
//
#define MAXTRIANGLES 2048
typedef struct {
vec3_t verts[3];
} triangle_t;
void LoadTriangleList (char *filename, triangle_t **pptri, int *numtriangles);

339
hlsdk/utils/common/wadlib.c Normal file
View File

@ -0,0 +1,339 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// wad2lib.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
//#include <sys/file.h>
#include <stdarg.h>
#ifdef NeXT
#include <libc.h>
#endif
#include "cmdlib.h"
#include "wadlib.h"
/*
============================================================================
WAD READING
============================================================================
*/
lumpinfo_t *lumpinfo; // location of each lump on disk
int numlumps;
wadinfo_t header;
FILE *wadhandle;
/*
====================
W_OpenWad
====================
*/
void W_OpenWad (char *filename)
{
lumpinfo_t *lump_p;
unsigned int i;
int length;
//
// open the file and add to directory
//
wadhandle = SafeOpenRead (filename);
SafeRead (wadhandle, &header, sizeof(header));
if (strncmp(header.identification,"WAD2",4) &&
strncmp(header.identification, "WAD3", 4))
Error ("Wad file %s doesn't have WAD2/WAD3 id\n",filename);
header.numlumps = LittleLong(header.numlumps);
header.infotableofs = LittleLong(header.infotableofs);
numlumps = header.numlumps;
length = numlumps*sizeof(lumpinfo_t);
lumpinfo = malloc (length);
lump_p = lumpinfo;
fseek (wadhandle, header.infotableofs, SEEK_SET);
SafeRead (wadhandle, lumpinfo, length);
//
// Fill in lumpinfo
//
for (i = 0 ; i < (unsigned int)numlumps ; i++,lump_p++)
{
lump_p->filepos = LittleLong(lump_p->filepos);
lump_p->size = LittleLong(lump_p->size);
}
}
void CleanupName (char *in, char *out)
{
int i;
for (i=0 ; i<sizeof( ((lumpinfo_t *)0)->name ) ; i++ )
{
if (!in[i])
break;
out[i] = toupper(in[i]);
}
for ( ; i<sizeof( ((lumpinfo_t *)0)->name ); i++ )
out[i] = 0;
}
/*
====================
W_CheckNumForName
Returns -1 if name not found
====================
*/
int W_CheckNumForName (char *name)
{
char cleanname[16];
int v1,v2, v3, v4;
int i;
lumpinfo_t *lump_p;
CleanupName (name, cleanname);
// make the name into four integers for easy compares
v1 = *(int *)cleanname;
v2 = *(int *)&cleanname[4];
v3 = *(int *)&cleanname[8];
v4 = *(int *)&cleanname[12];
// find it
lump_p = lumpinfo;
for (i=0 ; i<numlumps ; i++, lump_p++)
{
if ( *(int *)lump_p->name == v1
&& *(int *)&lump_p->name[4] == v2
&& *(int *)&lump_p->name[8] == v3
&& *(int *)&lump_p->name[12] == v4)
return i;
}
return -1;
}
/*
====================
W_GetNumForName
Calls W_CheckNumForName, but bombs out if not found
====================
*/
int W_GetNumForName (char *name)
{
int i;
i = W_CheckNumForName (name);
if (i != -1)
return i;
Error ("W_GetNumForName: %s not found!",name);
return -1;
}
/*
====================
W_LumpLength
Returns the buffer size needed to load the given lump
====================
*/
int W_LumpLength (int lump)
{
if (lump >= numlumps)
Error ("W_LumpLength: %i >= numlumps",lump);
return lumpinfo[lump].size;
}
/*
====================
W_ReadLumpNum
Loads the lump into the given buffer, which must be >= W_LumpLength()
====================
*/
void W_ReadLumpNum (int lump, void *dest)
{
lumpinfo_t *l;
if (lump >= numlumps)
Error ("W_ReadLump: %i >= numlumps",lump);
l = lumpinfo+lump;
fseek (wadhandle, l->filepos, SEEK_SET);
SafeRead (wadhandle, dest, l->size);
}
/*
====================
W_LoadLumpNum
====================
*/
void *W_LoadLumpNum (int lump)
{
void *buf;
if (lump >= numlumps)
Error ("W_CacheLumpNum: %i >= numlumps",lump);
buf = malloc (W_LumpLength (lump));
W_ReadLumpNum (lump, buf);
return buf;
}
/*
====================
W_LoadLumpName
====================
*/
void *W_LoadLumpName (char *name)
{
return W_LoadLumpNum (W_GetNumForName(name));
}
/*
===============================================================================
WAD CREATION
===============================================================================
*/
FILE *outwad;
lumpinfo_t outinfo[4096];
int outlumps;
short (*wadshort) (short l);
int (*wadlong) (int l);
/*
===============
NewWad
===============
*/
void NewWad (char *pathname, qboolean bigendien)
{
outwad = SafeOpenWrite (pathname);
fseek (outwad, sizeof(wadinfo_t), SEEK_SET);
memset (outinfo, 0, sizeof(outinfo));
if (bigendien)
{
wadshort = BigShort;
wadlong = BigLong;
}
else
{
wadshort = LittleShort;
wadlong = LittleLong;
}
outlumps = 0;
}
/*
===============
AddLump
===============
*/
void AddLump (char *name, void *buffer, int length, int type, int compress)
{
lumpinfo_t *info;
int ofs;
info = &outinfo[outlumps];
outlumps++;
memset (info,0,sizeof(info));
strcpy (info->name, name);
strupr (info->name);
ofs = ftell(outwad);
info->filepos = wadlong(ofs);
info->size = info->disksize = wadlong(length);
info->type = type;
info->compression = compress;
// FIXME: do compression
SafeWrite (outwad, buffer, length);
}
/*
===============
WriteWad
===============
*/
void WriteWad (int wad3)
{
wadinfo_t header;
int ofs;
// write the lumpingo
ofs = ftell(outwad);
SafeWrite (outwad, outinfo, outlumps*sizeof(lumpinfo_t) );
// write the header
// a program will be able to tell the ednieness of a wad by the id
header.identification[0] = 'W';
header.identification[1] = 'A';
header.identification[2] = 'D';
header.identification[3] = wad3 ? '3' : '2';
header.numlumps = wadlong(outlumps);
header.infotableofs = wadlong(ofs);
fseek (outwad, 0, SEEK_SET);
SafeWrite (outwad, &header, sizeof(header));
fclose (outwad);
}

View File

@ -0,0 +1,63 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// wadlib.h
//
// wad reading
//
#define CMP_NONE 0
#define CMP_LZSS 1
#define TYP_NONE 0
#define TYP_LABEL 1
#define TYP_LUMPY 64 // 64 + grab command number
typedef struct
{
char identification[4]; // should be WAD2 or 2DAW
int numlumps;
int infotableofs;
} wadinfo_t;
typedef struct
{
int filepos;
int disksize;
int size; // uncompressed
char type;
char compression;
char pad1, pad2;
char name[16]; // must be null terminated
} lumpinfo_t;
extern lumpinfo_t *lumpinfo; // location of each lump on disk
extern int numlumps;
extern wadinfo_t header;
void W_OpenWad (char *filename);
int W_CheckNumForName (char *name);
int W_GetNumForName (char *name);
int W_LumpLength (int lump);
void W_ReadLumpNum (int lump, void *dest);
void *W_LoadLumpNum (int lump);
void *W_LoadLumpName (char *name);
void CleanupName (char *in, char *out);
//
// wad creation
//
void NewWad (char *pathname, qboolean bigendien);
void AddLump (char *name, void *buffer, int length, int type, int compress);
void WriteWad (int wad3);

228
hlsdk/utils/light/light.c Normal file
View File

@ -0,0 +1,228 @@
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// lighting.c
#include "light.h"
/*
NOTES
-----
*/
float scaledist = 1.0;
float scalecos = 0.5;
float rangescale = 0.5;
byte *filebase, *file_p, *file_end;
dmodel_t *bspmodel;
vec3_t bsp_origin;
qboolean extrasamples;
qboolean hicolor;
qboolean clamp192 = true;
float minlights[MAX_MAP_FACES];
lightentity_t lightentities[MAX_MAP_ENTITIES];
int numlightentities;
/*
==================
LoadEntities
==================
*/
void LoadEntities (void)
{
char *s, *s2;
entity_t *e;
lightentity_t *le;
int i, j;
ParseEntities ();
// go through all the entities
for (i=1 ; i<num_entities ; i++)
{
e = &entities[i];
s = ValueForKey (e, "classname");
if (strncmp (s, "light", 5))
continue;
le = &lightentities[numlightentities];
numlightentities++;
strcpy (le->classname, s);
s = ValueForKey( e, "_light" );
if( s )
{
double v1, v2, v3;
v1 = v2 = v3 = 0;
if( sscanf( s, "%lf %lf %lf", &v1, &v2, &v3) != 3 )
v2 = v3 = v1;
le->light[0] = v1;
le->light[1] = v2;
le->light[2] = v3;
}
else
{
le->light[0] = DEFAULTLIGHTLEVEL;
le->light[1] = DEFAULTLIGHTLEVEL;
le->light[2] = DEFAULTLIGHTLEVEL;
}
le->style = FloatForKey (e, "style");
le->angle = FloatForKey (e, "angle");
GetVectorForKey (e, "origin", le->origin);
s = ValueForKey (e, "target");
if (!s[0])
continue;
// find matching targetname
for (j=1 ; j<num_entities ; j++)
{
s2 = ValueForKey (&entities[j], "targetname");
if (!strcmp (s, s2))
{
le->targetent = true;
GetVectorForKey (&entities[j], "origin", le->targetorigin);
break;
}
}
if (j == num_entities)
printf ("WARNING: entity %i has unmatched target %s\n", i, s);
}
qprintf ("%d lightentities\n", numlightentities);
}
byte *GetFileSpace (int size)
{
byte *buf;
ThreadLock();
file_p = (byte *)(((long)file_p + 3)&~3);
buf = file_p;
file_p += size;
ThreadUnlock();
if (file_p > file_end)
Error ("GetFileSpace: overrun");
return buf;
}
/*
=============
LightWorld
=============
*/
void LightWorld (void)
{
filebase = file_p = dlightdata;
file_end = filebase + MAX_MAP_LIGHTING;
RunThreadsOnIndividual (numfaces, true, LightFace);
lightdatasize = file_p - filebase;
printf ("lightdatasize: %i\n", lightdatasize);
}
/*
========
main
light modelfile
========
*/
int main (int argc, char **argv)
{
int i;
double start, end;
char source[1024];
printf("Light.exe Version 1.3 Id Software and valve (%s)\n", __DATE__ );
printf ("----- LightFaces ----\n");
// default to 24-bit light info
hicolor = true;
for (i=1 ; i<argc ; i++)
{
if (!strcmp(argv[i],"-threads"))
{
numthreads = atoi (argv[i+1]);
i++;
}
else if (!strcmp(argv[i],"-extra"))
{
extrasamples = true;
printf ("extra sampling enabled\n");
}
else if (!strcmp(argv[i],"-dist"))
{
scaledist = atof (argv[i+1]);
i++;
}
else if (!strcmp(argv[i],"-range"))
{
rangescale = atof (argv[i+1]);
i++;
}
else if (!strcmp(argv[i],"-lowcolor"))
{
hicolor = false;
}
else if (!strcmp( argv[ i ], "-noclamp" ) )
{
clamp192 = false;
}
else if (argv[i][0] == '-')
Error ("Unknown option \"%s\"", argv[i]);
else
break;
}
if (i != argc - 1)
Error ("usage: light [-threads num] [-extra] [-lowcolor] bspfile");
ThreadSetDefault ();
start = I_FloatTime ();
strcpy (source, argv[i]);
StripExtension (source);
DefaultExtension (source, ".bsp");
LoadBSPFile (source);
LoadEntities ();
MakeTnodes (&dmodels[0]);
LightWorld ();
WriteBSPFile (source);
end = I_FloatTime ();
printf ("%5.1f seconds elapsed\n", end-start);
return 0;
}

61
hlsdk/utils/light/light.h Normal file
View File

@ -0,0 +1,61 @@
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "cmdlib.h"
#include "mathlib.h"
#include "bspfile.h"
#include "threads.h"
#define DEFAULTLIGHTLEVEL 300
typedef struct entity_s
{
char classname[64];
vec3_t origin;
float angle;
vec3_t light;
int style;
qboolean targetent;
vec3_t targetorigin;
} lightentity_t;
extern lightentity_t lightentities[MAX_MAP_ENTITIES];
extern int numlightentities;
#undef ON_EPSILON
#define ON_EPSILON 0.1
#define MAXLIGHTS 1024
void LoadNodes (char *file);
qboolean TestLine (vec3_t start, vec3_t stop);
void LightFace (int surfnum);
void LightLeaf (dleaf_t *leaf);
void MakeTnodes (dmodel_t *bm);
extern float scaledist;
extern float scalecos;
extern float rangescale;
extern int c_culldistplane, c_proper;
byte *GetFileSpace (int size);
extern byte *filebase;
extern vec3_t bsp_origin;
extern vec3_t bsp_xvector;
extern vec3_t bsp_yvector;
void TransformSample (vec3_t in, vec3_t out);
void RotateSample (vec3_t in, vec3_t out);
extern qboolean extrasamples;
extern float minlights[MAX_MAP_FACES];

688
hlsdk/utils/light/ltface.c Normal file
View File

@ -0,0 +1,688 @@
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "light.h"
extern qboolean hicolor;
extern qboolean clamp192;
/*
============
CastRay
Returns the distance between the points, or -1 if blocked
=============
*/
vec_t CastRay (vec3_t p1, vec3_t p2)
{
int i;
vec_t t;
qboolean trace;
trace = TestLine (p1, p2);
if (!trace)
return -1; // ray was blocked
t = 0;
for (i=0 ; i< 3 ; i++)
t += (p2[i]-p1[i]) * (p2[i]-p1[i]);
if (t == 0)
t = 1; // don't blow up...
return sqrt(t);
}
/*
===============================================================================
SAMPLE POINT DETERMINATION
void SetupBlock (dface_t *f) Returns with surfpt[] set
This is a little tricky because the lightmap covers more area than the face.
If done in the straightforward fashion, some of the
sample points will be inside walls or on the other side of walls, causing
false shadows and light bleeds.
To solve this, I only consider a sample point valid if a line can be drawn
between it and the exact midpoint of the face. If invalid, it is adjusted
towards the center until it is valid.
(this doesn't completely work)
===============================================================================
*/
#define SINGLEMAP (18*18*4)
typedef struct
{
vec3_t lightmaps[MAXLIGHTMAPS][SINGLEMAP];
int numlightstyles;
vec_t *light;
vec_t facedist;
vec3_t facenormal;
int numsurfpt;
vec3_t surfpt[SINGLEMAP];
vec3_t texorg;
vec3_t worldtotex[2]; // s = (world - texorg) . worldtotex[0]
vec3_t textoworld[2]; // world = texorg + s * textoworld[0]
vec_t exactmins[2], exactmaxs[2];
int texmins[2], texsize[2];
int lightstyles[256];
int surfnum;
dface_t *face;
} lightinfo_t;
/*
================
CalcFaceVectors
Fills in texorg, worldtotex. and textoworld
================
*/
void CalcFaceVectors (lightinfo_t *l)
{
texinfo_t *tex;
int i, j;
vec3_t texnormal;
float distscale;
vec_t dist, len;
tex = &texinfo[l->face->texinfo];
// convert from float to vec_t
for (i=0 ; i<2 ; i++)
for (j=0 ; j<3 ; j++)
l->worldtotex[i][j] = tex->vecs[i][j];
// calculate a normal to the texture axis. points can be moved along this
// without changing their S/T
texnormal[0] = tex->vecs[1][1]*tex->vecs[0][2]
- tex->vecs[1][2]*tex->vecs[0][1];
texnormal[1] = tex->vecs[1][2]*tex->vecs[0][0]
- tex->vecs[1][0]*tex->vecs[0][2];
texnormal[2] = tex->vecs[1][0]*tex->vecs[0][1]
- tex->vecs[1][1]*tex->vecs[0][0];
VectorNormalize (texnormal);
// flip it towards plane normal
distscale = DotProduct (texnormal, l->facenormal);
if (!distscale)
Error ("Texture axis perpendicular to face");
if (distscale < 0)
{
distscale = -distscale;
VectorSubtract (vec3_origin, texnormal, texnormal);
}
// distscale is the ratio of the distance along the texture normal to
// the distance along the plane normal
distscale = 1/distscale;
for (i=0 ; i<2 ; i++)
{
len = VectorLength (l->worldtotex[i]);
dist = DotProduct (l->worldtotex[i], l->facenormal);
dist *= distscale;
VectorMA (l->worldtotex[i], -dist, texnormal, l->textoworld[i]);
VectorScale (l->textoworld[i], (1/len)*(1/len), l->textoworld[i]);
}
// calculate texorg on the texture plane
for (i=0 ; i<3 ; i++)
l->texorg[i] = -tex->vecs[0][3]* l->textoworld[0][i] - tex->vecs[1][3] * l->textoworld[1][i];
// project back to the face plane
dist = DotProduct (l->texorg, l->facenormal) - l->facedist - 1;
dist *= distscale;
VectorMA (l->texorg, -dist, texnormal, l->texorg);
}
/*
================
CalcFaceExtents
Fills in s->texmins[] and s->texsize[]
also sets exactmins[] and exactmaxs[]
================
*/
void CalcFaceExtents (lightinfo_t *l)
{
dface_t *s;
vec_t mins[2], maxs[2], val;
int i,j, e;
dvertex_t *v;
texinfo_t *tex;
s = l->face;
mins[0] = mins[1] = 999999;
maxs[0] = maxs[1] = -99999;
tex = &texinfo[s->texinfo];
for (i=0 ; i<s->numedges ; i++)
{
e = dsurfedges[s->firstedge+i];
if (e >= 0)
v = dvertexes + dedges[e].v[0];
else
v = dvertexes + dedges[-e].v[1];
for (j=0 ; j<2 ; j++)
{
val = v->point[0] * tex->vecs[j][0] +
v->point[1] * tex->vecs[j][1] +
v->point[2] * tex->vecs[j][2] +
tex->vecs[j][3];
if (val < mins[j])
mins[j] = val;
if (val > maxs[j])
maxs[j] = val;
}
}
for (i=0 ; i<2 ; i++)
{
l->exactmins[i] = mins[i];
l->exactmaxs[i] = maxs[i];
mins[i] = floor(mins[i]/16);
maxs[i] = ceil(maxs[i]/16);
l->texmins[i] = mins[i];
l->texsize[i] = maxs[i] - mins[i];
if (l->texsize[i] > 17)
Error ("Bad surface extents");
}
}
/*
=================
CalcPoints
For each texture aligned grid point, back project onto the plane
to get the world xyz value of the sample point
=================
*/
int c_bad;
void CalcPoints (lightinfo_t *l)
{
int i;
int s, t, j;
int w, h, step;
vec_t starts, startt, us, ut;
vec_t *surf;
vec_t mids, midt;
vec3_t facemid, move;
//
// fill in surforg
// the points are biased towards the center of the surface
// to help avoid edge cases just inside walls
//
surf = l->surfpt[0];
mids = (l->exactmaxs[0] + l->exactmins[0])/2;
midt = (l->exactmaxs[1] + l->exactmins[1])/2;
for (j=0 ; j<3 ; j++)
facemid[j] = l->texorg[j] + l->textoworld[0][j]*mids + l->textoworld[1][j]*midt;
if (extrasamples)
{ // extra filtering
h = (l->texsize[1]+1)*2;
w = (l->texsize[0]+1)*2;
starts = (l->texmins[0]-0.5)*16;
startt = (l->texmins[1]-0.5)*16;
step = 8;
}
else
{
h = l->texsize[1]+1;
w = l->texsize[0]+1;
starts = l->texmins[0]*16;
startt = l->texmins[1]*16;
step = 16;
}
l->numsurfpt = w * h;
for (t=0 ; t<h ; t++)
{
for (s=0 ; s<w ; s++, surf+=3)
{
us = starts + s*step;
ut = startt + t*step;
// if a line can be traced from surf to facemid, the point is good
for (i=0 ; i<6 ; i++)
{
// calculate texture point
for (j=0 ; j<3 ; j++)
surf[j] = l->texorg[j] + l->textoworld[0][j]*us
+ l->textoworld[1][j]*ut;
if (CastRay (facemid, surf) != -1)
break; // got it
if (i & 1)
{
if (us > mids)
{
us -= 8;
if (us < mids)
us = mids;
}
else
{
us += 8;
if (us > mids)
us = mids;
}
}
else
{
if (ut > midt)
{
ut -= 8;
if (ut < midt)
ut = midt;
}
else
{
ut += 8;
if (ut > midt)
ut = midt;
}
}
// move surf 8 pixels towards the center
VectorSubtract (facemid, surf, move);
VectorNormalize (move);
VectorMA (surf, 8, move, surf);
}
if (i == 2)
c_bad++;
}
}
}
/*
===============================================================================
FACE LIGHTING
===============================================================================
*/
int c_culldistplane, c_proper;
/*
================
SingleLightFace
================
*/
void SingleLightFace (lightentity_t *light, lightinfo_t *l)
{
vec_t dist;
vec3_t incoming;
vec_t angle;
vec_t add;
vec_t *surf;
qboolean hit;
int mapnum;
int size;
int c, i;
vec3_t rel;
vec3_t spotvec;
vec_t falloff;
vec3_t *lightsamp;
float intensity;
VectorSubtract (light->origin, bsp_origin, rel);
dist = scaledist * (DotProduct (rel, l->facenormal) - l->facedist);
// don't bother with lights behind the surface
if (dist <= 0)
return;
// don't bother with light too far away
intensity = ( light->light[ 0 ] + light->light[ 1 ] + light->light[ 2 ] ) / 3.0;
if( dist > intensity )
{
c_culldistplane++;
return;
}
if (light->targetent)
{
VectorSubtract (light->targetorigin, light->origin, spotvec);
VectorNormalize (spotvec);
if (!light->angle)
falloff = -cos(20*Q_PI/180);
else
falloff = -cos(light->angle/2*Q_PI/180);
}
else
falloff = 0; // shut up compiler warnings
mapnum = 0;
for (mapnum=0 ; mapnum<l->numlightstyles ; mapnum++)
if (l->lightstyles[mapnum] == light->style)
break;
lightsamp = l->lightmaps[mapnum];
if (mapnum == l->numlightstyles)
{ // init a new light map
if (mapnum == MAXLIGHTMAPS)
{
printf ("WARNING: Too many light styles on a face\n");
return;
}
size = (l->texsize[1]+1)*(l->texsize[0]+1);
for (i=0 ; i<size ; i++)
{
lightsamp[i][0] = 0;
lightsamp[i][1] = 0;
lightsamp[i][2] = 0;
}
}
//
// check it for real
//
hit = false;
c_proper++;
surf = l->surfpt[0];
for (c=0 ; c<l->numsurfpt ; c++, surf+=3)
{
dist = CastRay(light->origin, surf)*scaledist;
if (dist < 0)
continue; // light doesn't reach
VectorSubtract (light->origin, surf, incoming);
VectorNormalize (incoming);
angle = DotProduct (incoming, l->facenormal);
if (light->targetent)
{ // spotlight cutoff
if (DotProduct (spotvec, incoming) > falloff)
continue;
}
angle = (1.0-scalecos) + scalecos*angle;
for( i=0; i<3; i++ )
{
add = light->light[i] - dist;
add *= angle;
if (add < 0)
continue;
lightsamp[c][i] += add;
}
// check intensity
intensity = ( lightsamp[ c ][ 0 ] + lightsamp[ c ][ 1 ] + lightsamp[ c ][ 2 ] ) / 3.0;
if( intensity > 1 ) // ignore real tiny lights
hit = true;
}
if (mapnum == l->numlightstyles && hit)
{
l->lightstyles[mapnum] = light->style;
l->numlightstyles++; // the style has some real data now
}
}
/*
============
FixMinlight
============
*/
void FixMinlight (lightinfo_t *l)
{
int i, j;
float minlight;
minlight = minlights[l->surfnum];
// if minlight is set, there must be a style 0 light map
if (!minlight)
return;
for (i=0 ; i< l->numlightstyles ; i++)
{
if (l->lightstyles[i] == 0)
break;
}
if (i == l->numlightstyles)
{
if (l->numlightstyles == MAXLIGHTMAPS)
return; // oh well..
for (j=0 ; j<l->numsurfpt ; j++)
{
l->lightmaps[i][j][0] = minlight;
l->lightmaps[i][j][1] = minlight;
l->lightmaps[i][j][2] = minlight;
}
l->lightstyles[i] = 0;
l->numlightstyles++;
}
else
{
for (j=0 ; j<l->numsurfpt ; j++)
{
float intensity = ( l->lightmaps[i][j][0] + l->lightmaps[i][j][1] + l->lightmaps[i][j][2] ) / 3.0;
if ( intensity < minlight )
{
l->lightmaps[i][j][0] = minlight;
l->lightmaps[i][j][1] = minlight;
l->lightmaps[i][j][2] = minlight;
}
}
}
}
/*
============
LightFace
============
*/
void LightFace (int surfnum)
{
dface_t *f;
lightinfo_t l;
int s, t;
int i,j,c;
vec3_t total;
int size;
int lightmapwidth, lightmapsize;
byte *out;
vec3_t *light;
int w, h;
int clamp = 192;
float clampfactor = 0.75;
if ( !clamp192 )
{
clamp = 255;
clampfactor = 1.0;
}
f = dfaces + surfnum;
//
// some surfaces don't need lightmaps
//
f->lightofs = -1;
for (j=0 ; j<MAXLIGHTMAPS ; j++)
f->styles[j] = 255;
if ( texinfo[f->texinfo].flags & TEX_SPECIAL)
{ // non-lit texture
return;
}
memset (&l, 0, sizeof(l));
l.surfnum = surfnum;
l.face = f;
//
// rotate plane
//
VectorCopy (dplanes[f->planenum].normal, l.facenormal);
l.facedist = dplanes[f->planenum].dist;
if (f->side)
{
VectorSubtract (vec3_origin, l.facenormal, l.facenormal);
l.facedist = -l.facedist;
}
CalcFaceVectors (&l);
CalcFaceExtents (&l);
CalcPoints (&l);
lightmapwidth = l.texsize[0]+1;
size = lightmapwidth*(l.texsize[1]+1);
if (size > SINGLEMAP)
Error ("Bad lightmap size");
for (i=0 ; i<MAXLIGHTMAPS ; i++)
l.lightstyles[i] = 255;
//
// cast all lights
//
l.numlightstyles = 0;
for (i=0 ; i<numlightentities ; i++)
SingleLightFace (&lightentities[i], &l);
FixMinlight (&l);
if (!l.numlightstyles)
{ // no light hitting it
return;
}
//
// save out the values
//
for (i=0 ; i <MAXLIGHTMAPS ; i++)
f->styles[i] = l.lightstyles[i];
if( hicolor )
lightmapsize = size*l.numlightstyles*3;
else
lightmapsize = size * l.numlightstyles;
out = GetFileSpace (lightmapsize);
f->lightofs = out - filebase;
// extra filtering
h = (l.texsize[1]+1)*2;
w = (l.texsize[0]+1)*2;
for (i=0 ; i< l.numlightstyles ; i++)
{
if (l.lightstyles[i] == 0xff)
Error ("Wrote empty lightmap");
light = l.lightmaps[i];
c = 0;
for (t=0 ; t<=l.texsize[1] ; t++)
{
for (s=0 ; s<=l.texsize[0] ; s++, c++)
{
if (extrasamples)
{
#ifdef OLD_CODE
// filtered sample
VectorCopy( light[t*2*w+s*2], total );
VectorAdd( total, light[t*2*w+s*2+1], total );
VectorAdd( total, light[(t*2+1)*w+s*2], total );
VectorAdd( total, light[(t*2+1)*w+s*2+1], total );
VectorScale( total, 0.25, total );
#else
int u, v;
float weight[3][3] =
{
{ 5, 9, 5 },
{ 9, 16, 9 },
{ 5, 9, 5 },
};
float divisor = 0.0;
VectorFill(total,0);
for ( u = 0; u < 3; u++ )
{
for ( v = 0; v < 3; v++ )
{
if ( s+u-2>=0 && t+v-1>=0 && s+u-1 <= w && t+v-1 <= h)
{
vec3_t sample;
VectorScale( light[((t*2)+(v-1))*w + ((s*2)+(u-1))], weight[u][v], sample );
divisor += weight[u][v];
VectorAdd( total, sample, total );
}
}
}
#endif
if ( divisor > 1.0 )
VectorScale( total, 1/divisor, total );
total[0] = max(total[0],0.0);
total[1] = max(total[1],0.0);
total[2] = max(total[2],0.0);
}
else
VectorCopy( light[ c ], total );
// Scale
VectorScale( total, rangescale, total );
// Clamp
if( hicolor )
{
for( j=0; j<3; j++ )
{
total[ j ] *= clampfactor;
if( total[j] > clamp)
total[j] = clamp;
else if (total[j] < 0)
Error ("light < 0");
*out++ = (byte) total[j];
}
}
else
{
int intensity = total[ 0 ] + total[ 1 ] + total[ 2 ];
if( intensity > 255 )
intensity = 255;
else if( intensity < 0 )
Error( "light < 0" );
*out++ = (byte) intensity;
}
}
}
}
}

View File

@ -0,0 +1,132 @@
# Microsoft Developer Studio Project File - Name="light" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=light - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "light.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "light.mak" CFG="light - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "light - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "light - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "light - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /GX /O2 /I "..\..\common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "light - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\Debug"
# PROP Intermediate_Dir ".\Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /Gm /GX /ZI /Od /I "..\..\common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
!ENDIF
# Begin Target
# Name "light - Win32 Release"
# Name "light - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\..\common\bspfile.c
# End Source File
# Begin Source File
SOURCE=..\..\common\cmdlib.c
# End Source File
# Begin Source File
SOURCE=..\light.c
# End Source File
# Begin Source File
SOURCE=..\ltface.c
# End Source File
# Begin Source File
SOURCE=..\..\common\mathlib.c
# End Source File
# Begin Source File
SOURCE=..\..\common\scriplib.c
# End Source File
# Begin Source File
SOURCE=..\..\common\threads.c
# End Source File
# Begin Source File
SOURCE=..\trace.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=..\light.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@ -0,0 +1,312 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="light"
ProjectGUID="{44EB71E1-F1E7-4A77-92AB-22E054865619}"
SccProjectName=""
SccLocalPath="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/light.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/light.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/light.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/light.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
RuntimeLibrary="5"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/light.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/light.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/light.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/light.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90">
<File
RelativePath="..\..\common\bspfile.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\cmdlib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\light.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\ltface.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\mathlib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\threads.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\trace.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd">
<File
RelativePath="..\light.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,418 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="light"
ProjectGUID="{44EB71E1-F1E7-4A77-92AB-22E054865619}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/light.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/light.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
SuppressStartupBanner="true"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/light.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\Release/light.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/light.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/light.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/light.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/light.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
>
<File
RelativePath="..\..\common\bspfile.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\cmdlib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\light.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\ltface.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\mathlib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\threads.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\trace.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd"
>
<File
RelativePath="..\light.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

206
hlsdk/utils/light/trace.c Normal file
View File

@ -0,0 +1,206 @@
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// trace.c
#include "light.h"
typedef struct tnode_s
{
int type;
vec3_t normal;
float dist;
int children[2];
int pad;
} tnode_t;
tnode_t *tnodes, *tnode_p;
/*
==============
MakeTnode
Converts the disk node structure into the efficient tracing structure
==============
*/
void MakeTnode (int nodenum)
{
tnode_t *t;
dplane_t *plane;
int i;
dnode_t *node;
t = tnode_p++;
node = dnodes + nodenum;
plane = dplanes + node->planenum;
t->type = plane->type;
VectorCopy (plane->normal, t->normal);
t->dist = plane->dist;
for (i=0 ; i<2 ; i++)
{
if (node->children[i] < 0)
t->children[i] = dleafs[-node->children[i] - 1].contents;
else
{
t->children[i] = tnode_p - tnodes;
MakeTnode (node->children[i]);
}
}
}
/*
=============
MakeTnodes
Loads the node structure out of a .bsp file to be used for light occlusion
=============
*/
void MakeTnodes (dmodel_t *bm)
{
if (!numnodes)
Error ("Map has no nodes\n");
tnode_p = tnodes = malloc(numnodes * sizeof(tnode_t));
MakeTnode (0);
}
/*
==============================================================================
LINE TRACING
The major lighting operation is a point to point visibility test, performed
by recursive subdivision of the line by the BSP tree.
==============================================================================
*/
typedef struct
{
vec3_t backpt;
int side;
int node;
} tracestack_t;
/*
==============
TestLine
==============
*/
qboolean TestLine (vec3_t start, vec3_t stop)
{
int node;
float front, back;
tracestack_t *tstack_p;
int side;
float frontx,fronty, frontz, backx, backy, backz;
tracestack_t tracestack[64];
tnode_t *tnode;
frontx = start[0];
fronty = start[1];
frontz = start[2];
backx = stop[0];
backy = stop[1];
backz = stop[2];
tstack_p = tracestack;
node = 0;
while (1)
{
while (node < 0 && node != CONTENTS_SOLID)
{
// pop up the stack for a back side
tstack_p--;
if (tstack_p < tracestack)
return true;
node = tstack_p->node;
// set the hit point for this plane
frontx = backx;
fronty = backy;
frontz = backz;
// go down the back side
backx = tstack_p->backpt[0];
backy = tstack_p->backpt[1];
backz = tstack_p->backpt[2];
node = tnodes[tstack_p->node].children[!tstack_p->side];
}
if (node == CONTENTS_SOLID)
return false; // DONE!
tnode = &tnodes[node];
switch (tnode->type)
{
case PLANE_X:
front = frontx - tnode->dist;
back = backx - tnode->dist;
break;
case PLANE_Y:
front = fronty - tnode->dist;
back = backy - tnode->dist;
break;
case PLANE_Z:
front = frontz - tnode->dist;
back = backz - tnode->dist;
break;
default:
front = (frontx*tnode->normal[0] + fronty*tnode->normal[1] + frontz*tnode->normal[2]) - tnode->dist;
back = (backx*tnode->normal[0] + backy*tnode->normal[1] + backz*tnode->normal[2]) - tnode->dist;
break;
}
if (front > -ON_EPSILON && back > -ON_EPSILON)
// if (front > 0 && back > 0)
{
node = tnode->children[0];
continue;
}
if (front < ON_EPSILON && back < ON_EPSILON)
// if (front <= 0 && back <= 0)
{
node = tnode->children[1];
continue;
}
side = front < 0;
front = front / (front-back);
tstack_p->node = node;
tstack_p->side = side;
tstack_p->backpt[0] = backx;
tstack_p->backpt[1] = backy;
tstack_p->backpt[2] = backz;
tstack_p++;
backx = frontx + front*(backx-frontx);
backy = fronty + front*(backy-fronty);
backz = frontz + front*(backz-frontz);
node = tnode->children[side];
}
}

View File

@ -0,0 +1,494 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#define _NOENUMQBOOL
#include <windows.h>
extern "C"
{
#include "cmdlib.h"
#include "wadlib.h"
}
#include "qfont.h"
#define DEFAULT_FONT "Arial"
#define FONT_TAG 6 // Font's are the 6th tag after the TYP_LUMPY base ( 64 )...i.e., type == 70
BOOL bItalic = FALSE;
BOOL bBold = FALSE;
BOOL bUnderline = FALSE;
char fontname[ 256 ];
int pointsize[3] = { 9, 11, 15 };
/*
=================
zeromalloc
Allocates and zeroes memory
=================
*/
void *zeromalloc( size_t size )
{
unsigned char *pbuffer;
pbuffer = ( unsigned char * )malloc( size );
if ( !pbuffer )
{
printf( "Failed on allocation of %i bytes", size );
exit( -1 );
}
memset( pbuffer, 0, size );
return ( void * )pbuffer;
}
/*
=================
Draw_SetupConsolePalette
Set's the palette to full brightness ( 192 ) and
set's up palette entry 0 -- black
=================
*/
void Draw_SetupConsolePalette( unsigned char *pal )
{
unsigned char *pPalette;
int i;
pPalette = pal;
*(short *)pPalette = 3 * 256;
pPalette += sizeof( short );
for ( i = 0; i < 256; i++ )
{
pPalette[3 * i + 0 ] = i;
pPalette[3 * i + 1 ] = i;
pPalette[3 * i + 2 ] = i;
}
// Set palette zero correctly
pPalette[ 0 ] = 0;
pPalette[ 1 ] = 0;
pPalette[ 2 ] = 0;
}
/*
=================
CreateConsoleFont
Renders TT font into memory dc and creates appropriate qfont_t structure
=================
*/
// YWB: Sigh, VC 6.0's global optimizer causes weird stack fixups in release builds. Disable the globabl optimizer for this function.
#pragma optimize( "g", off )
qfont_t *CreateConsoleFont( char *pszFont, int nPointSize, BOOL bItalic, BOOL bUnderline, BOOL bBold, int *outsize )
{
HDC hdc;
HDC hmemDC;
HBITMAP hbm, oldbm;
RECT rc;
HFONT fnt, oldfnt;
int startchar = 32;
int c;
int i, j;
int x, y;
int nScans;
unsigned char *bits;
BITMAPINFO tempbmi;
BITMAPINFO *pbmi;
BITMAPINFOHEADER *pbmheader;
unsigned char *pqdata;
unsigned char *pCur;
int x1, y1;
unsigned char *pPalette;
qfont_t *pqf = NULL;
int fullsize;
int w = 16;
int h = (128-32)/16;
int charheight = nPointSize + 5;
int charwidth = 16;
RECT rcChar;
// Create the font
fnt = CreateFont( -nPointSize, 0, 0, 0, bBold ? FW_HEAVY : FW_MEDIUM, bItalic, bUnderline, 0, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH | FF_DONTCARE, pszFont );
bits = NULL;
fullsize = sizeof( qfont_t ) - 4 + ( 128 * w * charwidth ) + sizeof(short) + 768 + 64;
// Store off final size
*outsize = fullsize;
pqf = ( qfont_t * )zeromalloc( fullsize );
pqdata = (unsigned char *)pqf + sizeof( qfont_t ) - 4;
pPalette = pqdata + ( 128 * w * charwidth );
// Configure palette
Draw_SetupConsolePalette( pPalette );
hdc = GetDC( NULL );
hmemDC = CreateCompatibleDC( hdc );
rc.top = 0;
rc.left = 0;
rc.right = charwidth * w;
rc.bottom = charheight * h;
hbm = CreateBitmap( charwidth * w, charheight * h, 1, 1, NULL );
oldbm = (HBITMAP)SelectObject( hmemDC, hbm );
oldfnt = (HFONT)SelectObject( hmemDC, fnt );
SetTextColor( hmemDC, 0x00ffffff );
SetBkMode( hmemDC, TRANSPARENT );
// Paint black background
FillRect( hmemDC, &rc, (HBRUSH)GetStockObject( BLACK_BRUSH ) );
// Draw character set into memory DC
for ( j = 0; j < h; j++ )
{
for ( i = 0; i < w; i++ )
{
x = i * charwidth;
y = j * charheight;
c = (char)( startchar + j * w + i );
// Only draw printable characters, of course
if ( isprint( c ) && c <= 127 )
{
// Draw it.
rcChar.left = x + 1;
rcChar.top = y + 1;
rcChar.right = x + charwidth - 1;
rcChar.bottom = y + charheight - 1;
DrawText( hmemDC, (char *)&c, 1, &rcChar, DT_NOPREFIX | DT_LEFT );
}
}
}
// Now turn the qfont into raw format
memset( &tempbmi, 0, sizeof( BITMAPINFO ) );
pbmheader = ( BITMAPINFOHEADER * )&tempbmi;
pbmheader->biSize = sizeof( BITMAPINFOHEADER );
pbmheader->biWidth = w * charwidth;
pbmheader->biHeight = -h * charheight;
pbmheader->biPlanes = 1;
pbmheader->biBitCount = 1;
pbmheader->biCompression = BI_RGB;
// Find out how big the bitmap is
nScans = GetDIBits( hmemDC, hbm, 0, h * charheight, NULL, &tempbmi, DIB_RGB_COLORS );
// Allocate space for all bits
pbmi = ( BITMAPINFO * )zeromalloc( sizeof ( BITMAPINFOHEADER ) + 2 * sizeof( RGBQUAD ) + pbmheader->biSizeImage );
memcpy( pbmi, &tempbmi, sizeof( BITMAPINFO ) );
bits = ( unsigned char * )pbmi + sizeof( BITMAPINFOHEADER ) + 2 * sizeof( RGBQUAD );
// Now read in bits
nScans = GetDIBits( hmemDC, hbm, 0, h * charheight, bits, pbmi, DIB_RGB_COLORS );
if ( nScans > 0 )
{
// Now convert to proper raw format
//
// Now get results from dib
pqf->height = 128; // Always set to 128
pqf->width = charwidth;
pqf->rowheight = charheight;
pqf->rowcount = h;
pCur = pqdata;
// Set everything to index 255 ( 0xff ) == transparent
memset( pCur, 0xFF, w * charwidth * pqf->height );
for ( j = 0; j < h; j++ )
{
for ( i = 0; i < w; i++ )
{
int edge = 1;
int bestwidth;
x = i * charwidth;
y = j * charheight;
c = (char)( startchar + j * w + i );
pqf->fontinfo[ c ].charwidth = charwidth;
pqf->fontinfo[ c ].startoffset = y * w * charwidth + x;
bestwidth = 0;
// In this first pass, place the black drop shadow so characters draw ok in the engine against
// most backgrounds.
// YWB: FIXME, apply a box filter and enable blending?
// Make it all transparent for starters
for ( y1 = 0; y1 < charheight; y1++ )
{
for ( x1 = 0; x1 < charwidth; x1++ )
{
int offset;
offset = ( y + y1 ) * w * charwidth + x + x1 ;
// Dest
pCur = pqdata + offset;
// Assume transparent
pCur[0] = 255;
}
}
// Put black pixels below and to the right of each pixel
for ( y1 = edge; y1 < charheight - edge; y1++ )
{
for ( x1 = 0; x1 < charwidth; x1++ )
{
int offset;
int srcoffset;
int xx0, yy0;
offset = ( y + y1 ) * w * charwidth + x + x1 ;
// Dest
pCur = pqdata + offset;
for ( xx0 = -edge; xx0 <= edge; xx0++ )
{
for ( yy0 = -edge; yy0 <= edge; yy0++ )
{
srcoffset = ( y + y1 + yy0 ) * w * charwidth + x + x1 + xx0;
if ( bits[ srcoffset >> 3 ] & ( 1 << ( 7 - srcoffset & 7 ) ) )
{
// Near Black
pCur[0] = 32;
}
}
}
}
}
// Now copy in the actual font pixels
for ( y1 = 0; y1 < charheight; y1++ )
{
for ( x1 = 0; x1 < charwidth; x1++ )
{
int offset;
offset = ( y + y1 ) * w * charwidth + x + x1;
// Dest
pCur = pqdata + offset;
if ( bits[ offset >> 3 ] & ( 1 << ( 7 - offset & 7 ) ) )
{
if ( x1 > bestwidth )
{
bestwidth = x1;
}
// Full color
// FIXME: Enable true palette support in engine?
pCur[0] = 192;
}
}
}
// bestwidth += 1;
/*
// Now blend it
for ( y1 = 0; y1 < charheight; y1++ )
{
for ( x1 = 0; x1 < charwidth; x1++ )
{
int offset;
offset = ( y + y1 ) * w * charwidth + x + x1;
// Dest
pCur = pqdata + offset;
if ( bits[ offset >> 3 ] & ( 1 << ( 7 - offset & 7 ) ) )
{
if ( x1 > bestwidth )
{
bestwidth = x1;
}
// Full color
// FIXME: Enable true palette support in engine?
pCur[0] = 192;
}
}
}
*/
// Space character width
if ( c == 32 )
{
bestwidth = 8;
}
else
{
// Small characters needs can be padded a bit so they don't run into each other
if ( bestwidth <= 14 )
{
bestwidth += 2;
}
}
// Store off width
pqf->fontinfo[ c ].charwidth = bestwidth;
}
}
}
// Free memory bits
free ( pbmi );
SelectObject( hmemDC, oldfnt );
DeleteObject( fnt );
SelectObject( hmemDC, oldbm );
DeleteObject( hbm );
DeleteDC( hmemDC );
ReleaseDC( NULL, hdc );
return pqf;
}
#pragma optimize( "g", on )
/*
=================
main
=================
*/
int main(int argc, char* argv[])
{
int i;
DWORD start, end;
char destfile[1024];
char sz[ 32 ];
int outsize[ 3 ];
qfont_t *fonts[ 3 ];
strcpy( fontname, DEFAULT_FONT );
printf("makefont.exe Version 1.0 by valve (%s)\n", __DATE__ );
printf ("----- Creating Console Font ----\n");
for (i=1 ; i<argc ; i++)
{
if (!strcmp(argv[i],"-font"))
{
strcpy( fontname, argv[i+1] );
i++;
}
else if (!strcmp(argv[i],"-pointsizes"))
{
if ( i + 3 >= argc )
{
Error( "Makefont: Insufficient point sizes specified\n" );
}
pointsize[0] = atoi( argv[i+1] );
pointsize[1] = atoi( argv[i+2] );
pointsize[2] = atoi( argv[i+3] );
i += 3;
}
else if (!strcmp(argv[i],"-italic"))
{
bItalic = TRUE;
printf ( "italic set\n");
}
else if (!strcmp(argv[i],"-bold"))
{
bBold = TRUE;
printf ( "bold set\n");
}
else if (!strcmp(argv[i],"-underline"))
{
bUnderline = TRUE;
printf ( "underline set\n");
}
else if ( argv[i][0] == '-' )
{
Error ("Unknown option \"%s\"", argv[i]);
}
else
break;
}
if ( i != argc - 1 )
{
Error ("usage: makefont [-font \"fontname\"] [-italic] [-underline] [-bold] [-pointsizes sm med lg] outfile");
}
printf( "Creating %i, %i, and %i point %s fonts\n", pointsize[0], pointsize[1], pointsize[2], fontname );
start = timeGetTime();
// Create the fonts
for ( i = 0 ; i < 3; i++ )
{
fonts[ i ] = CreateConsoleFont( fontname, pointsize[i], bItalic, bUnderline, bBold, &outsize[ i ] );
}
// Create wad file
strcpy (destfile, argv[argc - 1]);
StripExtension (destfile);
DefaultExtension (destfile, ".wad");
NewWad( destfile, false );
// Add fonts as lumps
for ( i = 0; i < 3; i++ )
{
sprintf( sz, "font%i", i );
AddLump( sz, fonts[ i ], outsize[ i ], TYP_LUMPY + FONT_TAG, false );
}
// Store results as a WAD3
// NOTE: ( should be named fonts.wad in the valve\ subdirectory )
WriteWad( 3 );
// Clean up memory
for ( i = 0 ; i < 3; i++ )
{
free( fonts[ i ] );
}
end = timeGetTime ();
printf ( "%5.5f seconds elapsed\n", (float)( end - start )/1000.0 );
// Display for a second since it might not be running from command prompt
Sleep( 1000 );
return 0;
}

View File

@ -0,0 +1,134 @@
# Microsoft Developer Studio Project File - Name="makefont" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=makefont - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "makefont.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "makefont.mak" CFG="makefont - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "makefont - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "makefont - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "makefont - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /W3 /GX /Zi /O2 /I "../../../common" /I "../../common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX"qfont.h" /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:console /debug /machine:I386
# Begin Special Build Tool
TargetPath=.\Release\makefont.exe
SOURCE="$(InputPath)"
# End Special Build Tool
!ELSEIF "$(CFG)" == "makefont - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../common" /I "../../common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX"qfont.h" /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# Begin Special Build Tool
TargetPath=.\Debug\makefont.exe
SOURCE="$(InputPath)"
# End Special Build Tool
!ENDIF
# Begin Target
# Name "makefont - Win32 Release"
# Name "makefont - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\common\cmdlib.c
# End Source File
# Begin Source File
SOURCE=..\makefont.cpp
# End Source File
# Begin Source File
SOURCE=..\..\common\wadlib.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\..\common\cmdlib.h
# End Source File
# Begin Source File
SOURCE=..\StdAfx.h
# End Source File
# Begin Source File
SOURCE=..\..\common\wadlib.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# Begin Source File
SOURCE=..\ReadMe.txt
# End Source File
# End Target
# End Project

View File

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "makefont"=.\makefont.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@ -0,0 +1,231 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="makefont"
ProjectGUID="{26AE2C7D-A52F-473D-8B9E-F3D6B13B13D8}"
SccProjectName=""
SccLocalPath="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="../../../common,../../common"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="qfont.h"
PrecompiledHeaderFile=".\Release/makefont.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="odbc32.lib odbccp32.lib winmm.lib"
OutputFile=".\Release/makefont.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Release/makefont.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/makefont.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../common,../../common"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="qfont.h"
PrecompiledHeaderFile=".\Debug/makefont.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="odbc32.lib odbccp32.lib winmm.lib"
OutputFile=".\Debug/makefont.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/makefont.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/makefont.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="..\..\common\cmdlib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
</File>
<File
RelativePath="..\makefont.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\wadlib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath="..\..\common\cmdlib.h">
</File>
<File
RelativePath="..\StdAfx.h">
</File>
<File
RelativePath="..\..\common\wadlib.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
</Filter>
<File
RelativePath="..\ReadMe.txt">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,315 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="makefont"
ProjectGUID="{26AE2C7D-A52F-473D-8B9E-F3D6B13B13D8}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/makefont.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="../../../common,../../common"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderThrough="qfont.h"
PrecompiledHeaderFile=".\Release/makefont.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="odbc32.lib odbccp32.lib winmm.lib"
OutputFile=".\Release/makefont.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Release/makefont.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/makefont.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../common,../../common"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderThrough="qfont.h"
PrecompiledHeaderFile=".\Debug/makefont.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="odbc32.lib odbccp32.lib winmm.lib"
OutputFile=".\Debug/makefont.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/makefont.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="..\..\common\cmdlib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\makefont.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\wadlib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
<File
RelativePath="..\..\common\cmdlib.h"
>
</File>
<File
RelativePath="..\StdAfx.h"
>
</File>
<File
RelativePath="..\..\common\wadlib.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
<File
RelativePath="..\ReadMe.txt"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,181 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#if defined _MSC_VER && _MSC_VER >= 1400
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif
#pragma warning(disable: 4996) // deprecated functions
#endif
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **ppszFiles = NULL;
int nFiles = 0;
int nMaxFiles = 0;
int
string_comparator( const void *string1, const void *string2 )
{
char *s1 = *(char **)string1;
char *s2 = *(char **)string2;
return strcmp( s1, s2 );
}
void PrintUsage(char *pname)
{
printf("\n\tusage:%s <source directory> <wadfile name> <script name> \n\n",pname);
printf("\t%s.exe is used to generate a bitmap name sorted 'qlumpy script'.\n",pname);
}
int main(int argc, void **argv)
{
char *pszdir;
char *pszWadName;
char *pszScriptName;
char szBuf[1024];
HANDLE hFile, hScriptFile;
WIN32_FIND_DATA FindData;
BOOL fWrite;
BOOL fContinue = TRUE;
DWORD dwWritten;
printf("makels Copyright (c) 1998 Valve L.L.C., %s\n", __DATE__ );
pszdir = (char *)argv[1];
if ((argc != 4) || (pszdir[0] == '/') || (pszdir[0] == '-'))
{
PrintUsage((char *)argv[0]);
exit(1);
}
pszdir = (char *)malloc(strlen((char *)argv[1]) + 7);
strcpy(pszdir, (char *)argv[1]);
strcat(pszdir, "\\*.bmp");
pszWadName = (char *)malloc(strlen((char *)argv[2]) + 5);
strcpy(pszWadName, (char *)argv[2]);
strcat(pszWadName, ".WAD");
pszScriptName = (char *)malloc(strlen((char *)argv[3]));
strcpy(pszScriptName, (char *)argv[3]);
hScriptFile = CreateFile(pszScriptName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hScriptFile == INVALID_HANDLE_VALUE)
{
printf("\n---------- ERROR ------------------\n");
printf(" Could not open the script file: %s\n", pszScriptName);
Beep(800,500);
exit(EXIT_FAILURE);
}
sprintf(szBuf, "$DEST \"%s\"\r\n\r\n", pszWadName);
fWrite = WriteFile(hScriptFile, szBuf, strlen(szBuf), &dwWritten, NULL);
if (!fWrite || (dwWritten != strlen(szBuf)))
{
write_error:
printf("\n---------- ERROR ------------------\n");
printf(" Could not write to the script file: %s\n", pszScriptName);
Beep(800,500);
CloseHandle(hScriptFile);
exit(EXIT_FAILURE);
}
hFile = FindFirstFile(pszdir, &FindData);
if (hFile != INVALID_HANDLE_VALUE)
{
while (fContinue)
{
if (!(FindData.dwFileAttributes &
(FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN)))
{
char szShort[MAX_PATH];
// ignore N_ and F_ files
strcpy(szShort, FindData.cFileName);
strupr(szShort);
if ((szShort[1] == '_') && ((szShort[0] == 'N') || (szShort[0] == 'F')))
{
printf("Skipping %s.\n", FindData.cFileName);
} else {
if ( nFiles >= nMaxFiles )
{
nMaxFiles += 1000;
ppszFiles = (char **)realloc( ppszFiles, nMaxFiles * sizeof(*ppszFiles) );
if ( !ppszFiles )
{
printf("\n---------- ERROR ------------------\n");
printf(" Could not realloc more filename pointer storage\n");
Beep(800,500);
exit(EXIT_FAILURE);
}
}
ppszFiles[nFiles++] = strdup( szShort );
}
}
fContinue = FindNextFile(hFile, &FindData);
}
}
if (nFiles > 0)
{
qsort( ppszFiles, nFiles, sizeof(char*), string_comparator );
for( int i = 0; i < nFiles; i++ )
{
char *p;
char szShort[MAX_PATH];
char szFull[MAX_PATH];
strcpy(szShort, pszdir);
p = strchr(szShort, '*');
*p = '\0';
strcat(szShort, ppszFiles[i]);
GetFullPathName(szShort, MAX_PATH, szFull, NULL);
sprintf(szBuf, "$loadbmp \"%s\"\r\n", szFull);
fWrite = WriteFile(hScriptFile, szBuf, strlen(szBuf), &dwWritten, NULL);
if (!fWrite || (dwWritten != strlen(szBuf)))
goto write_error;
p = strchr(ppszFiles[i], '.');
*p = '\0';
sprintf(szBuf, "%s miptex -1 -1 -1 -1\r\n\r\n", ppszFiles[i]);
fWrite = WriteFile(hScriptFile, szBuf, strlen(szBuf), &dwWritten, NULL);
if (!fWrite || (dwWritten != strlen(szBuf)))
goto write_error;
free( ppszFiles[i] );
}
}
printf("Processed %d files specified by %s\n", nFiles, pszdir );
CloseHandle(hScriptFile);
free(pszdir);
exit(0);
return 0;
}

View File

@ -0,0 +1,212 @@
# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
!IF "$(CFG)" == ""
CFG=makels - Win32 Debug
!MESSAGE No configuration specified. Defaulting to makels - Win32 Debug.
!ENDIF
!IF "$(CFG)" != "makels - Win32 Release" && "$(CFG)" != "makels - Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "makels.mak" CFG="makels - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "makels - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "makels - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE
NULL=nul
!ENDIF
################################################################################
# Begin Project
# PROP Target_Last_Scanned "makels - Win32 Debug"
RSC=rc.exe
CPP=cl.exe
!IF "$(CFG)" == "makels - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
OUTDIR=.\Release
INTDIR=.\Release
ALL : "$(OUTDIR)\makels.exe"
CLEAN :
-@erase "$(INTDIR)\makels.obj"
-@erase "$(OUTDIR)\makels.exe"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
/Fp"$(INTDIR)/makels.pch" /YX /Fo"$(INTDIR)/" /c
CPP_OBJS=.\Release/
CPP_SBRS=.\.
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/makels.bsc"
BSC32_SBRS= \
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo\
/subsystem:console /incremental:no /pdb:"$(OUTDIR)/makels.pdb" /machine:I386\
/out:"$(OUTDIR)/makels.exe"
LINK32_OBJS= \
"$(INTDIR)\makels.obj"
"$(OUTDIR)\makels.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "makels - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
OUTDIR=.\Debug
INTDIR=.\Debug
ALL : "$(OUTDIR)\makels.exe" "$(OUTDIR)\makels.bsc"
CLEAN :
-@erase "$(INTDIR)\makels.obj"
-@erase "$(INTDIR)\makels.sbr"
-@erase "$(INTDIR)\vc40.idb"
-@erase "$(INTDIR)\vc40.pdb"
-@erase "$(OUTDIR)\makels.bsc"
-@erase "$(OUTDIR)\makels.exe"
-@erase "$(OUTDIR)\makels.ilk"
-@erase "$(OUTDIR)\makels.pdb"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /YX /c
CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\
/FR"$(INTDIR)/" /Fp"$(INTDIR)/makels.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/"\
/c
CPP_OBJS=.\Debug/
CPP_SBRS=.\Debug/
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/makels.bsc"
BSC32_SBRS= \
"$(INTDIR)\makels.sbr"
"$(OUTDIR)\makels.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo\
/subsystem:console /incremental:yes /pdb:"$(OUTDIR)/makels.pdb" /debug\
/machine:I386 /out:"$(OUTDIR)/makels.exe"
LINK32_OBJS= \
"$(INTDIR)\makels.obj"
"$(OUTDIR)\makels.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.c{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Target
# Name "makels - Win32 Release"
# Name "makels - Win32 Debug"
!IF "$(CFG)" == "makels - Win32 Release"
!ELSEIF "$(CFG)" == "makels - Win32 Debug"
!ENDIF
################################################################################
# Begin Source File
SOURCE=.\makels.cpp
!IF "$(CFG)" == "makels - Win32 Release"
"$(INTDIR)\makels.obj" : $(SOURCE) "$(INTDIR)"
!ELSEIF "$(CFG)" == "makels - Win32 Debug"
"$(INTDIR)\makels.obj" : $(SOURCE) "$(INTDIR)"
"$(INTDIR)\makels.sbr" : $(SOURCE) "$(INTDIR)"
!ENDIF
# End Source File
# End Target
# End Project
################################################################################

View File

@ -0,0 +1,100 @@
# Microsoft Developer Studio Project File - Name="makels" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=makels - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "makels.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "makels.mak" CFG="makels - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "makels - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "makels - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/SDKSrc/Tools/utils/makels", OUGBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "makels - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "makels - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\Debug"
# PROP Intermediate_Dir ".\Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386
!ENDIF
# Begin Target
# Name "makels - Win32 Release"
# Name "makels - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\makels.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@ -0,0 +1,37 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "makels"=.\makels.dsp - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/SDKSrc/Tools/utils/makels", OUGBAAAA
.
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
begin source code control
"$/SDKSrc/Tools/utils/makels", OUGBAAAA
.
end source code control
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="makels"
ProjectGUID="{1F049399-BFCD-4F88-95DA-A22747A23D0E}"
SccProjectName="&quot;$/SDKSrc/Tools/utils/makels&quot;, OUGBAAAA"
SccLocalPath=".">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/makels.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/makels.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/makels.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/makels.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
RuntimeLibrary="5"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/makels.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/makels.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/makels.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/makels.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90">
<File
RelativePath="..\makels.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd">
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,235 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="makels"
ProjectGUID="{1F049399-BFCD-4F88-95DA-A22747A23D0E}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/makels.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/makels.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/makels.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\Release/makels.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/makels.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/makels.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/makels.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/makels.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
>
<File
RelativePath="..\makels.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd"
>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,268 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
****/
// updates:
// 1-4-98 fixed initialization
#include <stdio.h>
#include <windows.h>
#include <gl\GL.h>
#include <gl\GLU.h>
#include <gl\glut.h>
#include "mathlib.h"
#include "..\..\engine\studio.h"
#include "mdlviewer.h"
#pragma warning( disable : 4244 ) // conversion from 'double ' to 'float ', possible loss of data
#pragma warning( disable : 4305 ) // truncation from 'const double ' to 'float '
vec3_t g_vright; // needs to be set to viewer's right in order for chrome to work
float g_lambert = 1.5;
float gldepthmin = 0;
float gldepthmax = 10.0;
/*
=============
R_Clear
=============
*/
void R_Clear (void)
{
glDepthFunc (GL_LEQUAL);
glDepthRange (gldepthmin, gldepthmax);
glDepthMask( 1 );
}
static StudioModel tempmodel;
void mdlviewer_display( )
{
R_Clear( );
tempmodel.SetBlending( 0, 0.0 );
tempmodel.SetBlending( 1, 0.0 );
static float prev;
float curr = GetTickCount( ) / 1000.0;
tempmodel.AdvanceFrame( curr - prev );
prev = curr;
tempmodel.DrawModel( );
}
void mdlviewer_init( char *modelname )
{
// make a bogus texture
// R_InitTexture( );
tempmodel.Init( modelname );
tempmodel.SetSequence( 0 );
tempmodel.SetController( 0, 0.0 );
tempmodel.SetController( 1, 0.0 );
tempmodel.SetController( 2, 0.0 );
tempmodel.SetController( 3, 0.0 );
tempmodel.SetMouth( 0 );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50.,1.,.1,10.);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor( 0, 0, 0.5, 0 );
}
void mdlviewer_nextsequence( void )
{
int iSeq = tempmodel.GetSequence( );
if (iSeq == tempmodel.SetSequence( iSeq + 1 ))
{
tempmodel.SetSequence( 0 );
}
}
//////////////////////////////////////////////////////////////////
static int pstyle;
static int translate = 1;
static int mesh = 1;
static float transx = 0, transy = 0, transz = -2, rotx=235, roty=-90;
static float amplitude = 0.03;
static float freq = 5.0f;
static float phase = .00003;
static int ox = -1, oy = -1;
static int show_t = 1;
static int mot;
#define PAN 1
#define ROT 2
#define ZOOM 3
void pan(int x, int y)
{
transx += (x-ox)/500.;
transy -= (y-oy)/500.;
ox = x; oy = y;
glutPostRedisplay();
}
void zoom(int x, int y)
{
transz += (x-ox)/20.;
ox = x;
glutPostRedisplay();
}
void rotate(int x, int y)
{
rotx += x-ox;
if (rotx > 360.) rotx -= 360.;
else if (rotx < -360.) rotx += 360.;
roty += y-oy;
if (roty > 360.) roty -= 360.;
else if (roty < -360.) roty += 360.;
ox = x; oy = y;
glutPostRedisplay();
}
void motion(int x, int y)
{
if (mot == PAN)
pan(x, y);
else if (mot == ROT)
rotate(x,y);
else if ( mot == ZOOM )
zoom( x, y );
}
void mouse(int button, int state, int x, int y)
{
if(state == GLUT_DOWN) {
switch(button) {
case GLUT_LEFT_BUTTON:
mot = PAN;
motion(ox = x, oy = y);
break;
case GLUT_RIGHT_BUTTON:
mot = ROT;
motion(ox = x, oy = y);
break;
case GLUT_MIDDLE_BUTTON:
break;
}
} else if (state == GLUT_UP) {
mot = 0;
}
}
void help(void)
{
printf("left mouse - pan\n");
printf("right mouse - rotate\n");
}
void init( char *arg )
{
mdlviewer_init( arg );
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50.,1.,.1,10.);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// glTranslatef(0.,0.,-5.5);
// glTranslatef(-.2.,1.0,-1.5);
glClearColor( 0, 0, 0.5, 0 );
}
void display(void)
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix();
glTranslatef(transx, transy, transz);
glRotatef(rotx, 0., 1., 0.);
glRotatef(roty, 1., 0., 0.);
glScalef( 0.01, 0.01, 0.01 );
glCullFace( GL_FRONT );
glEnable( GL_DEPTH_TEST );
mdlviewer_display( );
glPopMatrix();
glutSwapBuffers();
glutPostRedisplay();
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
}
/*ARGSUSED1*/
void key(unsigned char key, int x, int y)
{
switch(key)
{
case 'h':
help();
break;
case 'p':
printf("Translation: %f, %f %f\n", transx, transy, transz );
break;
case '\033': // Escape
exit(EXIT_SUCCESS);
break;
case ' ':
mdlviewer_nextsequence( );
break;
default:
break;
}
glutPostRedisplay();
}
int main(int argc, char** argv)
{
if (argc != 2)
{
printf("usage : %s <filename>\n", argv[0] );
exit(1);
}
glutInitWindowSize(512, 512);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
(void)glutCreateWindow(argv[0]);
init( argv[1] );
glutDisplayFunc(display);
glutKeyboardFunc(key);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutMainLoop();
return 0;
}

View File

@ -0,0 +1,78 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
typedef unsigned char byte;
class StudioModel
{
public:
void Init( char *modelname );
void DrawModel( void );
void AdvanceFrame( float dt );
void ExtractBbox( float *mins, float *maxs );
int SetSequence( int iSequence );
int GetSequence( void );
void GetSequenceInfo( float *pflFrameRate, float *pflGroundSpeed );
float SetController( int iController, float flValue );
float SetMouth( float flValue );
float SetBlending( int iBlender, float flValue );
int SetBodygroup( int iGroup, int iValue );
int SetSkin( int iValue );
private:
// entity settings
vec3_t m_origin;
vec3_t m_angles;
int m_sequence; // sequence index
float m_frame; // frame
int m_bodynum; // bodypart selection
int m_skinnum; // skin group selection
byte m_controller[4]; // bone controllers
byte m_blending[2]; // animation blending
byte m_mouth; // mouth position
// internal data
studiohdr_t *m_pstudiohdr;
mstudiomodel_t *m_pmodel;
studiohdr_t *m_ptexturehdr;
studioseqhdr_t *m_panimhdr[32];
vec4_t m_adj; // FIX: non persistant, make static
studiohdr_t *LoadModel( char *modelname );
studioseqhdr_t *LoadDemandSequences( char *modelname );
void CalcBoneAdj( void );
void CalcBoneQuaternion( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *q );
void CalcBonePosition( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *pos );
void CalcRotations ( vec3_t *pos, vec4_t *q, mstudioseqdesc_t *pseqdesc, mstudioanim_t *panim, float f );
mstudioanim_t *GetAnim( mstudioseqdesc_t *pseqdesc );
void SlerpBones( vec4_t q1[], vec3_t pos1[], vec4_t q2[], vec3_t pos2[], float s );
void SetUpBones ( void );
void DrawPoints( void );
void Lighting (float *lv, int bone, int flags, vec3_t normal);
void Chrome (int *chrome, int bone, vec3_t normal);
void SetupLighting( void );
void SetupModel ( int bodypart );
void UploadTexture( mstudiotexture_t *ptexture, byte *data, byte *pal );
};
extern vec3_t g_vright; // needs to be set to viewer's right in order for chrome to work
extern float g_lambert; // modifier for pseudo-hemispherical lighting

View File

@ -0,0 +1,122 @@
# Microsoft Developer Studio Project File - Name="mdlviewer" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=mdlviewer - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "mdlviewer.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "mdlviewer.mak" CFG="mdlviewer - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "mdlviewer - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "mdlviewer - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/SDKSrc/Tools/utils/mdlviewer", AIHBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "mdlviewer - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\common" /I "..\..\..\common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib glut32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "mdlviewer - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "mdlviewer___Win32_Debug"
# PROP BASE Intermediate_Dir "mdlviewer___Win32_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\common" /I "..\..\..\common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glut32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "mdlviewer - Win32 Release"
# Name "mdlviewer - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\common\mathlib.c
# End Source File
# Begin Source File
SOURCE=..\mdlviewer.cpp
# End Source File
# Begin Source File
SOURCE=..\studio_render.cpp
# End Source File
# Begin Source File
SOURCE=..\studio_utils.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\..\common\mathlib.h
# End Source File
# Begin Source File
SOURCE=..\mdlviewer.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "mdlviewer"=".\mdlviewer.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@ -0,0 +1,246 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="mdlviewer"
ProjectGUID="{C4694871-3C3D-4D8D-AC8C-A55C6A80800E}"
SccProjectName="&quot;$/SDKSrc/Tools/utils/mdlviewer&quot;, AIHBAAAA"
SccLocalPath=".">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common,..\..\..\common"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/mdlviewer.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="glu32.lib odbc32.lib odbccp32.lib opengl32.lib glut32.lib"
OutputFile=".\Debug/mdlviewer.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/mdlviewer.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/mdlviewer.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common,..\..\..\common"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/mdlviewer.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib glu32.lib glut32.lib"
OutputFile=".\Release/mdlviewer.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/mdlviewer.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/mdlviewer.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="..\..\common\mathlib.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\mdlviewer.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\studio_render.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\studio_utils.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath="..\..\common\mathlib.h">
</File>
<File
RelativePath="..\mdlviewer.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,334 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="mdlviewer"
ProjectGUID="{C4694871-3C3D-4D8D-AC8C-A55C6A80800E}"
RootNamespace="mdlviewer"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/mdlviewer.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common,..\..\..\common"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/mdlviewer.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="glu32.lib odbc32.lib odbccp32.lib opengl32.lib glut32.lib"
OutputFile=".\Debug/mdlviewer.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/mdlviewer.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/mdlviewer.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common,..\..\..\common"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/mdlviewer.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib glu32.lib glut32.lib"
OutputFile=".\Release/mdlviewer.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\Release/mdlviewer.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="..\..\common\mathlib.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\mdlviewer.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\studio_render.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\studio_utils.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
<File
RelativePath="..\..\common\mathlib.h"
>
</File>
<File
RelativePath="..\mdlviewer.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,727 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// studio_render.cpp: routines for drawing Half-Life 3DStudio models
// updates:
// 1-4-99 fixed AdvanceFrame wraping bug
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#pragma warning( disable : 4244 ) // double to float
////////////////////////////////////////////////////////////////////////
#include "mathlib.h"
#include "..\..\engine\studio.h"
#include "mdlviewer.h"
////////////////////////////////////////////////////////////////////////
vec3_t g_xformverts[MAXSTUDIOVERTS]; // transformed vertices
vec3_t g_lightvalues[MAXSTUDIOVERTS]; // light surface normals
vec3_t *g_pxformverts;
vec3_t *g_pvlightvalues;
vec3_t g_lightvec; // light vector in model reference frame
vec3_t g_blightvec[MAXSTUDIOBONES]; // light vectors in bone reference frames
int g_ambientlight; // ambient world light
float g_shadelight; // direct world light
vec3_t g_lightcolor;
int g_smodels_total; // cookie
float g_bonetransform[MAXSTUDIOBONES][3][4]; // bone transformation matrix
int g_chrome[MAXSTUDIOVERTS][2]; // texture coords for surface normals
int g_chromeage[MAXSTUDIOBONES]; // last time chrome vectors were updated
vec3_t g_chromeup[MAXSTUDIOBONES]; // chrome vector "up" in bone reference frames
vec3_t g_chromeright[MAXSTUDIOBONES]; // chrome vector "right" in bone reference frames
////////////////////////////////////////////////////////////////////////
void StudioModel::CalcBoneAdj( )
{
int i, j;
float value;
mstudiobonecontroller_t *pbonecontroller;
pbonecontroller = (mstudiobonecontroller_t *)((byte *)m_pstudiohdr + m_pstudiohdr->bonecontrollerindex);
for (j = 0; j < m_pstudiohdr->numbonecontrollers; j++)
{
i = pbonecontroller[j].index;
if (i <= 3)
{
// check for 360% wrapping
if (pbonecontroller[j].type & STUDIO_RLOOP)
{
value = m_controller[i] * (360.0/256.0) + pbonecontroller[j].start;
}
else
{
value = m_controller[i] / 255.0;
if (value < 0) value = 0;
if (value > 1.0) value = 1.0;
value = (1.0 - value) * pbonecontroller[j].start + value * pbonecontroller[j].end;
}
// Con_DPrintf( "%d %d %f : %f\n", m_controller[j], m_prevcontroller[j], value, dadt );
}
else
{
value = m_mouth / 64.0;
if (value > 1.0) value = 1.0;
value = (1.0 - value) * pbonecontroller[j].start + value * pbonecontroller[j].end;
// Con_DPrintf("%d %f\n", mouthopen, value );
}
switch(pbonecontroller[j].type & STUDIO_TYPES)
{
case STUDIO_XR:
case STUDIO_YR:
case STUDIO_ZR:
m_adj[j] = value * (Q_PI / 180.0);
break;
case STUDIO_X:
case STUDIO_Y:
case STUDIO_Z:
m_adj[j] = value;
break;
}
}
}
void StudioModel::CalcBoneQuaternion( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *q )
{
int j, k;
vec4_t q1, q2;
vec3_t angle1, angle2;
mstudioanimvalue_t *panimvalue;
for (j = 0; j < 3; j++)
{
if (panim->offset[j+3] == 0)
{
angle2[j] = angle1[j] = pbone->value[j+3]; // default;
}
else
{
panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j+3]);
k = frame;
while (panimvalue->num.total <= k)
{
k -= panimvalue->num.total;
panimvalue += panimvalue->num.valid + 1;
}
// Bah, missing blend!
if (panimvalue->num.valid > k)
{
angle1[j] = panimvalue[k+1].value;
if (panimvalue->num.valid > k + 1)
{
angle2[j] = panimvalue[k+2].value;
}
else
{
if (panimvalue->num.total > k + 1)
angle2[j] = angle1[j];
else
angle2[j] = panimvalue[panimvalue->num.valid+2].value;
}
}
else
{
angle1[j] = panimvalue[panimvalue->num.valid].value;
if (panimvalue->num.total > k + 1)
{
angle2[j] = angle1[j];
}
else
{
angle2[j] = panimvalue[panimvalue->num.valid + 2].value;
}
}
angle1[j] = pbone->value[j+3] + angle1[j] * pbone->scale[j+3];
angle2[j] = pbone->value[j+3] + angle2[j] * pbone->scale[j+3];
}
if (pbone->bonecontroller[j+3] != -1)
{
angle1[j] += m_adj[pbone->bonecontroller[j+3]];
angle2[j] += m_adj[pbone->bonecontroller[j+3]];
}
}
if (!VectorCompare( angle1, angle2 ))
{
AngleQuaternion( angle1, q1 );
AngleQuaternion( angle2, q2 );
QuaternionSlerp( q1, q2, s, q );
}
else
{
AngleQuaternion( angle1, q );
}
}
void StudioModel::CalcBonePosition( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *pos )
{
int j, k;
mstudioanimvalue_t *panimvalue;
for (j = 0; j < 3; j++)
{
pos[j] = pbone->value[j]; // default;
if (panim->offset[j] != 0)
{
panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j]);
k = frame;
// find span of values that includes the frame we want
while (panimvalue->num.total <= k)
{
k -= panimvalue->num.total;
panimvalue += panimvalue->num.valid + 1;
}
// if we're inside the span
if (panimvalue->num.valid > k)
{
// and there's more data in the span
if (panimvalue->num.valid > k + 1)
{
pos[j] += (panimvalue[k+1].value * (1.0 - s) + s * panimvalue[k+2].value) * pbone->scale[j];
}
else
{
pos[j] += panimvalue[k+1].value * pbone->scale[j];
}
}
else
{
// are we at the end of the repeating values section and there's another section with data?
if (panimvalue->num.total <= k + 1)
{
pos[j] += (panimvalue[panimvalue->num.valid].value * (1.0 - s) + s * panimvalue[panimvalue->num.valid + 2].value) * pbone->scale[j];
}
else
{
pos[j] += panimvalue[panimvalue->num.valid].value * pbone->scale[j];
}
}
}
if (pbone->bonecontroller[j] != -1)
{
pos[j] += m_adj[pbone->bonecontroller[j]];
}
}
}
void StudioModel::CalcRotations ( vec3_t *pos, vec4_t *q, mstudioseqdesc_t *pseqdesc, mstudioanim_t *panim, float f )
{
int i;
int frame;
mstudiobone_t *pbone;
float s;
frame = (int)f;
s = (f - frame);
// add in programatic controllers
CalcBoneAdj( );
pbone = (mstudiobone_t *)((byte *)m_pstudiohdr + m_pstudiohdr->boneindex);
for (i = 0; i < m_pstudiohdr->numbones; i++, pbone++, panim++)
{
CalcBoneQuaternion( frame, s, pbone, panim, q[i] );
CalcBonePosition( frame, s, pbone, panim, pos[i] );
}
if (pseqdesc->motiontype & STUDIO_X)
pos[pseqdesc->motionbone][0] = 0.0;
if (pseqdesc->motiontype & STUDIO_Y)
pos[pseqdesc->motionbone][1] = 0.0;
if (pseqdesc->motiontype & STUDIO_Z)
pos[pseqdesc->motionbone][2] = 0.0;
}
mstudioanim_t * StudioModel::GetAnim( mstudioseqdesc_t *pseqdesc )
{
mstudioseqgroup_t *pseqgroup;
pseqgroup = (mstudioseqgroup_t *)((byte *)m_pstudiohdr + m_pstudiohdr->seqgroupindex) + pseqdesc->seqgroup;
if (pseqdesc->seqgroup == 0)
{
return (mstudioanim_t *)((byte *)m_pstudiohdr + pseqgroup->data + pseqdesc->animindex);
}
return (mstudioanim_t *)((byte *)m_panimhdr[pseqdesc->seqgroup] + pseqdesc->animindex);
}
void StudioModel::SlerpBones( vec4_t q1[], vec3_t pos1[], vec4_t q2[], vec3_t pos2[], float s )
{
int i;
vec4_t q3;
float s1;
if (s < 0) s = 0;
else if (s > 1.0) s = 1.0;
s1 = 1.0 - s;
for (i = 0; i < m_pstudiohdr->numbones; i++)
{
QuaternionSlerp( q1[i], q2[i], s, q3 );
q1[i][0] = q3[0];
q1[i][1] = q3[1];
q1[i][2] = q3[2];
q1[i][3] = q3[3];
pos1[i][0] = pos1[i][0] * s1 + pos2[i][0] * s;
pos1[i][1] = pos1[i][1] * s1 + pos2[i][1] * s;
pos1[i][2] = pos1[i][2] * s1 + pos2[i][2] * s;
}
}
void StudioModel::AdvanceFrame( float dt )
{
mstudioseqdesc_t *pseqdesc;
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pstudiohdr + m_pstudiohdr->seqindex) + m_sequence;
if (dt > 0.1)
dt = (float)0.1;
m_frame += dt * pseqdesc->fps;
if (pseqdesc->numframes <= 1)
{
m_frame = 0;
}
else
{
// wrap
m_frame -= (int)(m_frame / (pseqdesc->numframes - 1)) * (pseqdesc->numframes - 1);
}
}
void StudioModel::SetUpBones ( void )
{
int i;
mstudiobone_t *pbones;
mstudioseqdesc_t *pseqdesc;
mstudioanim_t *panim;
static vec3_t pos[MAXSTUDIOBONES];
float bonematrix[3][4];
static vec4_t q[MAXSTUDIOBONES];
static vec3_t pos2[MAXSTUDIOBONES];
static vec4_t q2[MAXSTUDIOBONES];
static vec3_t pos3[MAXSTUDIOBONES];
static vec4_t q3[MAXSTUDIOBONES];
static vec3_t pos4[MAXSTUDIOBONES];
static vec4_t q4[MAXSTUDIOBONES];
if (m_sequence >= m_pstudiohdr->numseq) {
m_sequence = 0;
}
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pstudiohdr + m_pstudiohdr->seqindex) + m_sequence;
panim = GetAnim( pseqdesc );
CalcRotations( pos, q, pseqdesc, panim, m_frame );
if (pseqdesc->numblends > 1)
{
float s;
panim += m_pstudiohdr->numbones;
CalcRotations( pos2, q2, pseqdesc, panim, m_frame );
s = m_blending[0] / 255.0;
SlerpBones( q, pos, q2, pos2, s );
if (pseqdesc->numblends == 4)
{
panim += m_pstudiohdr->numbones;
CalcRotations( pos3, q3, pseqdesc, panim, m_frame );
panim += m_pstudiohdr->numbones;
CalcRotations( pos4, q4, pseqdesc, panim, m_frame );
s = m_blending[0] / 255.0;
SlerpBones( q3, pos3, q4, pos4, s );
s = m_blending[1] / 255.0;
SlerpBones( q, pos, q3, pos3, s );
}
}
pbones = (mstudiobone_t *)((byte *)m_pstudiohdr + m_pstudiohdr->boneindex);
for (i = 0; i < m_pstudiohdr->numbones; i++) {
QuaternionMatrix( q[i], bonematrix );
bonematrix[0][3] = pos[i][0];
bonematrix[1][3] = pos[i][1];
bonematrix[2][3] = pos[i][2];
if (pbones[i].parent == -1) {
memcpy(g_bonetransform[i], bonematrix, sizeof(float) * 12);
}
else {
R_ConcatTransforms (g_bonetransform[pbones[i].parent], bonematrix, g_bonetransform[i]);
}
}
}
/*
================
StudioModel::TransformFinalVert
================
*/
void StudioModel::Lighting (float *lv, int bone, int flags, vec3_t normal)
{
float illum;
float lightcos;
illum = g_ambientlight;
if (flags & STUDIO_NF_FLATSHADE)
{
illum += g_shadelight * 0.8;
}
else
{
float r;
lightcos = DotProduct (normal, g_blightvec[bone]); // -1 colinear, 1 opposite
if (lightcos > 1.0)
lightcos = 1;
illum += g_shadelight;
r = g_lambert;
if (r <= 1.0) r = 1.0;
lightcos = (lightcos + (r - 1.0)) / r; // do modified hemispherical lighting
if (lightcos > 0.0)
{
illum -= g_shadelight * lightcos;
}
if (illum <= 0)
illum = 0;
}
if (illum > 255)
illum = 255;
*lv = illum / 255.0; // Light from 0 to 1.0
}
void StudioModel::Chrome (int *pchrome, int bone, vec3_t normal)
{
float n;
if (g_chromeage[bone] != g_smodels_total)
{
// calculate vectors from the viewer to the bone. This roughly adjusts for position
vec3_t chromeupvec; // g_chrome t vector in world reference frame
vec3_t chromerightvec; // g_chrome s vector in world reference frame
vec3_t tmp; // vector pointing at bone in world reference frame
VectorScale( m_origin, -1, tmp );
tmp[0] += g_bonetransform[bone][0][3];
tmp[1] += g_bonetransform[bone][1][3];
tmp[2] += g_bonetransform[bone][2][3];
VectorNormalize( tmp );
CrossProduct( tmp, g_vright, chromeupvec );
VectorNormalize( chromeupvec );
CrossProduct( tmp, chromeupvec, chromerightvec );
VectorNormalize( chromerightvec );
VectorIRotate( chromeupvec, g_bonetransform[bone], g_chromeup[bone] );
VectorIRotate( chromerightvec, g_bonetransform[bone], g_chromeright[bone] );
g_chromeage[bone] = g_smodels_total;
}
// calc s coord
n = DotProduct( normal, g_chromeright[bone] );
pchrome[0] = (n + 1.0) * 32; // FIX: make this a float
// calc t coord
n = DotProduct( normal, g_chromeup[bone] );
pchrome[1] = (n + 1.0) * 32; // FIX: make this a float
}
/*
================
StudioModel::SetupLighting
set some global variables based on entity position
inputs:
outputs:
g_ambientlight
g_shadelight
================
*/
void StudioModel::SetupLighting ( )
{
int i;
g_ambientlight = 32;
g_shadelight = 192;
g_lightvec[0] = 0;
g_lightvec[1] = 0;
g_lightvec[2] = -1.0;
g_lightcolor[0] = 1.0;
g_lightcolor[1] = 1.0;
g_lightcolor[2] = 1.0;
// TODO: only do it for bones that actually have textures
for (i = 0; i < m_pstudiohdr->numbones; i++)
{
VectorIRotate( g_lightvec, g_bonetransform[i], g_blightvec[i] );
}
}
/*
=================
StudioModel::SetupModel
based on the body part, figure out which mesh it should be using.
inputs:
currententity
outputs:
pstudiomesh
pmdl
=================
*/
void StudioModel::SetupModel ( int bodypart )
{
int index;
if (bodypart > m_pstudiohdr->numbodyparts)
{
// Con_DPrintf ("StudioModel::SetupModel: no such bodypart %d\n", bodypart);
bodypart = 0;
}
mstudiobodyparts_t *pbodypart = (mstudiobodyparts_t *)((byte *)m_pstudiohdr + m_pstudiohdr->bodypartindex) + bodypart;
index = m_bodynum / pbodypart->base;
index = index % pbodypart->nummodels;
m_pmodel = (mstudiomodel_t *)((byte *)m_pstudiohdr + pbodypart->modelindex) + index;
}
/*
================
StudioModel::DrawModel
inputs:
currententity
r_entorigin
================
*/
void StudioModel::DrawModel( )
{
int i;
g_smodels_total++; // render data cache cookie
g_pxformverts = &g_xformverts[0];
g_pvlightvalues = &g_lightvalues[0];
if (m_pstudiohdr->numbodyparts == 0)
return;
glPushMatrix ();
glTranslatef (m_origin[0], m_origin[1], m_origin[2]);
glRotatef (m_angles[1], 0, 0, 1);
glRotatef (m_angles[0], 0, 1, 0);
glRotatef (m_angles[2], 1, 0, 0);
// glShadeModel (GL_SMOOTH);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
SetUpBones ( );
SetupLighting( );
for (i=0 ; i < m_pstudiohdr->numbodyparts ; i++)
{
SetupModel( i );
DrawPoints( );
}
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// glShadeModel (GL_FLAT);
// glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glPopMatrix ();
}
/*
================
================
*/
void StudioModel::DrawPoints ( )
{
int i, j;
mstudiomesh_t *pmesh;
byte *pvertbone;
byte *pnormbone;
vec3_t *pstudioverts;
vec3_t *pstudionorms;
mstudiotexture_t *ptexture;
float *av;
float *lv;
float lv_tmp;
short *pskinref;
pvertbone = ((byte *)m_pstudiohdr + m_pmodel->vertinfoindex);
pnormbone = ((byte *)m_pstudiohdr + m_pmodel->norminfoindex);
ptexture = (mstudiotexture_t *)((byte *)m_ptexturehdr + m_ptexturehdr->textureindex);
pmesh = (mstudiomesh_t *)((byte *)m_pstudiohdr + m_pmodel->meshindex);
pstudioverts = (vec3_t *)((byte *)m_pstudiohdr + m_pmodel->vertindex);
pstudionorms = (vec3_t *)((byte *)m_pstudiohdr + m_pmodel->normindex);
pskinref = (short *)((byte *)m_ptexturehdr + m_ptexturehdr->skinindex);
if (m_skinnum != 0 && m_skinnum < m_ptexturehdr->numskinfamilies)
pskinref += (m_skinnum * m_ptexturehdr->numskinref);
for (i = 0; i < m_pmodel->numverts; i++)
{
VectorTransform (pstudioverts[i], g_bonetransform[pvertbone[i]], g_pxformverts[i]);
}
//
// clip and draw all triangles
//
lv = (float *)g_pvlightvalues;
for (j = 0; j < m_pmodel->nummesh; j++)
{
int flags;
flags = ptexture[pskinref[pmesh[j].skinref]].flags;
for (i = 0; i < pmesh[j].numnorms; i++, lv += 3, pstudionorms++, pnormbone++)
{
Lighting (&lv_tmp, *pnormbone, flags, (float *)pstudionorms);
// FIX: move this check out of the inner loop
if (flags & STUDIO_NF_CHROME)
Chrome( g_chrome[(float (*)[3])lv - g_pvlightvalues], *pnormbone, (float *)pstudionorms );
lv[0] = lv_tmp * g_lightcolor[0];
lv[1] = lv_tmp * g_lightcolor[1];
lv[2] = lv_tmp * g_lightcolor[2];
}
}
glCullFace(GL_FRONT);
for (j = 0; j < m_pmodel->nummesh; j++)
{
float s, t;
short *ptricmds;
pmesh = (mstudiomesh_t *)((byte *)m_pstudiohdr + m_pmodel->meshindex) + j;
ptricmds = (short *)((byte *)m_pstudiohdr + pmesh->triindex);
s = 1.0/(float)ptexture[pskinref[pmesh->skinref]].width;
t = 1.0/(float)ptexture[pskinref[pmesh->skinref]].height;
glBindTexture( GL_TEXTURE_2D, ptexture[pskinref[pmesh->skinref]].index );
if (ptexture[pskinref[pmesh->skinref]].flags & STUDIO_NF_CHROME)
{
while (i = *(ptricmds++))
{
if (i < 0)
{
glBegin( GL_TRIANGLE_FAN );
i = -i;
}
else
{
glBegin( GL_TRIANGLE_STRIP );
}
for( ; i > 0; i--, ptricmds += 4)
{
// FIX: put these in as integer coords, not floats
glTexCoord2f(g_chrome[ptricmds[1]][0]*s, g_chrome[ptricmds[1]][1]*t);
lv = g_pvlightvalues[ptricmds[1]];
glColor4f( lv[0], lv[1], lv[2], 1.0 );
av = g_pxformverts[ptricmds[0]];
glVertex3f(av[0], av[1], av[2]);
}
glEnd( );
}
}
else
{
while (i = *(ptricmds++))
{
if (i < 0)
{
glBegin( GL_TRIANGLE_FAN );
i = -i;
}
else
{
glBegin( GL_TRIANGLE_STRIP );
}
for( ; i > 0; i--, ptricmds += 4)
{
// FIX: put these in as integer coords, not floats
glTexCoord2f(ptricmds[2]*s, ptricmds[3]*t);
lv = g_pvlightvalues[ptricmds[1]];
glColor4f( lv[0], lv[1], lv[2], 1.0 );
av = g_pxformverts[ptricmds[0]];
glVertex3f(av[0], av[1], av[2]);
}
glEnd( );
}
}
}
}

View File

@ -0,0 +1,436 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// updates:
// 1-4-99 fixed file texture load and file read bug
// 2-8-99 fixed demand loaded sequence bug (thanks to Frans 'Otis' Bouma)
////////////////////////////////////////////////////////////////////////
#if defined _MSC_VER && _MSC_VER >= 1400
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif
#pragma warning(disable: 4996) // deprecated functions
#endif
#include <stdio.h>
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include "mathlib.h"
#include "..\..\engine\studio.h"
#include "mdlviewer.h"
#pragma warning( disable : 4244 ) // double to float
////////////////////////////////////////////////////////////////////////
static int g_texnum = 1;
void StudioModel::UploadTexture(mstudiotexture_t *ptexture, byte *data, byte *pal)
{
// unsigned *in, int inwidth, int inheight, unsigned *out, int outwidth, int outheight;
int i, j;
int row1[256], row2[256], col1[256], col2[256];
byte *pix1, *pix2, *pix3, *pix4;
byte *tex, *out;
// convert texture to power of 2
int outwidth, outheight;
for (outwidth = 1; outwidth < ptexture->width; outwidth <<= 1)
;
if (outwidth > 256)
outwidth = 256;
for (outheight = 1; outheight < ptexture->height; outheight <<= 1)
;
if (outheight > 256)
outheight = 256;
tex = out = (byte *)malloc( outwidth * outheight * 4);
for (i = 0; i < outwidth; i++)
{
col1[i] = (i + 0.25) * (ptexture->width / (float)outwidth);
col2[i] = (i + 0.75) * (ptexture->width / (float)outwidth);
}
for (i = 0; i < outheight; i++)
{
row1[i] = (int)((i + 0.25) * (ptexture->height / (float)outheight)) * ptexture->width;
row2[i] = (int)((i + 0.75) * (ptexture->height / (float)outheight)) * ptexture->width;
}
// scale down and convert to 32bit RGB
for (i=0 ; i<outheight ; i++)
{
for (j=0 ; j<outwidth ; j++, out += 4)
{
pix1 = &pal[data[row1[i] + col1[j]] * 3];
pix2 = &pal[data[row1[i] + col2[j]] * 3];
pix3 = &pal[data[row2[i] + col1[j]] * 3];
pix4 = &pal[data[row2[i] + col2[j]] * 3];
out[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0])>>2;
out[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1])>>2;
out[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2])>>2;
out[3] = 0xFF;
}
}
glBindTexture( GL_TEXTURE_2D, g_texnum );
glTexImage2D( GL_TEXTURE_2D, 0, 3/*??*/, outwidth, outheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex );
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// ptexture->width = outwidth;
// ptexture->height = outheight;
ptexture->index = g_texnum;
g_texnum++;
free( tex );
}
studiohdr_t *StudioModel::LoadModel( char *modelname )
{
FILE *fp;
long size;
void *buffer;
// load the model
if( (fp = fopen( modelname, "rb" )) == NULL)
{
printf("unable to open %s\n", modelname );
exit(1);
}
fseek( fp, 0, SEEK_END );
size = ftell( fp );
fseek( fp, 0, SEEK_SET );
buffer = malloc( size );
fread( buffer, size, 1, fp );
int i;
byte *pin;
studiohdr_t *phdr;
mstudiotexture_t *ptexture;
pin = (byte *)buffer;
phdr = (studiohdr_t *)pin;
ptexture = (mstudiotexture_t *)(pin + phdr->textureindex);
if (phdr->textureindex != 0)
{
for (i = 0; i < phdr->numtextures; i++)
{
// strcpy( name, mod->name );
// strcpy( name, ptexture[i].name );
UploadTexture( &ptexture[i], pin + ptexture[i].index, pin + ptexture[i].width * ptexture[i].height + ptexture[i].index );
}
}
// UNDONE: free texture memory
fclose( fp );
return (studiohdr_t *)buffer;
}
studioseqhdr_t *StudioModel::LoadDemandSequences( char *modelname )
{
FILE *fp;
long size;
void *buffer;
// load the model
if( (fp = fopen( modelname, "rb" )) == NULL)
{
printf("unable to open %s\n", modelname );
exit(1);
}
fseek( fp, 0, SEEK_END );
size = ftell( fp );
fseek( fp, 0, SEEK_SET );
buffer = malloc( size );
fread( buffer, size, 1, fp );
fclose( fp );
return (studioseqhdr_t *)buffer;
}
void StudioModel::Init( char *modelname )
{
m_pstudiohdr = LoadModel( modelname );
// preload textures
if (m_pstudiohdr->numtextures == 0)
{
char texturename[256];
strcpy( texturename, modelname );
strcpy( &texturename[strlen(texturename) - 4], "T.mdl" );
m_ptexturehdr = LoadModel( texturename );
}
else
{
m_ptexturehdr = m_pstudiohdr;
}
// preload animations
if (m_pstudiohdr->numseqgroups > 1)
{
for (int i = 1; i < m_pstudiohdr->numseqgroups; i++)
{
char seqgroupname[256];
strcpy( seqgroupname, modelname );
sprintf( &seqgroupname[strlen(seqgroupname) - 4], "%02d.mdl", i );
m_panimhdr[i] = LoadDemandSequences( seqgroupname );
}
}
}
////////////////////////////////////////////////////////////////////////
int StudioModel::GetSequence( )
{
return m_sequence;
}
int StudioModel::SetSequence( int iSequence )
{
if (iSequence > m_pstudiohdr->numseq)
iSequence = 0;
if (iSequence < 0)
iSequence = m_pstudiohdr->numseq-1;
m_sequence = iSequence;
m_frame = 0;
return m_sequence;
}
void StudioModel::ExtractBbox( float *mins, float *maxs )
{
mstudioseqdesc_t *pseqdesc;
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pstudiohdr + m_pstudiohdr->seqindex);
mins[0] = pseqdesc[ m_sequence ].bbmin[0];
mins[1] = pseqdesc[ m_sequence ].bbmin[1];
mins[2] = pseqdesc[ m_sequence ].bbmin[2];
maxs[0] = pseqdesc[ m_sequence ].bbmax[0];
maxs[1] = pseqdesc[ m_sequence ].bbmax[1];
maxs[2] = pseqdesc[ m_sequence ].bbmax[2];
}
void StudioModel::GetSequenceInfo( float *pflFrameRate, float *pflGroundSpeed )
{
mstudioseqdesc_t *pseqdesc;
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pstudiohdr + m_pstudiohdr->seqindex) + (int)m_sequence;
if (pseqdesc->numframes > 1)
{
*pflFrameRate = 256 * pseqdesc->fps / (pseqdesc->numframes - 1);
*pflGroundSpeed = sqrt( pseqdesc->linearmovement[0]*pseqdesc->linearmovement[0]+ pseqdesc->linearmovement[1]*pseqdesc->linearmovement[1]+ pseqdesc->linearmovement[2]*pseqdesc->linearmovement[2] );
*pflGroundSpeed = *pflGroundSpeed * pseqdesc->fps / (pseqdesc->numframes - 1);
}
else
{
*pflFrameRate = 256.0;
*pflGroundSpeed = 0.0;
}
}
float StudioModel::SetController( int iController, float flValue )
{
mstudiobonecontroller_t *pbonecontroller = (mstudiobonecontroller_t *)((byte *)m_pstudiohdr + m_pstudiohdr->bonecontrollerindex);
// find first controller that matches the index
int i;
for (i = 0; i < m_pstudiohdr->numbonecontrollers; i++, pbonecontroller++)
{
if (pbonecontroller->index == iController)
break;
}
if (i >= m_pstudiohdr->numbonecontrollers)
return flValue;
// wrap 0..360 if it's a rotational controller
if (pbonecontroller->type & (STUDIO_XR | STUDIO_YR | STUDIO_ZR))
{
// ugly hack, invert value if end < start
if (pbonecontroller->end < pbonecontroller->start)
flValue = -flValue;
// does the controller not wrap?
if (pbonecontroller->start + 359.0 >= pbonecontroller->end)
{
if (flValue > ((pbonecontroller->start + pbonecontroller->end) / 2.0) + 180)
flValue = flValue - 360;
if (flValue < ((pbonecontroller->start + pbonecontroller->end) / 2.0) - 180)
flValue = flValue + 360;
}
else
{
if (flValue > 360)
flValue = flValue - (int)(flValue / 360.0) * 360.0;
else if (flValue < 0)
flValue = flValue + (int)((flValue / -360.0) + 1) * 360.0;
}
}
int setting = 255 * (flValue - pbonecontroller->start) / (pbonecontroller->end - pbonecontroller->start);
if (setting < 0) setting = 0;
if (setting > 255) setting = 255;
m_controller[iController] = setting;
return setting * (1.0 / 255.0) * (pbonecontroller->end - pbonecontroller->start) + pbonecontroller->start;
}
float StudioModel::SetMouth( float flValue )
{
mstudiobonecontroller_t *pbonecontroller = (mstudiobonecontroller_t *)((byte *)m_pstudiohdr + m_pstudiohdr->bonecontrollerindex);
// find first controller that matches the mouth
for (int i = 0; i < m_pstudiohdr->numbonecontrollers; i++, pbonecontroller++)
{
if (pbonecontroller->index == 4)
break;
}
// wrap 0..360 if it's a rotational controller
if (pbonecontroller->type & (STUDIO_XR | STUDIO_YR | STUDIO_ZR))
{
// ugly hack, invert value if end < start
if (pbonecontroller->end < pbonecontroller->start)
flValue = -flValue;
// does the controller not wrap?
if (pbonecontroller->start + 359.0 >= pbonecontroller->end)
{
if (flValue > ((pbonecontroller->start + pbonecontroller->end) / 2.0) + 180)
flValue = flValue - 360;
if (flValue < ((pbonecontroller->start + pbonecontroller->end) / 2.0) - 180)
flValue = flValue + 360;
}
else
{
if (flValue > 360)
flValue = flValue - (int)(flValue / 360.0) * 360.0;
else if (flValue < 0)
flValue = flValue + (int)((flValue / -360.0) + 1) * 360.0;
}
}
int setting = 64 * (flValue - pbonecontroller->start) / (pbonecontroller->end - pbonecontroller->start);
if (setting < 0) setting = 0;
if (setting > 64) setting = 64;
m_mouth = setting;
return setting * (1.0 / 64.0) * (pbonecontroller->end - pbonecontroller->start) + pbonecontroller->start;
}
float StudioModel::SetBlending( int iBlender, float flValue )
{
mstudioseqdesc_t *pseqdesc;
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pstudiohdr + m_pstudiohdr->seqindex) + (int)m_sequence;
if (pseqdesc->blendtype[iBlender] == 0)
return flValue;
if (pseqdesc->blendtype[iBlender] & (STUDIO_XR | STUDIO_YR | STUDIO_ZR))
{
// ugly hack, invert value if end < start
if (pseqdesc->blendend[iBlender] < pseqdesc->blendstart[iBlender])
flValue = -flValue;
// does the controller not wrap?
if (pseqdesc->blendstart[iBlender] + 359.0 >= pseqdesc->blendend[iBlender])
{
if (flValue > ((pseqdesc->blendstart[iBlender] + pseqdesc->blendend[iBlender]) / 2.0) + 180)
flValue = flValue - 360;
if (flValue < ((pseqdesc->blendstart[iBlender] + pseqdesc->blendend[iBlender]) / 2.0) - 180)
flValue = flValue + 360;
}
}
int setting = 255 * (flValue - pseqdesc->blendstart[iBlender]) / (pseqdesc->blendend[iBlender] - pseqdesc->blendstart[iBlender]);
if (setting < 0) setting = 0;
if (setting > 255) setting = 255;
m_blending[iBlender] = setting;
return setting * (1.0 / 255.0) * (pseqdesc->blendend[iBlender] - pseqdesc->blendstart[iBlender]) + pseqdesc->blendstart[iBlender];
}
int StudioModel::SetBodygroup( int iGroup, int iValue )
{
if (iGroup > m_pstudiohdr->numbodyparts)
return -1;
mstudiobodyparts_t *pbodypart = (mstudiobodyparts_t *)((byte *)m_pstudiohdr + m_pstudiohdr->bodypartindex) + iGroup;
int iCurrent = (m_bodynum / pbodypart->base) % pbodypart->nummodels;
if (iValue >= pbodypart->nummodels)
return iCurrent;
m_bodynum = (m_bodynum - (iCurrent * pbodypart->base) + (iValue * pbodypart->base));
return iValue;
}
int StudioModel::SetSkin( int iValue )
{
if (iValue < m_pstudiohdr->numskinfamilies)
{
return m_skinnum;
}
m_skinnum = iValue;
return iValue;
}

View File

@ -0,0 +1,270 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
/*
mkmovie.c
converts a movie file from the game engine to a collection of bitmaps
*/
#include "windows.h"
#include "cmdlib.h"
#include "movie.h"
//------------------------------------------------------------ Globals
#define MAJOR_VERSION 1
#define MINOR_VERSION 0
#define MAX_FILE 256
char *basename;
int framecnt;
const char *const formatStr = "Format: mkmovie [-basename <name>] <filename>";
//------------------------------------------------------------ Types
typedef struct
{
byte b;
byte g;
byte r;
} winColor24;
//------------------------------------------------------------ Functions
void PrintError( const char *pStr )
{
puts( pStr );
exit( 5 );
}
void ProcessMFRMBlock( HANDLE hf, movieblockheader_t *pHeader )
{
HANDLE hout;
BITMAPFILEHEADER hdr;
BITMAPINFOHEADER bi;
DWORD imagesize, bytesread, datasize;
long rowbytes, pelsize;
short row;
byte *hp, *data, *movie;
movieframe_t frame;
winColor24 *pRGB;
char outfilename[ MAX_FILE ];
// Read in header
if( !ReadFile( hf, (void *) &frame, sizeof(movieframe_t), &bytesread, NULL ) )
PrintError( "Error reading MFRM header." );
if( !bytesread )
PrintError( "Unexpected EOF found." );
// Read in data
datasize = pHeader->size - sizeof(movieframe_t);
data = (byte *) LocalAlloc( LPTR, datasize );
if( !ReadFile( hf, (void *) data, datasize, &bytesread, NULL ) )
PrintError( "Error reading MFRM data." );
if( !bytesread )
PrintError( "Unexpected EOF found." );
// NOTE: Writing 24bpp images
imagesize = frame.width * frame.height * 3;
// make the new data
movie = (byte *) LocalAlloc( LPTR, imagesize );
pRGB = (winColor24 *) movie;
if (frame.depth == 24)
pelsize = 3;
else
pelsize = 2;
// the 24 bit images from gl are already reversed
if (frame.depth == 24)
{
rowbytes = frame.width * pelsize;
hp = (byte *) data;
} else {
rowbytes = frame.width * pelsize;
hp = (byte *) data + datasize;
}
// Flip the bitmap vertically while we write it.
for( row=0; row<frame.height; row++ )
{
int i;
// back the pointer up a row;
if ( frame.depth != 24 )
{
hp -= rowbytes;
for( i=0; i<frame.width; i++, hp += pelsize, pRGB++ )
{
// Convert to 24bpp, swap r and b
if( frame.depth == 15 )
{
unsigned short nc = *(short *) hp;
pRGB->r = ( nc & 0x7c00 ) >> 7;
pRGB->g = ( nc & 0x03e0 ) >> 2;
pRGB->b = ( nc & 0x001f ) << 3;
}
else if ( frame.depth == 16 )
{
unsigned short nc = *(short *) hp;
pRGB->r = ( nc & 0xf800 ) >> 8;
pRGB->g = ( nc & 0x07e0 ) >> 3;
pRGB->b = ( nc & 0x001f ) << 3;
}
}
hp -= rowbytes;
}
else // 24-bit frames, just swap & copy
{
for( i=0; i<frame.width; i++, hp += pelsize, pRGB++ )
{
pRGB->r = hp[0]; // winColor24 is declared in reverse, so swapping is automatic
pRGB->g = hp[1];
pRGB->b = hp[2];
}
}
}
// Create the output file
sprintf( outfilename, "%s%04d.bmp", basename, framecnt++ );
printf( "Creating bitmap %s.\n", outfilename );
hout = CreateFile( outfilename, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( hout == INVALID_HANDLE_VALUE )
PrintError( "Couldn't create bitmap file for frame." );
// create file header
hdr.bfType = 0x4d42; // 'BM'
hdr.bfSize = (DWORD) ( sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + imagesize );
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD) ( sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) );
if( !WriteFile( hout, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &bytesread, NULL ) )
PrintError( "Couldn't write file header to framebitmap." );
// bitmap header
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = frame.width;
bi.biHeight = frame.height;
bi.biPlanes = 1;
bi.biBitCount = 24;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
if( !WriteFile( hout, (LPVOID) &bi, sizeof(BITMAPINFOHEADER), (LPDWORD) &bytesread, NULL ) )
PrintError( "Couldn't write bitmap header to frame bitmap." );
// bitmap data
if( !WriteFile( hout, (LPVOID) movie, imagesize, (LPDWORD) &bytesread, NULL ) )
PrintError( "Couldn't write bitmap data to frame bitmap." );
// clean up
if( !CloseHandle( hout ) )
PrintError( "Couldn't close bitmap file for frame." );
LocalFree( (HLOCAL) data );
LocalFree( (HLOCAL) movie );
}
void ProcessMovieFile( const char *pFilename )
{
HANDLE hf;
DWORD bytesread;
movieblockheader_t header;
qboolean eof = false;
printf( "Processing movie %s:\n", pFilename );
hf = CreateFile( pFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( hf == INVALID_HANDLE_VALUE )
PrintError( "Couldn't open movie file.\n" );
while( !eof )
{
if( !ReadFile( hf, (void *) &header, sizeof(movieblockheader_t), &bytesread, NULL ) )
PrintError( "Error reading from movie file.\n" );
// Check for end of file
if( !bytesread )
eof = true;
else
{
switch( header.tag )
{
case 'MFRM':
ProcessMFRMBlock( hf, &header );
break;
default:
PrintError( "Unknown block tag.\n" );
}
}
}
if( !CloseHandle( hf ) )
PrintError( "Error closing movie file.\n" );
printf( "Done processing movie.\n" );
}
void main( int argc, char *argv[] )
{
int i;
printf( "mkmovie v%d.%d (%s) Copyright 1997, valve software L.L.C\n", MAJOR_VERSION, MINOR_VERSION, __DATE__ );
if( argc < 2 )
PrintError( formatStr );
basename = NULL;
for( i=0; i<argc; i++ )
{
if( *argv[i] == '-' )
{
if( !strcmp( argv[i], "-basename" ) )
{
if( i >= argc - 1 )
PrintError( formatStr );
basename = argv[ ++i ];
}
}
}
if( *argv[ argc - 1 ] == '-' )
PrintError( formatStr );
if( !basename )
basename = argv[ argc - 1 ];
framecnt = 0;
ProcessMovieFile( argv[ argc - 1 ] );
}

Binary file not shown.

View File

@ -0,0 +1,19 @@
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#if !defined ( PROCINFOH )
#define PROCINFOH
#ifdef _WIN32
#ifndef __MINGW32__
#pragma once
#endif /* not __MINGW32__ */
#endif
int PROC_GetSpeed( void );
int PROC_IsMMX( void );
#endif // PROCINFOH

267
hlsdk/utils/qbsp2/bsp5.h Normal file
View File

@ -0,0 +1,267 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// bsp5.h
#include "cmdlib.h"
#include "mathlib.h"
#include "bspfile.h"
#include "threads.h"
//#define ON_EPSILON 0.05
#define BOGUS_RANGE 18000
// the exact bounding box of the brushes is expanded some for the headnode
// volume. is this still needed?
#define SIDESPACE 24
//============================================================================
typedef struct
{
int numpoints;
vec3_t points[8]; // variable sized
} winding_t;
#define MAX_POINTS_ON_WINDING 128
winding_t *BaseWindingForPlane (dplane_t *p);
winding_t *NewWinding (int points);
void FreeWinding (winding_t *w);
winding_t *CopyWinding (winding_t *w);
winding_t *ClipWinding (winding_t *in, dplane_t *split, qboolean keepon);
void DivideWinding (winding_t *in, dplane_t *split, winding_t **front, winding_t **back);
//============================================================================
#define MAXEDGES 48 // 32
#define MAXPOINTS 28 // don't let a base face get past this
// because it can be split more later
typedef struct face_s
{
struct face_s *next;
int planenum;
int texturenum;
int contents; // contents in front of face
struct face_s *original; // face on node
int outputnumber; // only valid for original faces after
// write surfaces
int numpoints;
vec3_t pts[MAXEDGES]; // FIXME: change to use winding_t
} face_t;
typedef struct surface_s
{
struct surface_s *next;
int planenum;
vec3_t mins, maxs;
struct node_s *onnode; // true if surface has already been used
// as a splitting node
face_t *faces; // links to all the faces on either side of the surf
} surface_t;
typedef struct
{
vec3_t mins, maxs;
surface_t *surfaces;
} surfchain_t;
//
// there is a node_t structure for every node and leaf in the bsp tree
//
#define PLANENUM_LEAF -1
typedef struct node_s
{
surface_t *surfaces;
vec3_t mins,maxs; // bounding volume of portals;
// information for decision nodes
int planenum; // -1 = leaf node
struct node_s *children[2]; // only valid for decision nodes
face_t *faces; // decision nodes only, list for both sides
// information for leafs
int contents; // leaf nodes (0 for decision nodes)
face_t **markfaces; // leaf nodes only, point to node faces
struct portal_s *portals;
int visleafnum; // -1 = solid
int valid; // for flood filling
int occupied; // light number in leaf for outside filling
} node_t;
#define NUM_HULLS 4
face_t *NewFaceFromFace (face_t *in);
void SplitFace (face_t *in, dplane_t *split, face_t **front, face_t **back);
//=============================================================================
// solidbsp.c
void DivideFacet (face_t *in, dplane_t *split, face_t **front, face_t **back);
void CalcSurfaceInfo (surface_t *surf);
void SubdivideFace (face_t *f, face_t **prevptr);
node_t *SolidBSP (surfchain_t *surfhead);
//=============================================================================
// merge.c
void MergePlaneFaces (surface_t *plane);
face_t *MergeFaceToList (face_t *face, face_t *list);
face_t *FreeMergeListScraps (face_t *merged);
void MergeAll (surface_t *surfhead);
//=============================================================================
// surfaces.c
extern int c_cornerverts;
extern int c_tryedges;
extern face_t *edgefaces[MAX_MAP_EDGES][2];
extern int firstmodeledge;
extern int firstmodelface;
void SubdivideFaces (surface_t *surfhead);
surfchain_t *GatherNodeFaces (node_t *headnode);
void MakeFaceEdges (node_t *headnode);
//=============================================================================
// portals.c
typedef struct portal_s
{
dplane_t plane;
node_t *onnode; // NULL = outside box
node_t *nodes[2]; // [0] = front side of plane
struct portal_s *next[2];
winding_t *winding;
} portal_t;
extern node_t outside_node; // portals outside the world face this
void AddPortalToNodes (portal_t *p, node_t *front, node_t *back);
void RemovePortalFromNode (portal_t *portal, node_t *l);
void MakeHeadnodePortals (node_t *node, vec3_t mins, vec3_t maxs);
void WritePortalfile (node_t *headnode);
//=============================================================================
// region.c
void GrowNodeRegions (node_t *headnode);
//=============================================================================
// tjunc.c
void tjunc (node_t *headnode);
//=============================================================================
// writebsp.c
void WriteNodePlanes (node_t *headnode);
void WriteClipNodes (node_t *headnode);
void WriteDrawNodes (node_t *headnode);
void BeginBSPFile (void);
void FinishBSPFile (void);
//=============================================================================
// draw.c
extern vec3_t draw_mins, draw_maxs;
void Draw_ClearBounds (void);
void Draw_AddToBounds (vec3_t v);
void Draw_DrawFace (face_t *f);
void Draw_ClearWindow (void);
void Draw_SetRed (void);
void Draw_SetGrey (void);
void Draw_SetBlack (void);
void DrawPoint (vec3_t v);
void Draw_SetColor (int c);
void SetColor (int c);
void DrawPortal (portal_t *p);
void DrawLeaf (node_t *l, int color);
void DrawWinding (winding_t *w);
void DrawTri (vec3_t p1, vec3_t p2, vec3_t p3);
//=============================================================================
// outside.c
node_t *FillOutside (node_t *node, qboolean leakfile);
//=============================================================================
extern qboolean drawflag;
extern qboolean nofill;
extern qboolean notjunc;
extern qboolean verbose;
extern qboolean nogfx;
extern qboolean leakonly;
extern qboolean watervis;
extern int subdivide_size;
extern int hullnum;
void qprintf (char *fmt, ...); // only prints if verbose
extern int valid;
extern char portfilename[1024];
extern char bspfilename[1024];
extern char pointfilename[1024];
extern qboolean worldmodel;
extern face_t *validfaces[MAX_MAP_PLANES];
surfchain_t *SurflistFromValidFaces (void);
// misc functions
face_t *AllocFace (void);
void FreeFace (face_t *f);
struct portal_s *AllocPortal (void);
void FreePortal (struct portal_s *p);
surface_t *AllocSurface (void);
void FreeSurface (surface_t *s);
node_t *AllocNode (void);
//=============================================================================
// cull.c
void CullStuff (void);

28
hlsdk/utils/qbsp2/cull.c Normal file
View File

@ -0,0 +1,28 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// cull.c
#include "bsp5.h"
/*
removes unused planes and nodes
*/
/*
=============
CullStuff
=============
*/
void CullStuff (void)
{
}

164
hlsdk/utils/qbsp2/gldraw.c Normal file
View File

@ -0,0 +1,164 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include "bsp5.h"
vec3_t draw_mins, draw_maxs;
void Draw_ClearBounds (void)
{
}
void Draw_AddToBounds (vec3_t v)
{
}
void Draw_DrawFace (face_t *f)
{
int i;
if (!drawflag)
return;
glColor4f (0,0,0,0.5);
glBegin (GL_LINE_LOOP);
for (i=0 ; i<f->numpoints ; i++)
glVertex3f (f->pts[i][0], f->pts[i][1], f->pts[i][2]);
glEnd ();
glColor4f (0,1,0,0.3);
glBegin (GL_POLYGON);
for (i=0 ; i<f->numpoints ; i++)
glVertex3f (f->pts[i][0], f->pts[i][1], f->pts[i][2]);
glEnd ();
glFlush ();
}
#define WIN_SIZE 512
void InitWindow (void)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGB);
auxInitPosition (0, 0, WIN_SIZE, WIN_SIZE);
auxInitWindow ("qbsp");
}
void Draw_ClearWindow (void)
{
static int init;
int w, h, g;
float mx, my;
if (!drawflag)
return;
if (!init)
{
init = true;
InitWindow ();
}
glClearColor (1,0.8,0.8,0);
glClear (GL_COLOR_BUFFER_BIT);
w = (draw_maxs[0] - draw_mins[0]);
h = (draw_maxs[1] - draw_mins[1]);
mx = draw_mins[0] + w/2;
my = draw_mins[1] + h/2;
g = w > h ? w : h;
glLoadIdentity ();
gluPerspective (90, 1, 2, 16384);
gluLookAt (mx, my, draw_maxs[2] + g/2, mx , my, draw_maxs[2], 0, 1, 0);
glColor4f (0,0,0,1);
// glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glDisable (GL_DEPTH_TEST);
glDisable (GL_CULL_FACE);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#if 0
glBegin (GL_POLYGON);
glVertex3f (mx, my, draw_mins[2]);
glVertex3f (mx, my+100, draw_mins[2]);
glVertex3f (mx, my+100, draw_mins[2]+100);
glVertex3f (mx, my, draw_mins[2]+100);
glEnd ();
#endif
glFlush ();
}
void Draw_SetRed (void)
{
if (!drawflag)
return;
glColor3f (1,0,0);
}
void Draw_SetGrey (void)
{
if (!drawflag)
return;
glColor3f (0.5,0.5,0.5);
}
void Draw_SetBlack (void)
{
if (!drawflag)
return;
glColor3f (0,0,0);
}
void DrawPoint (vec3_t v)
{
}
void DrawLeaf (node_t *l, int color)
{
}
void DrawWinding (winding_t *w)
{
int i;
if (!drawflag)
return;
glBegin (GL_POLYGON);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->points[i][0], w->points[i][1], w->points[i][2]);
glEnd ();
glFlush ();
}
void DrawTri (vec3_t p1, vec3_t p2, vec3_t p3)
{
}
void DrawPortal (portal_t *portal)
{
DrawWinding (portal->winding);
}

282
hlsdk/utils/qbsp2/merge.c Normal file
View File

@ -0,0 +1,282 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// merge.c
#include "bsp5.h"
// #define CONTINUOUS_EPSILON 0.001
#define CONTINUOUS_EPSILON ON_EPSILON
/*
================
CheckColinear
================
*/
void CheckColinear (face_t *f)
{
int i, j;
vec3_t v1, v2;
for (i=0 ; i<f->numpoints ;i++)
{
// skip the point if the vector from the previous point is the same
// as the vector to the next point
j = (i - 1 < 0) ? f->numpoints - 1 : i - 1;
VectorSubtract (f->pts[i], f->pts[j], v1);
VectorNormalize (v1);
j = (i + 1 == f->numpoints) ? 0 : i + 1;
VectorSubtract (f->pts[j], f->pts[i], v2);
VectorNormalize (v2);
if (VectorCompare (v1, v2))
Error ("Colinear edge");
}
}
/*
=============
TryMerge
If two polygons share a common edge and the edges that meet at the
common points are both inside the other polygons, merge them
Returns NULL if the faces couldn't be merged, or the new face.
The originals will NOT be freed.
=============
*/
face_t *TryMerge (face_t *f1, face_t *f2)
{
vec_t *p1, *p2, *p3, *p4, *back;
face_t *newf;
int i, j, k, l;
vec3_t normal, delta, planenormal;
vec_t dot;
dplane_t *plane;
qboolean keep1, keep2;
if (f1->numpoints == -1 || f2->numpoints == -1)
return NULL;
if (f1->texturenum != f2->texturenum)
return NULL;
if (f1->contents != f2->contents)
return NULL;
//
// find a common edge
//
p1 = p2 = NULL; // stop compiler warning
j = 0; //
for (i=0 ; i<f1->numpoints ; i++)
{
p1 = f1->pts[i];
p2 = f1->pts[(i+1)%f1->numpoints];
for (j=0 ; j<f2->numpoints ; j++)
{
p3 = f2->pts[j];
p4 = f2->pts[(j+1)%f2->numpoints];
for (k=0 ; k<3 ; k++)
{
if (fabs(p1[k] - p4[k]) > EQUAL_EPSILON)
break;
if (fabs(p2[k] - p3[k]) > EQUAL_EPSILON)
break;
}
if (k==3)
break;
}
if (j < f2->numpoints)
break;
}
if (i == f1->numpoints)
return NULL; // no matching edges
//
// check slope of connected lines
// if the slopes are colinear, the point can be removed
//
plane = &dplanes[f1->planenum];
VectorCopy (plane->normal, planenormal);
back = f1->pts[(i+f1->numpoints-1)%f1->numpoints];
VectorSubtract (p1, back, delta);
CrossProduct (planenormal, delta, normal);
VectorNormalize (normal);
back = f2->pts[(j+2)%f2->numpoints];
VectorSubtract (back, p1, delta);
dot = DotProduct (delta, normal);
if (dot > CONTINUOUS_EPSILON)
return NULL; // not a convex polygon
keep1 = dot < -CONTINUOUS_EPSILON;
back = f1->pts[(i+2)%f1->numpoints];
VectorSubtract (back, p2, delta);
CrossProduct (planenormal, delta, normal);
VectorNormalize (normal);
back = f2->pts[(j+f2->numpoints-1)%f2->numpoints];
VectorSubtract (back, p2, delta);
dot = DotProduct (delta, normal);
if (dot > CONTINUOUS_EPSILON)
return NULL; // not a convex polygon
keep2 = dot < -CONTINUOUS_EPSILON;
//
// build the new polygon
//
if (f1->numpoints + f2->numpoints > MAXEDGES)
{
// Error ("TryMerge: too many edges!");
return NULL;
}
newf = NewFaceFromFace (f1);
// copy first polygon
for (k=(i+1)%f1->numpoints ; k != i ; k=(k+1)%f1->numpoints)
{
if (k==(i+1)%f1->numpoints && !keep2)
continue;
VectorCopy (f1->pts[k], newf->pts[newf->numpoints]);
newf->numpoints++;
}
// copy second polygon
for (l= (j+1)%f2->numpoints ; l != j ; l=(l+1)%f2->numpoints)
{
if (l==(j+1)%f2->numpoints && !keep1)
continue;
VectorCopy (f2->pts[l], newf->pts[newf->numpoints]);
newf->numpoints++;
}
return newf;
}
/*
===============
MergeFaceToList
===============
*/
qboolean mergedebug;
face_t *MergeFaceToList (face_t *face, face_t *list)
{
face_t *newf, *f;
for (f=list ; f ; f=f->next)
{
//CheckColinear (f);
if (mergedebug)
{
Draw_ClearWindow ();
Draw_DrawFace (face);
Draw_DrawFace (f);
Draw_SetBlack ();
}
newf = TryMerge (face, f);
if (!newf)
continue;
FreeFace (face);
f->numpoints = -1; // merged out
return MergeFaceToList (newf, list);
}
// didn't merge, so add at start
face->next = list;
return face;
}
/*
===============
FreeMergeListScraps
===============
*/
face_t *FreeMergeListScraps (face_t *merged)
{
face_t *head, *next;
head = NULL;
for ( ; merged ; merged = next)
{
next = merged->next;
if (merged->numpoints == -1)
FreeFace (merged);
else
{
merged->next = head;
head = merged;
}
}
return head;
}
/*
===============
MergePlaneFaces
===============
*/
void MergePlaneFaces (surface_t *plane)
{
face_t *f1, *next;
face_t *merged;
merged = NULL;
for (f1 = plane->faces ; f1 ; f1 = next)
{
next = f1->next;
merged = MergeFaceToList (f1, merged);
}
// chain all of the non-empty faces to the plane
plane->faces = FreeMergeListScraps (merged);
}
/*
============
MergeAll
============
*/
void MergeAll (surface_t *surfhead)
{
surface_t *surf;
int mergefaces;
face_t *f;
qprintf ("---- MergeAll ----\n");
mergefaces = 0;
for (surf = surfhead ; surf ; surf=surf->next)
{
MergePlaneFaces (surf);
Draw_ClearWindow ();
for (f=surf->faces ; f ; f=f->next)
{
Draw_DrawFace (f);
mergefaces++;
}
}
qprintf ("%i mergefaces\n", mergefaces);
}

View File

@ -0,0 +1,176 @@
# Microsoft Developer Studio Project File - Name="qbsp2" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=qbsp2 - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "qbsp2.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "qbsp2.mak" CFG="qbsp2 - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "qbsp2 - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "qbsp2 - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/SDKSrc/Tools/utils/qbsp2", VUGBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "qbsp2 - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\qbsp2___"
# PROP BASE Intermediate_Dir ".\qbsp2___"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\release"
# PROP Intermediate_Dir ".\release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /MT /GX /O2 /I "..\..\common" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "DOUBLEVEC_T" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "qbsp2 - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\qbsp2__0"
# PROP BASE Intermediate_Dir ".\qbsp2__0"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\debug"
# PROP Intermediate_Dir ".\debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /MT /Gm /GX /ZI /Od /I "..\..\common" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "DOUBLEVEC_T" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
# ADD LINK32 opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
!ENDIF
# Begin Target
# Name "qbsp2 - Win32 Release"
# Name "qbsp2 - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\bsp5.h
# End Source File
# Begin Source File
SOURCE=..\..\common\bspfile.c
# End Source File
# Begin Source File
SOURCE=..\..\common\cmdlib.c
# End Source File
# Begin Source File
SOURCE=..\gldraw.c
# End Source File
# Begin Source File
SOURCE=..\..\common\mathlib.c
# End Source File
# Begin Source File
SOURCE=..\merge.c
# End Source File
# Begin Source File
SOURCE=..\outside.c
# End Source File
# Begin Source File
SOURCE=..\portals.c
# End Source File
# Begin Source File
SOURCE=..\qbsp.c
# End Source File
# Begin Source File
SOURCE=..\..\common\scriplib.c
# End Source File
# Begin Source File
SOURCE=..\solidbsp.c
# End Source File
# Begin Source File
SOURCE=..\surfaces.c
# End Source File
# Begin Source File
SOURCE=..\..\common\threads.c
# End Source File
# Begin Source File
SOURCE=..\tjunc.c
# End Source File
# Begin Source File
SOURCE=..\writebsp.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=..\..\common\bspfile.h
# End Source File
# Begin Source File
SOURCE=..\..\common\cmdlib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\mathlib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\scriplib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\threads.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "qbsp2"=.\qbsp2.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@ -0,0 +1,434 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="qbsp2"
ProjectGUID="{4E9A1E80-43D6-4414-B49C-614D629F524B}"
SccProjectName="&quot;$/SDKSrc/Tools/utils/qbsp2&quot;, VUGBAAAA"
SccLocalPath=".">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\release"
IntermediateDirectory=".\release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;DOUBLEVEC_T"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\release/qbsp2.pch"
AssemblerListingLocation=".\release/"
ObjectFile=".\release/"
ProgramDataBaseFileName=".\release/"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib glaux.lib odbc32.lib odbccp32.lib"
OutputFile=".\release/qbsp2.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\release/qbsp2.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\release/qbsp2.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\debug"
IntermediateDirectory=".\debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;DOUBLEVEC_T"
RuntimeLibrary="0"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\debug/qbsp2.pch"
AssemblerListingLocation=".\debug/"
ObjectFile=".\debug/"
ProgramDataBaseFileName=".\debug/"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib glaux.lib odbc32.lib odbccp32.lib"
OutputFile=".\debug/qbsp2.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\debug/qbsp2.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\debug/qbsp2.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90">
<File
RelativePath="..\bsp5.h">
</File>
<File
RelativePath="..\..\common\bspfile.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\cmdlib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\gldraw.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\mathlib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\merge.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\outside.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\portals.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\qbsp.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\solidbsp.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\surfaces.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\threads.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\tjunc.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\writebsp.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd">
<File
RelativePath="..\..\common\bspfile.h">
</File>
<File
RelativePath="..\..\common\cmdlib.h">
</File>
<File
RelativePath="..\..\common\mathlib.h">
</File>
<File
RelativePath="..\..\common\scriplib.h">
</File>
<File
RelativePath="..\..\common\threads.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,575 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="qbsp2"
ProjectGUID="{4E9A1E80-43D6-4414-B49C-614D629F524B}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\release"
IntermediateDirectory=".\release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\release/qbsp2.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;DOUBLEVEC_T"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\release/qbsp2.pch"
AssemblerListingLocation=".\release/"
ObjectFile=".\release/"
ProgramDataBaseFileName=".\release/"
SuppressStartupBanner="true"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib glaux.lib odbc32.lib odbccp32.lib"
OutputFile=".\release/qbsp2.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\release/qbsp2.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\debug"
IntermediateDirectory=".\debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\debug/qbsp2.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;DOUBLEVEC_T"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\debug/qbsp2.pch"
AssemblerListingLocation=".\debug/"
ObjectFile=".\debug/"
ProgramDataBaseFileName=".\debug/"
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib glaux.lib odbc32.lib odbccp32.lib"
OutputFile=".\debug/qbsp2.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\debug/qbsp2.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
>
<File
RelativePath="..\bsp5.h"
>
</File>
<File
RelativePath="..\..\common\bspfile.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\cmdlib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\gldraw.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\mathlib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\merge.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\outside.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\portals.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\qbsp.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\solidbsp.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\surfaces.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\threads.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\tjunc.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\writebsp.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd"
>
<File
RelativePath="..\..\common\bspfile.h"
>
</File>
<File
RelativePath="..\..\common\cmdlib.h"
>
</File>
<File
RelativePath="..\..\common\mathlib.h"
>
</File>
<File
RelativePath="..\..\common\scriplib.h"
>
</File>
<File
RelativePath="..\..\common\threads.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,59 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "bsp5.h"
void Draw_ClearBounds (void)
{
}
void Draw_AddToBounds (vec3_t v)
{
}
void Draw_DrawFace (face_t *f)
{
}
void Draw_ClearWindow (void)
{
}
void Draw_SetRed (void)
{
}
void Draw_SetGrey (void)
{
}
void Draw_SetBlack (void)
{
}
void DrawPoint (vec3_t v)
{
}
void DrawLeaf (node_t *l, int color)
{
}
void DrawWinding (winding_t *w)
{
}
void DrawTri (vec3_t p1, vec3_t p2, vec3_t p3)
{
}
void DrawPortal (portal_t *portal)
{
}

421
hlsdk/utils/qbsp2/outside.c Normal file
View File

@ -0,0 +1,421 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "bsp5.h"
int outleafs;
int valid;
int c_falsenodes;
int c_free_faces;
int c_keep_faces;
/*
===========
PointInLeaf
===========
*/
node_t *PointInLeaf (node_t *node, vec3_t point)
{
vec_t d;
if (node->contents)
return node;
d = DotProduct (dplanes[node->planenum].normal, point) - dplanes[node->planenum]. dist;
if (d > 0)
return PointInLeaf (node->children[0], point);
return PointInLeaf (node->children[1], point);
}
/*
===========
PlaceOccupant
===========
*/
qboolean PlaceOccupant (int num, vec3_t point, node_t *headnode)
{
node_t *n;
n = PointInLeaf (headnode, point);
if (n->contents == CONTENTS_SOLID)
return false;
n->occupied = num;
return true;
}
/*
=============
WindingCenter
=============
*/
void WindingCenter (winding_t *w, vec3_t center)
{
int i;
vec3_t d1, d2, cross;
float scale;
VectorCopy (vec3_origin, center);
for (i=0 ; i<w->numpoints ; i++)
VectorAdd (w->points[i], center, center);
scale = 1.0/w->numpoints;
VectorScale (center, scale, center);
}
/*
==============
MarkLeakTrail
==============
*/
portal_t *prevleaknode;
FILE *pointfile, *linefile;
void MarkLeakTrail (portal_t *n2)
{
int i, j;
vec3_t p1, p2, dir;
float len;
portal_t *n1;
if (hullnum)
return;
n1 = prevleaknode;
prevleaknode = n2;
if (!n1)
return;
WindingCenter (n2->winding, p1);
WindingCenter (n1->winding, p2);
fprintf (linefile, "%f %f %f\n", p1[0], p1[1], p1[2]);
VectorSubtract (p2, p1, dir);
len = VectorLength (dir);
VectorNormalize (dir);
while (len > 2)
{
fprintf (pointfile,"%f %f %f\n", p1[0], p1[1], p1[2]);
for (i=0 ; i<3 ; i++)
p1[i] += dir[i]*2;
len -= 2;
}
}
/*
==================
RecursiveFillOutside
If fill is false, just check, don't fill
Returns true if an occupied leaf is reached
==================
*/
int hit_occupied;
int backdraw;
qboolean RecursiveFillOutside (node_t *l, qboolean fill)
{
portal_t *p;
int s;
if (l->contents == CONTENTS_SOLID || l->contents == CONTENTS_SKY)
return false;
if (l->valid == valid)
return false;
if (l->occupied)
{
hit_occupied = l->occupied;
backdraw = 1000;
return true;
}
l->valid = valid;
// fill it and it's neighbors
if (fill)
{
l->contents = CONTENTS_SOLID;
l->planenum = -1;
}
outleafs++;
for (p=l->portals ; p ; )
{
s = (p->nodes[0] == l);
if (RecursiveFillOutside (p->nodes[s], fill) )
{ // leaked, so stop filling
if (backdraw-- > 0)
{
MarkLeakTrail (p);
DrawLeaf (l, 2);
}
return true;
}
p = p->next[!s];
}
return false;
}
/*
==================
ClearOutFaces_r
Removes unused nodes
==================
*/
node_t *ClearOutFaces_r (node_t *node)
{
face_t *f, *fnext;
face_t **fp;
portal_t *p;
// mark the node and all it's faces, so they
// can be removed if no children use them
node->valid = 0; // will be set if any children touch it
for (f=node->faces ; f ; f=f->next)
f->outputnumber = -1;
// go down the children
if (node->planenum != -1)
{
//
// decision node
//
node->children[0] = ClearOutFaces_r (node->children[0]);
node->children[1] = ClearOutFaces_r (node->children[1]);
// free any faces not in open child leafs
f=node->faces;
node->faces = NULL;
for ( ; f ; f=fnext)
{
fnext = f->next;
if (f->outputnumber == -1)
{ // never referenced, so free it
c_free_faces++;
FreeFace (f);
}
else
{
c_keep_faces++;
f->next = node->faces;
node->faces = f;
}
}
if (!node->valid)
{
// this node does not touch any interior leafs
// if both children are solid, just make this node solid
if (node->children[0]->contents == CONTENTS_SOLID
&& node->children[1]->contents == CONTENTS_SOLID)
{
node->contents = CONTENTS_SOLID;
node->planenum = -1;
return node;
}
// if one child is solid, shortcut down the other side
if (node->children[0]->contents == CONTENTS_SOLID)
return node->children[1];
if (node->children[1]->contents == CONTENTS_SOLID)
return node->children[0];
c_falsenodes++;
}
return node;
}
//
// leaf node
//
if (node->contents != CONTENTS_SOLID)
{
// this node is still inside
// mark all the nodes used as portals
for (p = node->portals ; p ; )
{
if (p->onnode)
p->onnode->valid = 1;
if (p->nodes[0] == node) // only write out from first leaf
p = p->next[0];
else
p = p->next[1];
}
// mark all of the faces to be drawn
for (fp = node->markfaces ; *fp ; fp++)
(*fp)->outputnumber = 0;
return node;
}
// this was a filled in node, so free the markfaces
if (node->planenum != -1)
free (node->markfaces);
return node;
}
//=============================================================================
/*
===========
FillOutside
===========
*/
node_t *FillOutside (node_t *node, qboolean leakfile)
{
int s;
vec_t *v;
int i;
qboolean inside;
qboolean ret;
vec3_t origin;
char *cl;
qprintf ("----- FillOutside ----\n");
if (nofill)
{
printf ("skipped\n");
return node;
}
//
// place markers for all entities so
// we know if we leak inside
//
inside = false;
for (i=1 ; i<num_entities ; i++)
{
GetVectorForKey (&entities[i], "origin", origin);
if (!VectorCompare(origin, vec3_origin))
{
cl = ValueForKey (&entities[i], "classname");
origin[2] += 1; // so objects on floor are ok
// nudge playerstart around if needed so clipping hulls allways
// have a vlaid point
if (!strcmp (cl, "info_player_start"))
{
int x, y;
for (x=-16 ; x<=16 ; x += 16)
{
for (y=-16 ; y<=16 ; y += 16)
{
origin[0] += x;
origin[1] += y;
if (PlaceOccupant (i, origin, node))
{
inside = true;
goto gotit;
}
origin[0] -= x;
origin[1] -= y;
}
}
gotit: ;
}
else
{
if (PlaceOccupant (i, origin, node))
inside = true;
}
}
}
if (!inside)
{
printf ("Hullnum %i: No entities in empty space -- no filling performed\n", hullnum);
return node;
}
s = !(outside_node.portals->nodes[1] == &outside_node);
// first check to see if an occupied leaf is hit
outleafs = 0;
valid++;
prevleaknode = NULL;
if (leakfile)
{
pointfile = fopen (pointfilename, "w");
if (!pointfile)
Error ("Couldn't open %s\n", pointfilename);
StripExtension (pointfilename);
strcat (pointfilename, ".lin");
linefile = fopen (pointfilename, "w");
if (!linefile)
Error ("Couldn't open %s\n", pointfilename);
}
ret = RecursiveFillOutside (outside_node.portals->nodes[s], false);
if (leakfile)
{
fclose (pointfile);
fclose (linefile);
}
if (ret)
{
printf("LEAK LEAK LEAK\n");
GetVectorForKey (&entities[hit_occupied], "origin", origin);
qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
qprintf ("reached occupant at: (%4.0f,%4.0f,%4.0f)\n"
, origin[0], origin[1], origin[2]);
qprintf ("no filling performed\n");
qprintf ("point file and line file generated\n");
qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
if (leakonly)
Error ("Stopped by leak.");
return node;
}
// now go back and fill things in
valid++;
RecursiveFillOutside (outside_node.portals->nodes[s], true);
// remove faces and nodes from filled in leafs
c_falsenodes = 0;
c_free_faces = 0;
c_keep_faces = 0;
node = ClearOutFaces_r (node);
qprintf ("%5i outleafs\n", outleafs);
qprintf ("%5i freed faces\n", c_free_faces);
qprintf ("%5i keep faces\n", c_keep_faces);
qprintf ("%5i falsenodes\n", c_falsenodes);
// save portal file for vis tracing
if (leakfile)
WritePortalfile (node);
return node;
}

433
hlsdk/utils/qbsp2/portals.c Normal file
View File

@ -0,0 +1,433 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "bsp5.h"
node_t outside_node; // portals outside the world face this
//=============================================================================
/*
=============
AddPortalToNodes
=============
*/
void AddPortalToNodes (portal_t *p, node_t *front, node_t *back)
{
if (p->nodes[0] || p->nodes[1])
Error ("AddPortalToNode: allready included");
p->nodes[0] = front;
p->next[0] = front->portals;
front->portals = p;
p->nodes[1] = back;
p->next[1] = back->portals;
back->portals = p;
}
/*
=============
RemovePortalFromNode
=============
*/
void RemovePortalFromNode (portal_t *portal, node_t *l)
{
portal_t **pp, *t;
// remove reference to the current portal
pp = &l->portals;
while (1)
{
t = *pp;
if (!t)
Error ("RemovePortalFromNode: portal not in leaf");
if ( t == portal )
break;
if (t->nodes[0] == l)
pp = &t->next[0];
else if (t->nodes[1] == l)
pp = &t->next[1];
else
Error ("RemovePortalFromNode: portal not bounding leaf");
}
if (portal->nodes[0] == l)
{
*pp = portal->next[0];
portal->nodes[0] = NULL;
}
else if (portal->nodes[1] == l)
{
*pp = portal->next[1];
portal->nodes[1] = NULL;
}
}
//============================================================================
void PrintPortal (portal_t *p)
{
int i;
winding_t *w;
w = p->winding;
for (i=0 ; i<w->numpoints ; i++)
printf ("(%5.0f,%5.0f,%5.0f)\n",w->points[i][0]
, w->points[i][1], w->points[i][2]);
}
/*
================
MakeHeadnodePortals
The created portals will face the global outside_node
================
*/
void MakeHeadnodePortals (node_t *node, vec3_t mins, vec3_t maxs)
{
vec3_t bounds[2];
int i, j, n;
portal_t *p, *portals[6];
dplane_t bplanes[6], *pl;
Draw_ClearWindow ();
// pad with some space so there will never be null volume leafs
for (i=0 ; i<3 ; i++)
{
bounds[0][i] = mins[i] - SIDESPACE;
bounds[1][i] = maxs[i] + SIDESPACE;
}
outside_node.contents = CONTENTS_SOLID;
outside_node.portals = NULL;
for (i=0 ; i<3 ; i++)
for (j=0 ; j<2 ; j++)
{
n = j*3 + i;
p = AllocPortal ();
portals[n] = p;
pl = &bplanes[n];
memset (pl, 0, sizeof(*pl));
if (j)
{
pl->normal[i] = -1;
pl->dist = -bounds[j][i];
}
else
{
pl->normal[i] = 1;
pl->dist = bounds[j][i];
}
p->plane = *pl;
p->winding = BaseWindingForPlane (pl);
AddPortalToNodes (p, node, &outside_node);
}
// clip the basewindings by all the other planes
for (i=0 ; i<6 ; i++)
{
for (j=0 ; j<6 ; j++)
{
if (j == i)
continue;
portals[i]->winding = ClipWinding (portals[i]->winding, &bplanes[j], true);
}
}
}
//============================================================================
void CheckWindingInNode (winding_t *w, node_t *node)
{
int i, j;
for (i=0 ; i<w->numpoints ; i++)
{
for (j=0 ; j<3 ; j++)
if (w->points[i][j] < node->mins[j] - 1
|| w->points[i][j] > node->maxs[j] + 1)
{
printf ("WARNING: CheckWindingInNode: outside\n");
return;
}
}
}
void CheckWindingArea (winding_t *w)
{
int i;
float total, add;
vec3_t v1, v2, cross;
total = 0;
for (i=1 ; i<w->numpoints ; i++)
{
VectorSubtract (w->points[i], w->points[0], v1);
VectorSubtract (w->points[i+1], w->points[0], v2);
CrossProduct (v1, v2, cross);
add = VectorLength (cross);
total += add*0.5;
}
if (total < 16)
printf ("WARNING: winding area %f\n", total);
}
void PlaneFromWinding (winding_t *w, dplane_t *plane)
{
vec3_t v1, v2;
vec3_t plane_normal;
// calc plane
VectorSubtract (w->points[2], w->points[1], v1);
VectorSubtract (w->points[0], w->points[1], v2);
CrossProduct (v2, v1, plane_normal);
VectorNormalize (plane_normal);
VectorCopy (plane_normal, plane->normal); // change from vec_t
plane->dist = DotProduct (w->points[0], plane->normal);
}
void CheckLeafPortalConsistancy (node_t *node)
{
int side, side2;
portal_t *p, *p2;
dplane_t plane, plane2;
int i;
winding_t *w;
float dist;
side = side2 = 0; // quiet compiler warning
for (p = node->portals ; p ; p = p->next[side])
{
if (p->nodes[0] == node)
side = 0;
else if (p->nodes[1] == node)
side = 1;
else
Error ("CutNodePortals_r: mislinked portal");
CheckWindingInNode (p->winding, node);
CheckWindingArea (p->winding);
// check that the side orders are correct
plane = p->plane;
PlaneFromWinding (p->winding, &plane2);
for (p2 = node->portals ; p2 ; p2 = p2->next[side2])
{
if (p2->nodes[0] == node)
side2 = 0;
else if (p2->nodes[1] == node)
side2 = 1;
else
Error ("CutNodePortals_r: mislinked portal");
w = p2->winding;
for (i=0 ; i<w->numpoints ; i++)
{
dist = DotProduct (w->points[i], plane.normal) - plane.dist;
if ( (side == 0 && dist < -1) || (side == 1 && dist > 1) )
{
printf ("WARNING: portal siding direction is wrong\n");
return;
}
}
}
}
}
/*
==============================================================================
PORTAL FILE GENERATION
==============================================================================
*/
#define PORTALFILE "PRT1"
FILE *pf;
int num_visleafs; // leafs the player can be in
int num_visportals;
void WriteFloat (FILE *f, vec_t v)
{
if ( fabs(v - Q_rint(v)) < ON_EPSILON )
fprintf (f,"%i ",(int)Q_rint(v));
else
fprintf (f,"%f ",v);
}
void WritePortalFile_r (node_t *node)
{
int i;
portal_t *p;
winding_t *w;
dplane_t *pl, plane2;
if (!node->contents)
{
WritePortalFile_r (node->children[0]);
WritePortalFile_r (node->children[1]);
return;
}
if (node->contents == CONTENTS_SOLID)
return;
for (p = node->portals ; p ; )
{
w = p->winding;
if (w && p->nodes[0] == node)
{
if ( (watervis && p->nodes[0]->contents != CONTENTS_SOLID && p->nodes[1]->contents != CONTENTS_SOLID)
|| (p->nodes[0]->contents == p->nodes[1]->contents) )
{
// write out to the file
// sometimes planes get turned around when they are very near
// the changeover point between different axis. interpret the
// plane the same way vis will, and flip the side orders if needed
PlaneFromWinding (w, &plane2);
if ( DotProduct (p->plane.normal, plane2.normal) < 1.0-ON_EPSILON )
{ // backwards...
fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->visleafnum, p->nodes[0]->visleafnum);
}
else
fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->visleafnum, p->nodes[1]->visleafnum);
for (i=0 ; i<w->numpoints ; i++)
{
fprintf (pf,"(");
WriteFloat (pf, w->points[i][0]);
WriteFloat (pf, w->points[i][1]);
WriteFloat (pf, w->points[i][2]);
fprintf (pf,") ");
}
fprintf (pf,"\n");
}
}
if (p->nodes[0] == node)
p = p->next[0];
else
p = p->next[1];
}
}
/*
================
NumberLeafs_r
================
*/
void NumberLeafs_r (node_t *node)
{
portal_t *p;
if (!node->contents)
{ // decision node
node->visleafnum = -99;
NumberLeafs_r (node->children[0]);
NumberLeafs_r (node->children[1]);
return;
}
Draw_ClearWindow ();
DrawLeaf (node, 1);
if (node->contents == CONTENTS_SOLID)
{ // solid block, viewpoint never inside
node->visleafnum = -1;
return;
}
node->visleafnum = num_visleafs++;
for (p = node->portals ; p ; )
{
if (p->nodes[0] == node) // only write out from first leaf
{
if ( (watervis && p->nodes[0]->contents != CONTENTS_SOLID && p->nodes[1]->contents != CONTENTS_SOLID)
|| (p->nodes[0]->contents == p->nodes[1]->contents) )
num_visportals++;
p = p->next[0];
}
else
p = p->next[1];
}
}
/*
================
WritePortalfile
================
*/
void WritePortalfile (node_t *headnode)
{
// set the visleafnum field in every leaf and count the total number of portals
num_visleafs = 0;
num_visportals = 0;
NumberLeafs_r (headnode);
// write the file
printf ("writing %s\n", portfilename);
pf = fopen (portfilename, "w");
if (!pf)
Error ("Error opening %s", portfilename);
fprintf (pf, "%s\n", PORTALFILE);
fprintf (pf, "%i\n", num_visleafs);
fprintf (pf, "%i\n", num_visportals);
WritePortalFile_r (headnode);
fclose (pf);
}
//===================================================
void FreePortals (node_t *node)
{
portal_t *p, *nextp;
if (node->planenum != -1)
{
FreePortals (node->children[0]);
FreePortals (node->children[1]);
return;
}
for (p=node->portals ; p ; p=nextp)
{
if (p->nodes[0] == node)
nextp = p->next[0];
else
nextp = p->next[1];
RemovePortalFromNode (p, p->nodes[0]);
RemovePortalFromNode (p, p->nodes[1]);
FreeWinding (p->winding);
FreePortal (p);
}
}

1016
hlsdk/utils/qbsp2/qbsp.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,984 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// solidbsp.c
#include "bsp5.h"
/*
Each node or leaf will have a set of portals that completely enclose
the volume of the node and pass into an adjacent node.
*/
int c_leaffaces;
int c_nodefaces;
int c_splitnodes;
//============================================================================
/*
==================
FaceSide
For BSP hueristic
==================
*/
int FaceSide (face_t *in, dplane_t *split)
{
int frontcount, backcount;
vec_t dot;
int i;
vec_t *p;
frontcount = backcount = 0;
// axial planes are fast
if (split->type < 3)
for (i=0, p = in->pts[0]+split->type ; i<in->numpoints ; i++, p+=3)
{
if (*p > split->dist + ON_EPSILON)
{
if (backcount)
return SIDE_ON;
frontcount = 1;
}
else if (*p < split->dist - ON_EPSILON)
{
if (frontcount)
return SIDE_ON;
backcount = 1;
}
}
else
// sloping planes take longer
for (i=0, p = in->pts[0] ; i<in->numpoints ; i++, p+=3)
{
dot = DotProduct (p, split->normal);
dot -= split->dist;
if (dot > ON_EPSILON)
{
if (backcount)
return SIDE_ON;
frontcount = 1;
}
else if (dot < -ON_EPSILON)
{
if (frontcount)
return SIDE_ON;
backcount = 1;
}
}
if (!frontcount)
return SIDE_BACK;
if (!backcount)
return SIDE_FRONT;
return SIDE_ON;
}
/*
==================
ChooseMidPlaneFromList
When there are a huge number of planes, just choose one closest
to the middle.
==================
*/
surface_t *ChooseMidPlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs)
{
int j,l;
surface_t *p, *bestsurface;
vec_t bestvalue, value, dist;
dplane_t *plane;
//
// pick the plane that splits the least
//
bestvalue = 6*8192*8192;
bestsurface = NULL;
for (p=surfaces ; p ; p=p->next)
{
if (p->onnode)
continue;
plane = &dplanes[p->planenum];
// check for axis aligned surfaces
l = plane->type;
if (l > PLANE_Z)
continue;
//
// calculate the split metric along axis l, smaller values are better
//
value = 0;
dist = plane->dist * plane->normal[l];
for (j=0 ; j<3 ; j++)
{
if (j == l)
{
value += (maxs[l]-dist)*(maxs[l]-dist);
value += (dist-mins[l])*(dist-mins[l]);
}
else
value += 2*(maxs[j]-mins[j])*(maxs[j]-mins[j]);
}
if (value > bestvalue)
continue;
//
// currently the best!
//
bestvalue = value;
bestsurface = p;
}
if (!bestsurface)
{
for (p=surfaces ; p ; p=p->next)
if (!p->onnode)
return p; // first valid surface
Error ("ChooseMidPlaneFromList: no valid planes");
}
return bestsurface;
}
/*
==================
ChoosePlaneFromList
Choose the plane that splits the least faces
==================
*/
surface_t *ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs)
{
int j,k,l;
surface_t *p, *p2, *bestsurface;
vec_t bestvalue, bestdistribution, value, dist;
dplane_t *plane;
face_t *f;
//
// pick the plane that splits the least
//
bestvalue = 99999;
bestsurface = NULL;
bestdistribution = 9e30;
for (p=surfaces ; p ; p=p->next)
{
if (p->onnode)
continue;
plane = &dplanes[p->planenum];
k = 0;
for (p2=surfaces ; p2 ; p2=p2->next)
{
if (p2 == p)
continue;
if (p2->onnode)
continue;
for (f=p2->faces ; f ; f=f->next)
{
if (FaceSide (f, plane) == SIDE_ON)
{
k++;
if (k >= bestvalue)
break;
}
}
if (k > bestvalue)
break;
}
if (k > bestvalue)
continue;
// if equal numbers, axial planes win, then decide on spatial subdivision
if (k < bestvalue || (k == bestvalue && plane->type < PLANE_ANYX) )
{
// check for axis aligned surfaces
l = plane->type;
if (l <= PLANE_Z)
{ // axial aligned
//
// calculate the split metric along axis l
//
value = 0;
for (j=0 ; j<3 ; j++)
{
if (j == l)
{
dist = plane->dist * plane->normal[l];
value += (maxs[l]-dist)*(maxs[l]-dist);
value += (dist-mins[l])*(dist-mins[l]);
}
else
value += 2*(maxs[j]-mins[j])*(maxs[j]-mins[j]);
}
if (value > bestdistribution && k == bestvalue)
continue;
bestdistribution = value;
}
//
// currently the best!
//
bestvalue = k;
bestsurface = p;
}
}
return bestsurface;
}
/*
==================
SelectPartition
Selects a surface from a linked list of surfaces to split the group on
returns NULL if the surface list can not be divided any more (a leaf)
==================
*/
surface_t *SelectPartition (surface_t *surfaces, node_t *node, qboolean usemidsplit)
{
int i,j;
surface_t *p, *bestsurface;
//
// count surface choices
//
i = 0;
bestsurface = NULL;
for (p=surfaces ; p ; p=p->next)
if (!p->onnode)
{
i++;
bestsurface = p;
}
if (i==0)
return NULL; // this is a leafnode
if (i==1)
return bestsurface; // this is a final split
if (usemidsplit) // do fast way for clipping hull
return ChooseMidPlaneFromList (surfaces, node->mins, node->maxs);
// do slow way to save poly splits for drawing hull
return ChoosePlaneFromList (surfaces, node->mins, node->maxs);
}
//============================================================================
/*
=================
CalcSurfaceInfo
Calculates the bounding box
=================
*/
void CalcSurfaceInfo (surface_t *surf)
{
int i,j;
face_t *f;
if (!surf->faces)
Error ("CalcSurfaceInfo: surface without a face");
//
// calculate a bounding box
//
for (i=0 ; i<3 ; i++)
{
surf->mins[i] = 99999;
surf->maxs[i] = -99999;
}
for (f=surf->faces ; f ; f=f->next)
{
if (f->contents >= 0)
Error ("Bad contents");
for (i=0 ; i<f->numpoints ; i++)
for (j=0 ; j<3 ; j++)
{
if (f->pts[i][j] < surf->mins[j])
surf->mins[j] = f->pts[i][j];
if (f->pts[i][j] > surf->maxs[j])
surf->maxs[j] = f->pts[i][j];
}
}
}
/*
==================
DivideSurface
==================
*/
void DivideSurface (surface_t *in, dplane_t *split, surface_t **front, surface_t **back)
{
face_t *facet, *next;
face_t *frontlist, *backlist;
face_t *frontfrag, *backfrag;
surface_t *news;
dplane_t *inplane;
inplane = &dplanes[in->planenum];
// parallel case is easy
if (inplane->normal[0] == split->normal[0]
&& inplane->normal[1] == split->normal[1]
&& inplane->normal[2] == split->normal[2])
{
if (inplane->dist > split->dist)
{
*front = in;
*back = NULL;
}
else if (inplane->dist < split->dist)
{
*front = NULL;
*back = in;
}
else
{ // split the surface into front and back
frontlist = NULL;
backlist = NULL;
for (facet = in->faces ; facet ; facet = next)
{
next = facet->next;
if (facet->planenum & 1)
{
facet->next = backlist;
backlist = facet;
}
else
{
facet->next = frontlist;
frontlist = facet;
}
}
goto makesurfs;
}
return;
}
// do a real split. may still end up entirely on one side
// OPTIMIZE: use bounding box for fast test
frontlist = NULL;
backlist = NULL;
for (facet = in->faces ; facet ; facet = next)
{
next = facet->next;
SplitFace (facet, split, &frontfrag, &backfrag);
if (frontfrag)
{
frontfrag->next = frontlist;
frontlist = frontfrag;
}
if (backfrag)
{
backfrag->next = backlist;
backlist = backfrag;
}
}
// if nothing actually got split, just move the in plane
makesurfs:
if (frontlist == NULL)
{
*front = NULL;
*back = in;
in->faces = backlist;
return;
}
if (backlist == NULL)
{
*front = in;
*back = NULL;
in->faces = frontlist;
return;
}
// stuff got split, so allocate one new surface and reuse in
news = AllocSurface ();
*news = *in;
news->faces = backlist;
*back = news;
in->faces = frontlist;
*front = in;
// recalc bboxes and flags
CalcSurfaceInfo (news);
CalcSurfaceInfo (in);
}
/*
=============
SplitNodeSurfaces
=============
*/
void SplitNodeSurfaces (surface_t *surfaces, node_t *node)
{
surface_t *p, *next;
surface_t *frontlist, *backlist;
surface_t *frontfrag, *backfrag;
dplane_t *splitplane;
splitplane = &dplanes[node->planenum];
frontlist = NULL;
backlist = NULL;
for (p=surfaces ; p ; p=next)
{
next = p->next;
DivideSurface (p, splitplane, &frontfrag, &backfrag);
if (frontfrag)
{
if (!frontfrag->faces)
Error ("surface with no faces");
frontfrag->next = frontlist;
frontlist = frontfrag;
}
if (backfrag)
{
if (!backfrag->faces)
Error ("surface with no faces");
backfrag->next = backlist;
backlist = backfrag;
}
}
node->children[0]->surfaces = frontlist;
node->children[1]->surfaces = backlist;
}
int RankForContents (int contents)
{
switch (contents)
{
case CONTENTS_EMPTY: return 0;
case CONTENTS_WATER: return 1;
case CONTENTS_TRANSLUCENT: return 2;
case CONTENTS_CURRENT_0: return 3;
case CONTENTS_CURRENT_90: return 4;
case CONTENTS_CURRENT_180: return 5;
case CONTENTS_CURRENT_270: return 6;
case CONTENTS_CURRENT_UP: return 7;
case CONTENTS_CURRENT_DOWN: return 8;
case CONTENTS_SLIME: return 9;
case CONTENTS_LAVA : return 10;
case CONTENTS_SKY : return 11;
case CONTENTS_SOLID: return 12;
default:
Error ("RankForContents: bad contents %i", contents);
}
return -1;
}
int ContentsForRank (int rank)
{
switch (rank)
{
case -1: return CONTENTS_SOLID; // no faces at all
case 0: return CONTENTS_EMPTY;
case 1: return CONTENTS_WATER;
case 2: return CONTENTS_TRANSLUCENT;
case 3: return CONTENTS_CURRENT_0;
case 4: return CONTENTS_CURRENT_90;
case 5: return CONTENTS_CURRENT_180;
case 6: return CONTENTS_CURRENT_270;
case 7: return CONTENTS_CURRENT_UP;
case 8: return CONTENTS_CURRENT_DOWN;
case 9: return CONTENTS_SLIME;
case 10: return CONTENTS_LAVA;
case 11: return CONTENTS_SKY;
case 12: return CONTENTS_SOLID;
default:
Error ("ContentsForRank: bad rank %i", rank);
}
return -1;
}
/*
=============
FreeLeafSurfs
=============
*/
void FreeLeafSurfs (node_t *leaf)
{
surface_t *surf, *snext;
face_t *f, *fnext;
for (surf = leaf->surfaces ; surf ; surf=snext)
{
snext = surf->next;
for (f=surf->faces ; f ; f=fnext)
{
fnext = f->next;
FreeFace (f);
}
FreeSurface (surf);
}
leaf->surfaces = NULL;
}
/*
==================
LinkLeafFaces
Determines the contents of the leaf and creates the final list of
original faces that have some fragment inside this leaf
==================
*/
#define MAX_LEAF_FACES 1024
void LinkLeafFaces (surface_t *planelist, node_t *leafnode)
{
face_t *f;
surface_t *surf;
int rank, r;
int nummarkfaces;
face_t *markfaces[MAX_LEAF_FACES];
leafnode->faces = NULL;
leafnode->planenum = -1;
rank = -1;
for ( surf = planelist ; surf ; surf = surf->next)
{
for (f = surf->faces ; f ; f=f->next)
{
r = RankForContents (f->contents);
if (r > rank)
rank = r;
}
}
leafnode->contents = ContentsForRank (rank);
if (leafnode->contents != CONTENTS_SOLID)
{
nummarkfaces = 0;
for (surf = leafnode->surfaces ; surf ; surf=surf->next)
{
for (f=surf->faces ; f ; f=f->next)
{
if (nummarkfaces == MAX_LEAF_FACES)
Error ("nummarkfaces == MAX_LEAF_FACES");
markfaces[nummarkfaces++] = f->original;
}
}
c_leaffaces += nummarkfaces;
markfaces[nummarkfaces] = NULL; // end marker
nummarkfaces++;
leafnode->markfaces = malloc(nummarkfaces * sizeof(*leafnode->markfaces));
memcpy (leafnode->markfaces, markfaces, nummarkfaces * sizeof(*leafnode->markfaces));
}
FreeLeafSurfs (leafnode);
leafnode->surfaces = NULL;
}
/*
==================
MakeNodePortal
create the new portal by taking the full plane winding for the cutting plane
and clipping it by all of the planes from the other portals.
Each portal tracks the node that created it, so unused nodes
can be removed later.
==================
*/
void MakeNodePortal (node_t *node)
{
portal_t *new_portal, *p;
dplane_t *plane;
dplane_t clipplane;
winding_t *w;
int side;
plane = &dplanes[node->planenum];
w = BaseWindingForPlane (plane);
new_portal = AllocPortal ();
new_portal->plane = *plane;
new_portal->onnode = node;
side = 0; // shut up compiler warning
for (p = node->portals ; p ; p = p->next[side])
{
clipplane = p->plane;
if (p->nodes[0] == node)
side = 0;
else if (p->nodes[1] == node)
{
clipplane.dist = -clipplane.dist;
VectorSubtract (vec3_origin, clipplane.normal, clipplane.normal);
side = 1;
}
else
Error ("MakeNodePortal: mislinked portal");
w = ClipWinding (w, &clipplane, true);
if (!w)
{
printf ("WARNING: MakeNodePortal:new portal was clipped away from node@(%.0f,%.0f,%.0f)-(%.0f,%.0f,%.0f)\n",
node->mins[0], node->mins[1], node->mins[2],
node->maxs[0], node->maxs[1], node->maxs[2]);
FreePortal (new_portal);
return;
}
}
new_portal->winding = w;
AddPortalToNodes (new_portal, node->children[0], node->children[1]);
}
/*
==============
SplitNodePortals
Move or split the portals that bound node so that the node's
children have portals instead of node.
==============
*/
void SplitNodePortals (node_t *node)
{
portal_t *p, *next_portal, *new_portal;
node_t *f, *b, *other_node;
int side;
dplane_t *plane;
winding_t *frontwinding, *backwinding;
plane = &dplanes[node->planenum];
f = node->children[0];
b = node->children[1];
for (p = node->portals ; p ; p = next_portal)
{
if (p->nodes[0] == node)
side = 0;
else if (p->nodes[1] == node)
side = 1;
else
Error ("CutNodePortals_r: mislinked portal");
next_portal = p->next[side];
other_node = p->nodes[!side];
RemovePortalFromNode (p, p->nodes[0]);
RemovePortalFromNode (p, p->nodes[1]);
//
// cut the portal into two portals, one on each side of the cut plane
//
DivideWinding (p->winding, plane, &frontwinding, &backwinding);
if (!frontwinding)
{
if (side == 0)
AddPortalToNodes (p, b, other_node);
else
AddPortalToNodes (p, other_node, b);
continue;
}
if (!backwinding)
{
if (side == 0)
AddPortalToNodes (p, f, other_node);
else
AddPortalToNodes (p, other_node, f);
continue;
}
// the winding is split
new_portal = AllocPortal ();
*new_portal = *p;
new_portal->winding = backwinding;
FreeWinding (p->winding);
p->winding = frontwinding;
if (side == 0)
{
AddPortalToNodes (p, f, other_node);
AddPortalToNodes (new_portal, b, other_node);
}
else
{
AddPortalToNodes (p, other_node, f);
AddPortalToNodes (new_portal, other_node, b);
}
}
node->portals = NULL;
}
/*
==================
CalcNodeBounds
Determines the boundaries of a node by
minmaxing all the portal points, whcih
completely enclose the node.
Returns true if the node should be midsplit.(very large)
==================
*/
qboolean CalcNodeBounds (node_t *node)
{
int i, j;
vec_t v;
portal_t *p, *next_portal;
int side;
node->mins[0] = node->mins[1] = node->mins[2] = 9999;
node->maxs[0] = node->maxs[1] = node->maxs[2] = -9999;
for (p = node->portals ; p ; p = next_portal)
{
if (p->nodes[0] == node)
side = 0;
else if (p->nodes[1] == node)
side = 1;
else
Error ("CutNodePortals_r: mislinked portal");
next_portal = p->next[side];
for (i=0 ; i<p->winding->numpoints ; i++)
{
for (j=0 ; j<3 ; j++)
{
v = p->winding->points[i][j];
if (v < node->mins[j])
node->mins[j] = v;
if (v > node->maxs[j])
node->maxs[j] = v;
}
}
}
for (i=0 ; i<3 ; i++)
if (node->maxs[i] - node->mins[i] > 1024)
return true;
return false;
}
/*
==================
CopyFacesToNode
Do a final merge attempt, then subdivide the faces
to surface cache size if needed.
These are final faces that will be drawable in the game.
Copies of these faces are further chopped up into the leafs,
but they will reference these originals.
==================
*/
void CopyFacesToNode (node_t *node, surface_t *surf)
{
face_t **prevptr, *f, *newf;
// merge as much as possible
MergePlaneFaces (surf);
// subdivide large faces
prevptr = &surf->faces;
while (1)
{
f = *prevptr;
if (!f)
break;
SubdivideFace (f, prevptr);
f = *prevptr;
prevptr = &f->next;
}
// copy the faces to the node, and consider them the originals
node->surfaces = NULL;
node->faces = NULL;
for (f=surf->faces ; f ; f=f->next)
{
if (f->contents != CONTENTS_SOLID)
{
newf = AllocFace ();
*newf = *f;
f->original = newf;
newf->next = node->faces;
node->faces = newf;
c_nodefaces++;
}
}
}
/*
==================
DrawSurfaces
==================
*/
void DrawSurfaces (surface_t *surf)
{
face_t *f;
Draw_ClearWindow ();
for ( ; surf ; surf=surf->next)
{
for (f = surf->faces ; f ; f=f->next)
{
Draw_DrawFace (f);
}
}
}
/*
==================
BuildBspTree_r
==================
*/
void BuildBspTree_r (node_t *node)
{
surface_t *split;
qboolean midsplit;
surface_t *allsurfs;
midsplit = CalcNodeBounds (node);
DrawSurfaces (node->surfaces);
split = SelectPartition (node->surfaces, node, midsplit);
if (!split)
{ // this is a leaf node
node->planenum = PLANENUM_LEAF;
LinkLeafFaces (node->surfaces, node);
return;
}
//
// these are final polygons
//
split->onnode = node; // can't use again
allsurfs = node->surfaces;
node->planenum = split->planenum;
node->faces = NULL;
CopyFacesToNode (node, split);
c_splitnodes++;
node->children[0] = AllocNode ();
node->children[1] = AllocNode ();
//
// split all the polysurfaces into front and back lists
//
SplitNodeSurfaces (allsurfs, node);
//
// create the portal that seperates the two children
//
MakeNodePortal (node);
//
// carve the portals on the boundaries of the node
//
SplitNodePortals (node);
//
// recursively do the children
//
BuildBspTree_r (node->children[0]);
BuildBspTree_r (node->children[1]);
}
/*
==================
SolidBSP
Takes a chain of surfaces plus a split type, and
returns a bsp tree with faces off the nodes.
The original surface chain will be completely freed.
==================
*/
node_t *SolidBSP (surfchain_t *surfhead)
{
int i;
node_t *headnode;
qprintf ("----- SolidBSP -----\n");
headnode = AllocNode ();
headnode->surfaces = surfhead->surfaces;
Draw_ClearWindow ();
c_splitnodes = 0;
c_nodefaces = 0;
c_leaffaces = 0;
if (!surfhead->surfaces)
{
// nothing at all to build
headnode->planenum = -1;
headnode->contents = CONTENTS_EMPTY;
return headnode;
}
//
// generate six portals that enclose the entire world
//
MakeHeadnodePortals (headnode, surfhead->mins, surfhead->maxs);
//
// recursively partition everything
//
BuildBspTree_r (headnode);
qprintf ("%5i split nodes\n", c_splitnodes);
qprintf ("%5i node faces\n", c_nodefaces);
qprintf ("%5i leaf faces\n", c_leaffaces);
return headnode;
}

View File

@ -0,0 +1,474 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// divide.h
#include "bsp5.h"
int TexelDelta( face_t *f, dplane_t *plane );
int TexelSize( face_t *f );
surface_t newcopy_t;
/*
a surface has all of the faces that could be drawn on a given plane
the outside filling stage can remove some of them so a better bsp can be generated
*/
int subdivides;
/*
===============
SubdivideFace
If the face is >256 in either texture direction, carve a valid sized
piece off and insert the remainder in the next link
===============
*/
void SubdivideFace (face_t *f, face_t **prevptr)
{
float mins, maxs;
vec_t v;
int axis, i;
dplane_t plane;
face_t *front, *back, *next;
texinfo_t *tex;
vec3_t temp;
// special (non-surface cached) faces don't need subdivision
tex = &texinfo[f->texturenum];
if ( tex->flags & TEX_SPECIAL)
return;
for (axis = 0 ; axis < 2 ; axis++)
{
while (1)
{
mins = 999999;
maxs = -999999;
for (i=0 ; i<f->numpoints ; i++)
{
v = DotProduct (f->pts[i], tex->vecs[axis]);
if (v < mins)
mins = v;
if (v > maxs)
maxs = v;
}
if (maxs - mins <= subdivide_size)
break;
// split it
subdivides++;
VectorCopy (tex->vecs[axis], temp);
v = VectorNormalize (temp);
VectorCopy (temp, plane.normal);
plane.dist = (mins + subdivide_size - 16)/v;
next = f->next;
SplitFace (f, &plane, &front, &back);
if (!front || !back)
{
//PrintMemory();
printf("SubdivideFace: didn't split the %d-sided polygon @(%.0f,%.0f,%.0f)",
f->numpoints, f->pts[0][0], f->pts[0][1], f->pts[0][2] );
break;
}
*prevptr = back;
back->next = front;
front->next = next;
f = back;
}
}
}
int TexelDelta( face_t *f, dplane_t *plane )
{
int current, delta;
current = delta = 0;
// Does the plane split the face?
if ( FaceSide (f, plane) == SIDE_ON )
{
face_t *front, *back;
// Compute the change in texture cache from splitting the face
current = TexelSize( f );
// Speculatively split the face
SplitFaceTmp(f, plane, &front, &back);
if (!front || !back) // Didn't actually split the face
delta = 0;
else
{
delta = 0;//TexelSize( front ) + TexelSize( back ) - current; // Change in texel size
FreeFace( front ); // Free new faces
FreeFace( back );
}
}
return delta;
}
int TexelSize( face_t *f )
{
float mins, maxs;
vec_t v;
int i, smax, tmax;
dplane_t plane;
face_t *front, *back, *next;
texinfo_t *tex;
vec3_t temp;
// special (non-surface cached) faces don't need subdivision
if ( f->texturenum > numtexinfo )
{
printf("Error on face\n" );
return 0;
}
tex = &texinfo[f->texturenum];
if ( tex->flags & TEX_SPECIAL)
return 0;
mins = 999999;
maxs = -999999;
for (i=0 ; i<f->numpoints ; i++)
{
v = DotProduct (f->pts[i], tex->vecs[0]);
if (v < mins)
mins = v;
if (v > maxs)
maxs = v;
}
smax = maxs - mins;
mins = 999999;
maxs = -999999;
for (i=0 ; i<f->numpoints ; i++)
{
v = DotProduct (f->pts[i], tex->vecs[1]);
if (v < mins)
mins = v;
if (v > maxs)
maxs = v;
}
tmax = maxs - mins;
return smax * tmax;
}
//===========================================================================
typedef struct hashvert_s
{
struct hashvert_s *next;
vec3_t point;
int num;
int numplanes; // for corner determination
int planenums[2];
int numedges;
} hashvert_t;
// #define POINT_EPSILON 0.01
#define POINT_EPSILON ON_EPSILON
int c_cornerverts;
hashvert_t hvertex[MAX_MAP_VERTS];
hashvert_t *hvert_p;
face_t *edgefaces[MAX_MAP_EDGES][2];
int firstmodeledge = 1;
int firstmodelface;
//============================================================================
#define NUM_HASH 4096
hashvert_t *hashverts[NUM_HASH];
static vec3_t hash_min, hash_scale;
static void InitHash (void)
{
vec3_t size;
vec_t volume;
vec_t scale;
int newsize[2];
int i;
memset (hashverts, 0, sizeof(hashverts));
for (i=0 ; i<3 ; i++)
{
hash_min[i] = -8000;
size[i] = 16000;
}
volume = size[0]*size[1];
scale = sqrt(volume / NUM_HASH);
newsize[0] = size[0] / scale;
newsize[1] = size[1] / scale;
hash_scale[0] = newsize[0] / size[0];
hash_scale[1] = newsize[1] / size[1];
hash_scale[2] = newsize[1];
hvert_p = hvertex;
}
static unsigned HashVec (vec3_t vec)
{
unsigned h;
h = hash_scale[0] * (vec[0] - hash_min[0]) * hash_scale[2]
+ hash_scale[1] * (vec[1] - hash_min[1]);
if ( h >= NUM_HASH)
return NUM_HASH - 1;
return h;
}
/*
=============
GetVertex
=============
*/
int GetVertex (vec3_t in, int planenum)
{
int h;
int i;
hashvert_t *hv;
vec3_t vert;
for (i=0 ; i<3 ; i++)
{
if ( fabs(in[i] - Q_rint(in[i])) < 0.001)
vert[i] = Q_rint(in[i]);
else
vert[i] = in[i];
}
h = HashVec (vert);
for (hv=hashverts[h] ; hv ; hv=hv->next)
{
if ( fabs(hv->point[0]-vert[0])<POINT_EPSILON
&& fabs(hv->point[1]-vert[1])<POINT_EPSILON
&& fabs(hv->point[2]-vert[2])<POINT_EPSILON )
{
hv->numedges++;
if (hv->numplanes == 3)
return hv->num; // allready known to be a corner
for (i=0 ; i<hv->numplanes ; i++)
if (hv->planenums[i] == planenum)
return hv->num; // allready know this plane
if (hv->numplanes == 2)
c_cornerverts++;
else
hv->planenums[hv->numplanes] = planenum;
hv->numplanes++;
return hv->num;
}
}
hv = hvert_p;
hv->numedges = 1;
hv->numplanes = 1;
hv->planenums[0] = planenum;
hv->next = hashverts[h];
hashverts[h] = hv;
VectorCopy (vert, hv->point);
hv->num = numvertexes;
if (hv->num==MAX_MAP_VERTS)
Error ("GetVertex: MAX_MAP_VERTS");
hvert_p++;
// emit a vertex
if (numvertexes == MAX_MAP_VERTS)
Error ("numvertexes == MAX_MAP_VERTS");
dvertexes[numvertexes].point[0] = vert[0];
dvertexes[numvertexes].point[1] = vert[1];
dvertexes[numvertexes].point[2] = vert[2];
numvertexes++;
return hv->num;
}
//===========================================================================
/*
==================
GetEdge
Don't allow four way edges
==================
*/
int c_tryedges;
int GetEdge (vec3_t p1, vec3_t p2, face_t *f)
{
int v1, v2;
dedge_t *edge;
int i;
if (!f->contents)
Error ("GetEdge: 0 contents");
c_tryedges++;
v1 = GetVertex (p1, f->planenum);
v2 = GetVertex (p2, f->planenum);
for (i=firstmodeledge ; i < numedges ; i++)
{
edge = &dedges[i];
if (v1 == edge->v[1] && v2 == edge->v[0]
&& !edgefaces[i][1]
&& edgefaces[i][0]->contents == f->contents)
{
edgefaces[i][1] = f;
return -i;
}
}
// emit an edge
if (numedges >= MAX_MAP_EDGES)
Error ("numedges == MAX_MAP_EDGES");
edge = &dedges[numedges];
numedges++;
edge->v[0] = v1;
edge->v[1] = v2;
edgefaces[i][0] = f;
return i;
}
/*
=============
CheckVertexes
// debugging
=============
*/
void CheckVertexes (void)
{
int cb, c0, c1, c2, c3;
hashvert_t *hv;
cb = c0 = c1 = c2 = c3 = 0;
for (hv=hvertex ; hv!=hvert_p ; hv++)
{
if (hv->numedges < 0 || hv->numedges & 1)
cb++;
else if (!hv->numedges)
c0++;
else if (hv->numedges == 2)
c1++;
else if (hv->numedges == 4)
c2++;
else
c3++;
}
qprintf ("%5i bad edge points\n", cb);
qprintf ("%5i 0 edge points\n", c0);
qprintf ("%5i 2 edge points\n", c1);
qprintf ("%5i 4 edge points\n", c2);
qprintf ("%5i 6+ edge points\n", c3);
}
/*
=============
CheckEdges
// debugging
=============
*/
void CheckEdges (void)
{
dedge_t *edge;
int i;
dvertex_t *d1, *d2;
face_t *f1, *f2;
int c_nonconvex;
int c_multitexture;
c_nonconvex = c_multitexture = 0;
// CheckVertexes ();
for (i=1 ; i < numedges ; i++)
{
edge = &dedges[i];
if (!edgefaces[i][1])
{
d1 = &dvertexes[edge->v[0]];
d2 = &dvertexes[edge->v[1]];
qprintf ("unshared edge at: (%8.2f, %8.2f, %8.2f) (%8.2f, %8.2f, %8.2f)\n",d1->point[0], d1->point[1], d1->point[2], d2->point[0], d2->point[1], d2->point[2]);
}
else
{
f1 = edgefaces[i][0];
f2 = edgefaces[i][1];
if (f1->planenum != f2->planenum)
continue;
// on the same plane, might be discardable
if (f1->texturenum == f2->texturenum)
{
hvertex[edge->v[0]].numedges-=2;
hvertex[edge->v[1]].numedges-=2;
c_nonconvex++;
}
else
c_multitexture++;
}
}
// qprintf ("%5i edges\n", i);
// qprintf ("%5i c_nonconvex\n", c_nonconvex);
// qprintf ("%5i c_multitexture\n", c_multitexture);
// CheckVertexes ();
}
/*
================
MakeFaceEdges
================
*/
void MakeFaceEdges (node_t *headnode)
{
InitHash ();
c_tryedges = 0;
c_cornerverts = 0;
firstmodeledge = numedges;
firstmodelface = numfaces;
}

520
hlsdk/utils/qbsp2/tjunc.c Normal file
View File

@ -0,0 +1,520 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// tjunc.c
#include "bsp5.h"
typedef struct wvert_s
{
vec_t t;
struct wvert_s *prev, *next;
} wvert_t;
typedef struct wedge_s
{
struct wedge_s *next;
vec3_t dir;
vec3_t origin;
wvert_t head;
} wedge_t;
int numwedges, numwverts;
int tjuncs;
int tjuncfaces;
#define MAXWVERTS 0x20000
#define MAXWEDGES 0x10000
wvert_t wverts[MAXWVERTS];
wedge_t wedges[MAXWEDGES];
void PrintFace (face_t *f)
{
int i;
for (i=0 ; i<f->numpoints ; i++)
printf ("(%5.2f, %5.2f, %5.2f)\n", f->pts[i][0], f->pts[i][1], f->pts[i][2]);
}
//============================================================================
#define NUM_HASH 1024
wedge_t *wedge_hash[NUM_HASH];
static vec3_t hash_min, hash_scale;
static void InitHash (vec3_t mins, vec3_t maxs)
{
vec3_t size;
vec_t volume;
vec_t scale;
int newsize[2];
VectorCopy (mins, hash_min);
VectorSubtract (maxs, mins, size);
memset (wedge_hash, 0, sizeof(wedge_hash));
volume = size[0]*size[1];
scale = sqrt(volume / NUM_HASH);
newsize[0] = size[0] / scale;
newsize[1] = size[1] / scale;
hash_scale[0] = newsize[0] / size[0];
hash_scale[1] = newsize[1] / size[1];
hash_scale[2] = newsize[1];
}
static unsigned HashVec (vec3_t vec)
{
unsigned h;
h = hash_scale[0] * (vec[0] - hash_min[0]) * hash_scale[2]
+ hash_scale[1] * (vec[1] - hash_min[1]);
if ( h >= NUM_HASH)
return NUM_HASH - 1;
return h;
}
//============================================================================
void CanonicalVector (vec3_t vec)
{
VectorNormalize (vec);
if (vec[0] > 0 /* EQUAL_EPSILON */)
return;
else if (vec[0] < 0 /* -EQUAL_EPSILON */ )
{
VectorSubtract (vec3_origin, vec, vec);
return;
}
else
vec[0] = 0;
if (vec[1] > 0 /* EQUAL_EPSILON */)
return;
else if (vec[1] < 0 /*-EQUAL_EPSILON*/)
{
VectorSubtract (vec3_origin, vec, vec);
return;
}
else
vec[1] = 0;
if (vec[2] > 0 /* EQUAL_EPSILON */ )
return;
else if (vec[2] < 0 /*-EQUAL_EPSILON*/ )
{
VectorSubtract (vec3_origin, vec, vec);
return;
}
else
vec[2] = 0;
printf ("WARNING: CanonicalVector: degenerate\n");
}
wedge_t *FindEdge (vec3_t p1, vec3_t p2, vec_t *t1, vec_t *t2)
{
vec3_t origin;
vec3_t dir;
wedge_t *w;
vec_t temp;
int h;
VectorSubtract (p2, p1, dir);
CanonicalVector (dir);
*t1 = DotProduct (p1, dir);
*t2 = DotProduct (p2, dir);
VectorMA (p1, -*t1, dir, origin);
if (*t1 > *t2)
{
temp = *t1;
*t1 = *t2;
*t2 = temp;
}
h = HashVec (origin);
for (w = wedge_hash[h] ; w ; w=w->next)
{
temp = w->origin[0] - origin[0];
if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
continue;
temp = w->origin[1] - origin[1];
if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
continue;
temp = w->origin[2] - origin[2];
if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
continue;
temp = w->dir[0] - dir[0];
if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
continue;
temp = w->dir[1] - dir[1];
if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
continue;
temp = w->dir[2] - dir[2];
if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
continue;
return w;
}
if (numwedges == MAXWEDGES)
Error ("FindEdge: numwedges == MAXWEDGES");
w = &wedges[numwedges];
numwedges++;
w->next = wedge_hash[h];
wedge_hash[h] = w;
VectorCopy (origin, w->origin);
VectorCopy (dir, w->dir);
w->head.next = w->head.prev = &w->head;
w->head.t = 99999;
return w;
}
/*
===============
AddVert
===============
*/
// #define T_EPSILON 0.01
#define T_EPSILON ON_EPSILON
void AddVert (wedge_t *w, vec_t t)
{
wvert_t *v, *newv;
v = w->head.next;
do
{
if (fabs(v->t - t) < T_EPSILON)
return;
if (v->t > t)
break;
v = v->next;
} while (1);
// insert a new wvert before v
if (numwverts == MAXWVERTS)
Error ("AddVert: numwverts == MAXWVERTS");
newv = &wverts[numwverts];
numwverts++;
newv->t = t;
newv->next = v;
newv->prev = v->prev;
v->prev->next = newv;
v->prev = newv;
}
/*
===============
AddEdge
===============
*/
void AddEdge (vec3_t p1, vec3_t p2)
{
wedge_t *w;
vec_t t1, t2;
w = FindEdge(p1, p2, &t1, &t2);
AddVert (w, t1);
AddVert (w, t2);
}
/*
===============
AddFaceEdges
===============
*/
void AddFaceEdges (face_t *f)
{
int i, j;
for (i=0 ; i < f->numpoints ; i++)
{
j = (i+1)%f->numpoints;
AddEdge (f->pts[i], f->pts[j]);
}
}
//============================================================================
// a specially allocated face that can hold hundreds of edges if needed
byte superfacebuf[8192];
face_t *superface = (face_t *)superfacebuf;
int MAXSUPERFACEEDGES = ( sizeof(superfacebuf)-sizeof(face_t)+sizeof(superface->pts)) / sizeof(vec3_t);
void FixFaceEdges (face_t *f);
face_t *newlist;
void SplitFaceForTjunc (face_t *f, face_t *original)
{
int i;
face_t *new, *chain;
vec3_t dir, test;
vec_t v;
int firstcorner, lastcorner;
chain = NULL;
do
{
if (f->numpoints <= MAXPOINTS)
{ // the face is now small enough without more cutting
// so copy it back to the original
*original = *f;
original->original = chain;
original->next = newlist;
newlist = original;
return;
}
tjuncfaces++;
restart:
// find the last corner
VectorSubtract (f->pts[f->numpoints-1], f->pts[0], dir);
VectorNormalize (dir);
for (lastcorner=f->numpoints-1 ; lastcorner > 0 ; lastcorner--)
{
VectorSubtract (f->pts[lastcorner-1], f->pts[lastcorner], test);
VectorNormalize (test);
v = DotProduct (test, dir);
if (v < 1.0-ON_EPSILON || v > 1.0+ON_EPSILON)
{
break;
}
}
// find the first corner
VectorSubtract (f->pts[1], f->pts[0], dir);
VectorNormalize (dir);
for (firstcorner=1 ; firstcorner < f->numpoints-1 ; firstcorner++)
{
VectorSubtract (f->pts[firstcorner+1], f->pts[firstcorner], test);
VectorNormalize (test);
v = DotProduct (test, dir);
if (v < 1.0-ON_EPSILON || v > 1.0+ON_EPSILON)
{
break;
}
}
if (firstcorner+2 >= MAXPOINTS)
{
// rotate the point winding
VectorCopy (f->pts[0], test);
for (i=1 ; i<f->numpoints ; i++)
{
VectorCopy (f->pts[i], f->pts[i-1]);
}
VectorCopy (test, f->pts[f->numpoints-1]);
goto restart;
}
// cut off as big a piece as possible, less than MAXPOINTS, and not
// past lastcorner
new = NewFaceFromFace (f);
if (f->original)
Error ("SplitFaceForTjunc: f->original");
new->original = chain;
chain = new;
new->next = newlist;
newlist = new;
if (f->numpoints - firstcorner <= MAXPOINTS)
new->numpoints = firstcorner+2;
else if (lastcorner+2 < MAXPOINTS &&
f->numpoints - lastcorner <= MAXPOINTS)
new->numpoints = lastcorner+2;
else
new->numpoints = MAXPOINTS;
for (i=0 ; i<new->numpoints ; i++)
{
VectorCopy (f->pts[i], new->pts[i]);
}
for (i=new->numpoints-1 ; i<f->numpoints ; i++)
{
VectorCopy (f->pts[i], f->pts[i-(new->numpoints-2)]);
}
f->numpoints -= (new->numpoints-2);
} while (1);
}
/*
===============
FixFaceEdges
===============
*/
void FixFaceEdges (face_t *f)
{
int i, j, k;
wedge_t *w;
wvert_t *v;
vec_t t1, t2;
*superface = *f;
restart:
for (i=0 ; i < superface->numpoints ; i++)
{
j = (i+1)%superface->numpoints;
w = FindEdge (superface->pts[i], superface->pts[j], &t1, &t2);
for (v=w->head.next ; v->t < t1 + T_EPSILON; v = v->next)
{
}
if (v->t < t2-T_EPSILON)
{
tjuncs++;
// insert a new vertex here
for (k = superface->numpoints ; k> j ; k--)
{
VectorCopy (superface->pts[k-1], superface->pts[k]);
}
VectorMA (w->origin, v->t, w->dir, superface->pts[j]);
superface->numpoints++;
if ( superface->numpoints >= MAXSUPERFACEEDGES )
Error( "FixFaceEdges: Exceeded MAXSUPERFACEEDGES(%d)!\n", MAXSUPERFACEEDGES );
goto restart;
}
}
if (superface->numpoints <= MAXPOINTS)
{
*f = *superface;
f->next = newlist;
newlist = f;
return;
}
// the face needs to be split into multiple faces because of too many edges
SplitFaceForTjunc (superface, f);
}
//============================================================================
void tjunc_find_r (node_t *node)
{
face_t *f;
if (node->planenum == PLANENUM_LEAF)
return;
for (f=node->faces ; f ; f=f->next)
AddFaceEdges (f);
tjunc_find_r (node->children[0]);
tjunc_find_r (node->children[1]);
}
void tjunc_fix_r (node_t *node)
{
face_t *f, *next;
if (node->planenum == PLANENUM_LEAF)
return;
newlist = NULL;
for (f=node->faces ; f ; f=next)
{
next = f->next;
FixFaceEdges (f);
}
node->faces = newlist;
tjunc_fix_r (node->children[0]);
tjunc_fix_r (node->children[1]);
}
/*
===========
tjunc
===========
*/
void tjunc (node_t *headnode)
{
vec3_t maxs, mins;
int i;
qprintf ("---- tjunc ----\n");
if (notjunc)
return;
//
// identify all points on common edges
//
// origin points won't allways be inside the map, so extend the hash area
for (i=0 ; i<3 ; i++)
{
if ( fabs(headnode->maxs[i]) > fabs(headnode->mins[i]) )
maxs[i] = fabs(headnode->maxs[i]);
else
maxs[i] = fabs(headnode->mins[i]);
}
VectorSubtract (vec3_origin, maxs, mins);
InitHash (mins, maxs);
numwedges = numwverts = 0;
tjunc_find_r (headnode);
qprintf ("%i world edges %i edge points\n", numwedges, numwverts);
//
// add extra vertexes on edges where needed
//
tjuncs = tjuncfaces = 0;
tjunc_fix_r (headnode);
qprintf ("%i edges added by tjunctions\n", tjuncs);
qprintf ("%i faces added by tjunctions\n", tjuncfaces);
}

View File

@ -0,0 +1,289 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "bsp5.h"
//===========================================================================
/*
==================
WriteClipNodes_r
==================
*/
int WriteClipNodes_r (node_t *node)
{
int i, c;
dclipnode_t *cn;
int num;
if (node->planenum == -1)
{
num = node->contents;
free (node->markfaces);
free (node);
return num;
}
// emit a clipnode
if (numclipnodes == MAX_MAP_CLIPNODES)
Error ("MAX_MAP_CLIPNODES");
c = numclipnodes;
cn = &dclipnodes[numclipnodes];
numclipnodes++;
if (node->planenum & 1)
Error ("WriteClipNodes_r: odd planenum");
cn->planenum = node->planenum;
for (i=0 ; i<2 ; i++)
cn->children[i] = WriteClipNodes_r(node->children[i]);
free (node);
return c;
}
/*
==================
WriteClipNodes
Called after the clipping hull is completed. Generates a disk format
representation and frees the original memory.
==================
*/
void WriteClipNodes (node_t *nodes)
{
WriteClipNodes_r (nodes);
}
//===========================================================================
/*
==================
WriteDrawLeaf
==================
*/
void WriteDrawLeaf (node_t *node)
{
face_t **fp, *f;
dleaf_t *leaf_p;
// emit a leaf
leaf_p = &dleafs[numleafs];
numleafs++;
leaf_p->contents = node->contents;
//
// write bounding box info
//
VectorCopy (node->mins, leaf_p->mins);
VectorCopy (node->maxs, leaf_p->maxs);
leaf_p->visofs = -1; // no vis info yet
//
// write the marksurfaces
//
leaf_p->firstmarksurface = nummarksurfaces;
for (fp=node->markfaces ; *fp ; fp++)
{
// emit a marksurface
f = *fp;
do
{
dmarksurfaces[nummarksurfaces] = f->outputnumber;
if (nummarksurfaces >= MAX_MAP_MARKSURFACES)
Error ("nummarksurfaces == MAX_MAP_MARKSURFACES");
nummarksurfaces++;
f=f->original; // grab tjunction split faces
} while (f);
}
free (node->markfaces);
leaf_p->nummarksurfaces = nummarksurfaces - leaf_p->firstmarksurface;
}
/*
==================
WriteFace
==================
*/
void WriteFace (face_t *f)
{
dface_t *df;
int i;
int e;
f->outputnumber = numfaces;
df = &dfaces[numfaces];
if (numfaces >= MAX_MAP_FACES)
Error ("numfaces == MAX_MAP_FACES");
numfaces++;
df->planenum = f->planenum & (~1);
df->side = f->planenum & 1;
df->firstedge = numsurfedges;
df->numedges = f->numpoints;
df->texinfo = f->texturenum;
for (i=0 ; i<f->numpoints ; i++)
{
e = GetEdge (f->pts[i], f->pts[(i+1)%f->numpoints], f);
if (numsurfedges >= MAX_MAP_SURFEDGES)
Error ("numsurfedges == MAX_MAP_SURFEDGES");
dsurfedges[numsurfedges] = e;
numsurfedges++;
}
}
/*
==================
WriteDrawNodes_r
==================
*/
void WriteDrawNodes_r (node_t *node)
{
dnode_t *n;
int i;
face_t *f, *next;
// emit a node
if (numnodes == MAX_MAP_NODES)
Error ("numnodes == MAX_MAP_NODES");
n = &dnodes[numnodes];
numnodes++;
VectorCopy (node->mins, n->mins);
VectorCopy (node->maxs, n->maxs);
if (node->planenum & 1)
Error ("WriteDrawNodes_r: odd planenum");
n->planenum = node->planenum;
n->firstface = numfaces;
for (f=node->faces ; f ; f=f->next)
WriteFace (f);
n->numfaces = numfaces - n->firstface;
//
// recursively output the other nodes
//
for (i=0 ; i<2 ; i++)
{
if (node->children[i]->planenum == -1)
{
if (node->children[i]->contents == CONTENTS_SOLID)
n->children[i] = -1;
else
{
n->children[i] = -(numleafs + 1);
WriteDrawLeaf (node->children[i]);
}
}
else
{
n->children[i] = numnodes;
WriteDrawNodes_r (node->children[i]);
}
}
}
/*
===========
FreeDrawNodes_r
===========
*/
void FreeDrawNodes_r (node_t *node)
{
int i;
face_t *f, *next;
for (i=0 ; i<2 ; i++)
if (node->children[i]->planenum != -1)
FreeDrawNodes_r (node->children[i]);
//
// free the faces on the node
//
for (f=node->faces ; f ; f=next)
{
next = f->next;
FreeFace (f);
}
free (node);
}
/*
==================
WriteDrawNodes
Called after a drawing hull is completed
Frees all nodes and faces.
==================
*/
void WriteDrawNodes (node_t *headnode)
{
if (headnode->contents < 0)
WriteDrawLeaf (headnode);
else
{
WriteDrawNodes_r (headnode);
FreeDrawNodes_r (headnode);
}
}
//===========================================================================
/*
==================
BeginBSPFile
==================
*/
void BeginBSPFile (void)
{
// these values may actually be initialized
// if the file existed when loaded, so clear them explicitly
nummodels = 0;
numfaces = 0;
numnodes = 0;
numclipnodes = 0;
numvertexes = 0;
nummarksurfaces = 0;
numsurfedges = 0;
// edge 0 is not used, because 0 can't be negated
numedges = 1;
// leaf 0 is common solid with no faces
numleafs = 1;
dleafs[0].contents = CONTENTS_SOLID;
}
/*
==================
FinishBSPFile
==================
*/
void FinishBSPFile (void)
{
int i;
qprintf ("--- FinishBSPFile ---\n");
if (verbose)
PrintBSPFileSizes ();
WriteBSPFile (bspfilename);
}

987
hlsdk/utils/qcsg/brush.c Normal file
View File

@ -0,0 +1,987 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// brush.c
#include "csg.h"
plane_t mapplanes[MAX_MAP_PLANES];
int nummapplanes;
/*
=============================================================================
PLANE FINDING
=============================================================================
*/
void FindGCD (int *v)
{
int i, j, smallest;
int rem[3];
int val[3];
for (i=0 ; i<3 ; i++)
val[i] = abs(v[i]);
while (1)
{
smallest = 1<<30;
for (i=0 ; i<3 ; i++)
{
j = abs(val[i]);
if (j && j<smallest)
smallest = j;
}
for (i=0 ; i<3 ; i++)
rem[i] = val[i]%smallest;
if (rem[0] + rem[1] + rem[2] == 0)
break; // smallest == gcd
for (i=0 ; i<3 ; i++)
if (!rem[i])
val[i] = smallest;
else
val[i] = rem[i];
}
for (i=0 ; i<3 ; i++)
v[i] /= smallest;
}
int PlaneTypeForNormal (vec3_t normal)
{
vec_t ax, ay, az;
// NOTE: should these have an epsilon around 1.0?
if (normal[0] == 1.0 || normal[0] == -1.0)
return PLANE_X;
if (normal[1] == 1.0 || normal[1] == -1.0)
return PLANE_Y;
if (normal[2] == 1.0 || normal[2] == -1.0)
return PLANE_Z;
ax = fabs(normal[0]);
ay = fabs(normal[1]);
az = fabs(normal[2]);
if (ax >= ay && ax >= az)
return PLANE_ANYX;
if (ay >= ax && ay >= az)
return PLANE_ANYY;
return PLANE_ANYZ;
}
/*
=============
FindIntPlane
Returns which plane number to use for a given integer defined plane.
=============
*/
int FindIntPlane (int *inormal, int *iorigin)
{
int i, j;
plane_t *p, temp;
int t;
vec3_t origin;
qboolean locked;
FindGCD (inormal);
p = mapplanes;
locked = false;
i = 0;
while (1)
{
if (i == nummapplanes)
{
if (!locked)
{
locked = true;
ThreadLock (); // make sure we don't race
}
if (i == nummapplanes)
break; // we didn't race
}
// see if origin is on plane
t = 0;
for (j=0 ; j<3 ; j++)
t += (iorigin[j] - p->iorigin[j]) * inormal[j];
if (!t)
{ // on plane
// see if the normal is forward, backwards, or off
for (j=0 ; j<3 ; j++)
if (inormal[j] != p->inormal[j])
break;
if (j == 3)
{
if (locked)
ThreadUnlock ();
return i;
}
}
i++;
p++;
}
if (!locked)
Error ("not locked");
// create a new plane
for (j=0 ; j<3 ; j++)
{
p->inormal[j] = inormal[j];
(p+1)->inormal[j] = -inormal[j];
p->iorigin[j] = iorigin[j];
(p+1)->iorigin[j] = iorigin[j];
p->normal[j] = inormal[j];
origin[j] = iorigin[j];
}
if (nummapplanes >= MAX_MAP_PLANES)
Error ("MAX_MAP_PLANES");
VectorNormalize (p->normal);
p->type = (p+1)->type = PlaneTypeForNormal (p->normal);
p->dist = DotProduct (origin, p->normal);
VectorSubtract (vec3_origin, p->normal, (p+1)->normal);
(p+1)->dist = -p->dist;
// allways put axial planes facing positive first
if (p->type < 3)
{
if (inormal[0] < 0 || inormal[1] < 0 || inormal[2] < 0)
{
// flip order
temp = *p;
*p = *(p+1);
*(p+1) = temp;
nummapplanes += 2;
ThreadUnlock ();
return i + 1;
}
}
nummapplanes += 2;
ThreadUnlock ();
return i;
}
int PlaneFromPoints (int *p0, int *p1, int *p2)
{
int j;
int t1[3], t2[3];
int normal[3];
// convert to a vector / dist plane
for (j=0 ; j<3 ; j++)
{
t1[j] = p0[j] - p1[j];
t2[j] = p2[j] - p1[j];
}
FindGCD (t1);
FindGCD (t2);
normal[0] = t1[1]*t2[2] - t1[2]*t2[1];
normal[1] = t1[2]*t2[0] - t1[0]*t2[2];
normal[2] = t1[0]*t2[1] - t1[1]*t2[0];
if (!normal[0] && !normal[1] && !normal[2])
return -1;
return FindIntPlane (normal, p0);
}
/*
=============================================================================
TURN BRUSHES INTO GROUPS OF FACES
=============================================================================
*/
void ScaleUpIVector (int *iv, int min)
{
int i;
int largest, scale;
largest = 0;
for (i=0 ; i<3 ; i++)
{
if (abs(iv[i]) > largest)
largest = abs(iv[i]);
}
scale = (min + largest - 1)/largest;
for (i=0 ; i<3 ; i++)
iv[i] *= scale;
}
/*
=================
BaseWindingForIPlane
=================
*/
winding_t *BaseWindingForIPlane (plane_t *p)
{
int i, x;
vec_t max, v;
winding_t *w;
int org[3], vup[3], vright[3];
VectorCopy (p->iorigin, org);
VectorCopy (vec3_origin, vup);
VectorCopy (vec3_origin, vright);
if (!p->inormal[1] && !p->inormal[2])
{
vup[2] = 8192;
vright[1] = 8192*p->normal[0];
}
else if (!p->inormal[0] && !p->inormal[2])
{
vup[2] = 8192;
vright[0] = -8192*p->normal[1];
}
else if (!p->inormal[0] && !p->inormal[1])
{
vup[1] = 8192;
vright[0] = 8192*p->normal[2];
}
else
{
vup[0] = -2*p->inormal[1]*p->inormal[2];
vup[1] = p->inormal[0]*p->inormal[2];
vup[2] = p->inormal[0]*p->inormal[1];
FindGCD (vup);
vright[0] = vup[1]*p->inormal[2] - vup[2]*p->inormal[1];
vright[1] = vup[2]*p->inormal[0] - vup[0]*p->inormal[2];
vright[2] = vup[0]*p->inormal[1] - vup[1]*p->inormal[0];
FindGCD (vright);
ScaleUpIVector (vup, 8192);
ScaleUpIVector (vright, 8192);
}
w = AllocWinding (4);
VectorSubtract (org, vright, w->p[0]);
VectorAdd (w->p[0], vup, w->p[0]);
VectorAdd (org, vright, w->p[1]);
VectorAdd (w->p[1], vup, w->p[1]);
VectorAdd (org, vright, w->p[2]);
VectorSubtract (w->p[2], vup, w->p[2]);
VectorSubtract (org, vright, w->p[3]);
VectorSubtract (w->p[3], vup, w->p[3]);
w->numpoints = 4;
return w;
}
/*
==============================================================================
BEVELED CLIPPING HULL GENERATION
This is done by brute force, and could easily get a lot faster if anyone cares.
==============================================================================
*/
#if 0
vec3_t hull_size[NUM_HULLS][2] = {
{ {0, 0, 0}, {0, 0, 0} },
{ {-16,-16,-32}, {16,16,24} },
{ {-32,-32,-64}, {32,32,24} }
};
#endif
#if 1
vec3_t hull_size[NUM_HULLS][2] = {
{ {0, 0, 0}, {0, 0, 0} },
{ {-16,-16,-36}, {16,16,36} },// 32x32x72
{ {-32,-32,-32}, {32,32,32} }, // 64x64x64
{ {-16,-16,-18}, {16,16,18} } // 32x32x36
};
#endif
#define MAX_HULL_POINTS 32
#define MAX_HULL_EDGES 64
typedef struct
{
brush_t *b;
int hullnum;
int num_hull_points;
vec3_t hull_points[MAX_HULL_POINTS];
vec3_t hull_corners[MAX_HULL_POINTS*8];
int num_hull_edges;
int hull_edges[MAX_HULL_EDGES][2];
} expand_t;
/*
=============
IPlaneEquiv
=============
*/
qboolean IPlaneEquiv (plane_t *p1, plane_t *p2)
{
int t;
int j;
// see if origin is on plane
t = 0;
for (j=0 ; j<3 ; j++)
t += (p2->iorigin[j] - p1->iorigin[j]) * p2->inormal[j];
if (t)
return false;
// see if the normal is forward, backwards, or off
for (j=0 ; j<3 ; j++)
if (p2->inormal[j] != p1->inormal[j])
break;
if (j == 3)
return true;
for (j=0 ; j<3 ; j++)
if (p2->inormal[j] != -p1->inormal[j])
break;
if (j == 3)
return true;
return false;
}
/*
============
AddBrushPlane
=============
*/
void AddBrushPlane (expand_t *ex, plane_t *plane)
{
int i;
plane_t *pl;
bface_t *f, *nf;
brushhull_t *h;
h = &ex->b->hulls[ex->hullnum];
// see if the plane has allready been added
for (f=h->faces ; f ; f=f->next)
{
pl = f->plane;
if (IPlaneEquiv (plane, pl))
return;
}
nf = malloc(sizeof(*nf));
memset (nf, 0, sizeof(*nf));
nf->planenum = FindIntPlane (plane->inormal, plane->iorigin);
nf->plane = &mapplanes[nf->planenum];
nf->next = h->faces;
nf->contents = CONTENTS_EMPTY;
h->faces = nf;
nf->texinfo = 0; // all clip hulls have same texture
}
/*
============
TestAddPlane
Adds the given plane to the brush description if all of the original brush
vertexes can be put on the front side
=============
*/
void TestAddPlane (expand_t *ex, plane_t *plane)
{
int i, j, c, t;
vec_t d;
vec_t *corner;
plane_t flip;
vec3_t inv;
int counts[3];
plane_t *pl;
bface_t *f, *nf;
brushhull_t *h;
// see if the plane has allready been added
h = &ex->b->hulls[ex->hullnum];
for (f=h->faces ; f ; f=f->next)
{
pl = f->plane;
if (IPlaneEquiv (plane, pl))
return;
}
// check all the corner points
counts[0] = counts[1] = counts[2] = 0;
c = ex->num_hull_points * 8;
corner = ex->hull_corners[0];
for (i=0 ; i<c ; i++, corner += 3)
{
t = 0;
for (j=0 ; j<3 ; j++)
t += (corner[j] - plane->iorigin[j]) * plane->inormal[j];
if (t < 0)
{
if (counts[0])
return;
counts[1]++;
}
else if (t > 0)
{
if (counts[1])
return;
counts[0]++;
}
else
counts[2]++;
}
// the plane is a seperator
if (counts[0])
{
VectorSubtract (vec3_origin, plane->inormal, flip.inormal);
VectorCopy (plane->iorigin, flip.iorigin);
plane = &flip;
}
nf = malloc(sizeof(*nf));
memset (nf, 0, sizeof(*nf));
nf->planenum = FindIntPlane (plane->inormal, plane->iorigin);
nf->plane = &mapplanes[nf->planenum];
nf->next = h->faces;
nf->contents = CONTENTS_EMPTY;
h->faces = nf;
nf->texinfo = 0; // all clip hulls have same texture
}
/*
============
AddHullPoint
Doesn't add if duplicated
=============
*/
int AddHullPoint (expand_t *ex, vec3_t p)
{
int i, j;
vec_t *c;
int x,y,z;
vec3_t r;
for (i=0 ; i<3 ; i++)
r[i] = floor (p[i]+0.5);
for (i=0 ; i<ex->num_hull_points ; i++)
{
for (j=0 ; j<3 ; j++)
if (r[j] != ex->hull_points[i][j])
break;
if (j == 3)
return i; // allready added
}
if (ex->num_hull_points == MAX_HULL_POINTS)
Error ("MAX_HULL_POINTS");
ex->num_hull_points++;
VectorCopy (r, ex->hull_points[ex->num_hull_points]);
c = ex->hull_corners[i*8];
for (x=0 ; x<2 ; x++)
for (y=0 ; y<2 ; y++)
for (z=0; z<2 ; z++)
{
c[0] = r[0] + hull_size[ex->hullnum][x][0];
c[1] = r[1] + hull_size[ex->hullnum][y][1];
c[2] = r[2] + hull_size[ex->hullnum][z][2];
c += 3;
}
return i;
}
/*
============
AddHullEdge
Creates all of the hull planes around the given edge, if not done allready
=============
*/
//#define ANGLEEPSILON 0.00001
#define ANGLEEPSILON ON_EPSILON
void AddHullEdge (expand_t *ex, vec3_t p1, vec3_t p2)
{
int pt1, pt2;
int i;
int a, b, c, d, e;
vec3_t edgevec, planeorg, planevec;
plane_t plane;
vec_t l;
pt1 = AddHullPoint (ex, p1);
pt2 = AddHullPoint (ex, p2);
// now use the rounded values
p1 = ex->hull_points[pt1];
p2 = ex->hull_points[pt2];
for (i=0 ; i<ex->num_hull_edges ; i++)
if ( (ex->hull_edges[i][0] == pt1 && ex->hull_edges[i][1] == pt2)
|| (ex->hull_edges[i][0] == pt2 && ex->hull_edges[i][1] == pt1) )
return; // allread added
if (ex->num_hull_edges == MAX_HULL_EDGES)
Error ("MAX_HULL_EDGES");
ex->hull_edges[i][0] = pt1;
ex->hull_edges[i][1] = pt2;
ex->num_hull_edges++;
VectorSubtract (p1, p2, edgevec);
VectorNormalize (edgevec);
for (a=0 ; a<3 ; a++)
{
b = (a+1)%3;
c = (a+2)%3;
for (d=0 ; d<=1 ; d++)
for (e=0 ; e<=1 ; e++)
{
VectorCopy (p1, plane.iorigin);
plane.iorigin[b] += hull_size[ex->hullnum][d][b];
plane.iorigin[c] += hull_size[ex->hullnum][e][c];
VectorCopy (vec3_origin, planevec);
planevec[a] = 1;
plane.inormal[0] = planevec[1]*edgevec[2] - planevec[2]*edgevec[1];
plane.inormal[1] = planevec[2]*edgevec[0] - planevec[0]*edgevec[2];
plane.inormal[2] = planevec[0]*edgevec[1] - planevec[1]*edgevec[0];
if (!plane.inormal[0] && !plane.inormal[1] && !plane.inormal[2])
continue; // degenerate
TestAddPlane (ex, &plane);
}
}
}
/*
============
ExpandBrush
=============
*/
void ExpandBrush (brush_t *b, int hullnum)
{
int i, x, s;
int corner;
bface_t *brush_faces, *f, *nf;
plane_t *p, plane;
int iorigin[3], inormal[3];
expand_t ex;
brushhull_t *h;
qboolean axial;
brush_faces = b->hulls[0].faces;
h = &b->hulls[hullnum];
ex.b = b;
ex.hullnum = hullnum;
ex.num_hull_points = 0;
ex.num_hull_edges = 0;
// expand all of the planes
axial = true;
for (f=brush_faces ; f ; f=f->next)
{
p = f->plane;
if (p->type > PLANE_Z)
axial = false; // not an xyz axial plane
VectorCopy (p->iorigin, iorigin);
VectorCopy (p->inormal, inormal);
for (x=0 ; x<3 ; x++)
{
if (p->normal[x] > 0)
corner = hull_size[hullnum][1][x];
else if (p->normal[x] < 0)
corner = - hull_size[hullnum][0][x];
else
corner = 0;
iorigin[x] += p->normal[x]*corner;
}
nf = malloc(sizeof(*nf));
memset (nf, 0, sizeof(*nf));
nf->planenum = FindIntPlane (inormal, iorigin);
nf->plane = &mapplanes[nf->planenum];
nf->next = h->faces;
nf->contents = CONTENTS_EMPTY;
h->faces = nf;
nf->texinfo = 0; // all clip hulls have same texture
}
// if this was an axial brush, we are done
if (axial)
return;
#if 1
// add any axis planes not contained in the brush to bevel off corners
for (x=0 ; x<3 ; x++)
for (s=-1 ; s<=1 ; s+=2)
{
// add the plane
VectorCopy (vec3_origin, plane.inormal);
plane.inormal[x] = s;
if (s == -1)
{
VectorAdd (b->hulls[0].mins, hull_size[hullnum][0], plane.iorigin);
}
else
{
VectorAdd (b->hulls[0].maxs, hull_size[hullnum][1], plane.iorigin);
}
AddBrushPlane (&ex, &plane);
}
#endif
#if 0
// create all the hull points
for (f=brush_faces ; f ; f=f->next)
for (i=0 ; i<f->w->numpoints ; i++)
AddHullPoint (&ex, f->w->p[i]);
// add all of the edge bevels
for (f=brush_faces ; f ; f=f->next)
for (i=0 ; i<f->w->numpoints ; i++)
AddHullEdge (&ex, f->w->p[i], f->w->p[(i+1)%f->w->numpoints]);
#endif
}
//============================================================================
/*
===========
MakeHullFaces
===========
*/
void MakeHullFaces (brush_t *b, brushhull_t *h)
{
bface_t *f, *f2;
winding_t *w;
plane_t *p;
int i, j;
vec_t v;
vec_t area;
restart:
h->mins[0] = h->mins[1] = h->mins[2] = 9999;
h->maxs[0] = h->maxs[1] = h->maxs[2] = -9999;
for (f = h->faces ; f ; f=f->next)
{
// w = BaseWindingForIPlane (f->plane);
w = BaseWindingForPlane (f->plane->normal, f->plane->dist);
for (f2 = h->faces ; f2 && w ; f2=f2->next)
{
if (f == f2)
continue;
p = &mapplanes[f2->planenum ^ 1];
w = ChopWinding (w, p->normal, p->dist);
}
area = w ? WindingArea(w) : 0;
if (area < 0.1)
{
qprintf ("Entity %i, Brush %i: plane with area %4.2f\n"
, b->entitynum, b->brushnum, area);
// remove the face and regenerate the hull
if (h->faces == f)
h->faces = f->next;
else
{
for (f2=h->faces ; f2->next != f ; f2=f2->next)
;
f2->next = f->next;
}
goto restart;
}
f->w = w;
f->contents = CONTENTS_EMPTY;
if (w)
{
for (i=0 ; i<w->numpoints ; i++)
{
for (j=0 ; j<3 ; j++)
{
v = w->p[i][j];
// w->p[i][j] = floor (v+0.5); // round to int
if (v<h->mins[j])
h->mins[j] = v;
if (v>h->maxs[j])
h->maxs[j] = v;
}
}
}
}
for (i=0 ; i<3 ; i++)
{
if (h->mins[i] < -BOGUS_RANGE/2
|| h->maxs[i] > BOGUS_RANGE/2)
{
vec3_t eorigin = { 0, 0, 0};
char *pszClass = "Unknown Class";
if ( b->entitynum )
{
entity_t *e = entities + b->entitynum;
pszClass = ValueForKey(e, "classname" );
GetVectorForKey( e, "origin", eorigin );
}
printf( "Entity %i, Brush %i: A '%s' @(%.0f,%.0f,%.0f)\n",
b->entitynum, b->brushnum, pszClass, eorigin[0], eorigin[1], eorigin[2] );
printf( "\toutside world(+/-%d): (%.0f, %.0f, %.0f)-(%.0f,%.0f,%.0f)\n",
BOGUS_RANGE/2, h->mins[0], h->mins[1], h->mins[2], h->maxs[0], h->maxs[1], h->maxs[2] );
break;
}
}
}
/*
===========
MakeBrushPlanes
===========
*/
qboolean MakeBrushPlanes (brush_t *b)
{
int i, j;
int planenum;
side_t *s;
int contents;
bface_t *f;
vec3_t origin;
//
// if the origin key is set (by an origin brush), offset all of the values
//
GetVectorForKey (&entities[b->entitynum], "origin", origin);
//
// convert to mapplanes
//
for (i=0 ; i<b->numsides ; i++)
{
s = &brushsides[b->firstside + i];
for (j=0 ; j<3 ; j++)
{
VectorSubtract (s->planepts[j], origin, s->planepts[j]);
}
planenum = PlaneFromPoints (s->planepts[0], s->planepts[1], s->planepts[2]);
if (planenum == -1)
{
printf ("Entity %i, Brush %i: plane with no normal\n"
, b->entitynum, b->brushnum);
continue;
}
//
// see if the plane has been used already
//
for (f=b->hulls[0].faces ; f ; f=f->next)
{
if (f->planenum == planenum || f->planenum == (planenum^1) )
{
char *pszClass = "Unknown Class";
if ( b->entitynum )
{
entity_t *e = entities + b->entitynum;
pszClass = ValueForKey(e, "classname" );
}
printf( "Entity %i, Brush %i: A '%s' @(%.0f,%.0f,%.0f) has a coplanar plane at (%.0f, %.0f, %.0f), texture %s\n",
b->entitynum, b->brushnum, pszClass, origin[0], origin[1], origin[2], s->planepts[0][0]+origin[0], s->planepts[0][1]+origin[1], s->planepts[0][2]+origin[2], s->td.name );
return false;
}
}
f = malloc(sizeof(*f));
memset (f, 0, sizeof(*f));
f->planenum = planenum;
f->plane = &mapplanes[planenum];
f->next = b->hulls[0].faces;
b->hulls[0].faces = f;
f->texinfo = onlyents ? 0 : TexinfoForBrushTexture (f->plane, &s->td, origin);
}
return true;
}
/*
===========
TextureContents
===========
*/
int TextureContents (char *name)
{
if (!Q_strncasecmp (name, "sky",3))
return CONTENTS_SKY;
if (!Q_strncasecmp(name+1,"!lava",5))
return CONTENTS_LAVA;
if (!Q_strncasecmp(name+1,"!slime",6))
return CONTENTS_SLIME;
if (!Q_strncasecmp (name, "!cur_90",7))
return CONTENTS_CURRENT_90;
if (!Q_strncasecmp (name, "!cur_0",6))
return CONTENTS_CURRENT_0;
if (!Q_strncasecmp (name, "!cur_270",8))
return CONTENTS_CURRENT_270;
if (!Q_strncasecmp (name, "!cur_180",8))
return CONTENTS_CURRENT_180;
if (!Q_strncasecmp (name, "!cur_up",7))
return CONTENTS_CURRENT_UP;
if (!Q_strncasecmp (name, "!cur_dwn",8))
return CONTENTS_CURRENT_DOWN;
if (name[0] == '!')
return CONTENTS_WATER;
if (!Q_strncasecmp (name, "origin",6))
return CONTENTS_ORIGIN;
if (!Q_strncasecmp (name, "clip",4))
return CONTENTS_CLIP;
if( !Q_strncasecmp( name, "translucent", 11 ) )
return CONTENTS_TRANSLUCENT;
if( name[0] == '@' )
return CONTENTS_TRANSLUCENT;
return CONTENTS_SOLID;
}
/*
===========
BrushContents
===========
*/
int BrushContents (brush_t *b)
{
char *name;
int contents;
bface_t *f;
side_t *s;
int i;
s = &brushsides[b->firstside];
contents = TextureContents (s->td.name);
for (i=1 ; i<b->numsides ; i++, s++)
{
if (TextureContents(s->td.name) != contents)
{
printf ("Entity %i, Brush %i: mixed face contents"
, b->entitynum, b->brushnum);
break;
}
}
return contents;
}
/*
===========
CreateBrush
===========
*/
void CreateBrush (int brushnum)
{
brush_t *b;
int contents;
int h;
SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL);
b = &mapbrushes[brushnum];
contents = b->contents;
if (contents == CONTENTS_ORIGIN)
return;
//
// convert brush sides to planes
//
MakeBrushPlanes (b);
MakeHullFaces (b, &b->hulls[0]);
// water brushes are not solid, so are not represented in
// the clipping hull
if (contents == CONTENTS_LAVA
|| contents == CONTENTS_SLIME
|| contents == CONTENTS_WATER
|| contents == CONTENTS_TRANSLUCENT )
return;
if (!noclip)
{
for (h=1 ; h<NUM_HULLS ; h++)
{
ExpandBrush (b, h);
MakeHullFaces (b, &b->hulls[h]);
}
}
// clip brushes don't stay in the drawing hull
if (contents == CONTENTS_CLIP)
{
b->hulls[0].faces = NULL;
b->contents = CONTENTS_SOLID;
}
}

144
hlsdk/utils/qcsg/csg.h Normal file
View File

@ -0,0 +1,144 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "cmdlib.h"
#include "mathlib.h"
#include "scriplib.h"
#include "polylib.h"
#include "threads.h"
#include "bspfile.h"
#include <windows.h>
#ifndef DOUBLEVEC_T
#error you must add -dDOUBLEVEC_T to the project!
#endif
#define BOGUS_RANGE 8192
typedef struct
{
vec3_t normal;
vec_t dist;
int type;
int iorigin[3];
int inormal[3];
} plane_t;
extern plane_t mapplanes[MAX_MAP_PLANES];
extern int nummapplanes;
extern int g_nMapFileVersion; // map file version * 100 (ie 201), zero for pre-Worldcraft 2.0.1 maps
typedef struct
{
vec3_t UAxis;
vec3_t VAxis;
vec_t shift[2];
vec_t rotate;
vec_t scale[2];
char name[32];
} brush_texture_t;
typedef struct side_s
{
brush_texture_t td;
int planepts[3][3];
} side_t;
typedef struct bface_s
{
struct bface_s *next;
int planenum;
plane_t *plane;
winding_t *w;
int texinfo;
qboolean used; // just for face counting
int contents, backcontents;
vec3_t mins, maxs;
} bface_t;
#define NUM_HULLS 4 // no larger than MAX_MAP_HULLS
typedef struct
{
vec3_t mins, maxs;
bface_t *faces;
} brushhull_t;
typedef struct brush_s
{
int entitynum;
int brushnum;
int firstside;
int numsides;
int contents;
brushhull_t hulls[NUM_HULLS];
} brush_t;
extern int nummapbrushes;
extern brush_t mapbrushes[MAX_MAP_BRUSHES];
#define MAX_MAP_SIDES (MAX_MAP_BRUSHES*6)
extern int numbrushplanes;
extern plane_t planes[MAX_MAP_PLANES];
extern int numbrushsides;
extern side_t brushsides[MAX_MAP_SIDES];
extern qboolean noclip;
extern qboolean wadtextures;
int nWadInclude;
char *pszWadInclude[];
void LoadMapFile (char *filename);
//=============================================================================
// textures.c
extern int nummiptex;
void WriteMiptex (void);
int TexinfoForBrushTexture (plane_t *plane, brush_texture_t *bt, vec3_t origin);
//=============================================================================
// brush.c
void FindGCD (int *v);
brush_t *Brush_LoadEntity (entity_t *ent, int hullnum);
int PlaneTypeForNormal (vec3_t normal);
void CreateBrush (int brushnum);
//=============================================================================
// csg.c
bface_t *NewFaceFromFace (bface_t *in);
extern qboolean onlyents;
//=============================================================================
// draw.c
extern vec3_t draw_mins, draw_maxs;
extern qboolean drawflag;
void Draw_ClearWindow (void);
void DrawWinding (winding_t *w);

154
hlsdk/utils/qcsg/gldraw.c Normal file
View File

@ -0,0 +1,154 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include "csg.h"
// can't use the glvertex3fv functions, because the vec3_t fields
// could be either floats or doubles, depending on DOUBLEVEC_T
qboolean drawflag;
vec3_t draw_mins, draw_maxs;
#define WIN_SIZE 512
void InitWindow (void)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGB);
auxInitPosition (0, 0, WIN_SIZE, WIN_SIZE);
auxInitWindow ("qcsg");
}
void Draw_ClearWindow (void)
{
static int init;
int w, h, g;
vec_t mx, my;
if (!drawflag)
return;
if (!init)
{
init = true;
InitWindow ();
}
glClearColor (1,0.8,0.8,0);
glClear (GL_COLOR_BUFFER_BIT);
w = (draw_maxs[0] - draw_mins[0]);
h = (draw_maxs[1] - draw_mins[1]);
mx = draw_mins[0] + w/2;
my = draw_mins[1] + h/2;
g = w > h ? w : h;
glLoadIdentity ();
gluPerspective (90, 1, 2, 16384);
gluLookAt (mx, my, draw_maxs[2] + g/2, mx , my, draw_maxs[2], 0, 1, 0);
glColor3f (0,0,0);
// glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glDisable (GL_DEPTH_TEST);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#if 0
glColor4f (1,0,0,0.5);
glBegin (GL_POLYGON);
glVertex3f (0, 500, 0);
glVertex3f (0, 900, 0);
glVertex3f (0, 900, 100);
glVertex3f (0, 500, 100);
glEnd ();
#endif
glFlush ();
}
void Draw_SetRed (void)
{
if (!drawflag)
return;
glColor3f (1,0,0);
}
void Draw_SetGrey (void)
{
if (!drawflag)
return;
glColor3f (0.5,0.5,0.5);
}
void Draw_SetBlack (void)
{
if (!drawflag)
return;
glColor3f (0,0,0);
}
void DrawWinding (winding_t *w)
{
int i;
if (!drawflag)
return;
glColor4f (0,0,0,0.5);
glBegin (GL_LINE_LOOP);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glColor4f (0,1,0,0.3);
glBegin (GL_POLYGON);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glFlush ();
}
void DrawAuxWinding (winding_t *w)
{
int i;
if (!drawflag)
return;
glColor4f (0,0,0,0.5);
glBegin (GL_LINE_LOOP);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glColor4f (1,0,0,0.3);
glBegin (GL_POLYGON);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glFlush ();
}

View File

@ -0,0 +1,87 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "csg.h"
extern vec3_t hull_size[NUM_HULLS][2];
/*
============
CheckHullFile
============
*/
void CheckHullFile( qboolean hullfile, char *filename )
{
FILE *f;
char scan[ 128 ];
vec3_t new_hulls[NUM_HULLS][2];
qboolean read_error = false;
int i;
if ( !hullfile )
return;
// Open up hull file
f = fopen (filename, "r");
if ( !f )
{
printf ("WARNING: Couldn't open hullfile %s, using default hulls", filename );
return;
}
else
{
printf("[Reading hulls from '%s']\n", filename);
}
for ( i = 0 ; i < NUM_HULLS; i++ )
{
float x1, y1, z1, x2, y2, z2;
vec3_t mins, maxs;
int argCnt;
if ( !fgets(scan, sizeof(scan), f ) )
{
printf ("WARNING: Error parsing %s, couln't read hull line %i, using default hulls", filename, i );
read_error = true;
break;
}
argCnt = sscanf (scan, "( %f %f %f ) ( %f %f %f ) ", &x1, &y1, &z1, &x2, &y2, &z2 );
if ( argCnt != 6 )
{
printf ("WARNING: Error parsing %s, expeciting '( x y z ) ( x y z )' using default hulls", filename );
read_error = true;
break;
}
else
{
mins[0] = x1;
mins[1] = y1;
mins[2] = z1;
maxs[0] = x2;
maxs[1] = y2;
maxs[2] = z2;
}
VectorCopy( mins, new_hulls[ i ][ 0 ] );
VectorCopy( maxs, new_hulls[ i ][ 1 ] );
}
if ( read_error )
{
printf ("WARNING: Error parsing %s, using default hulls", filename );
}
else
{
memcpy( hull_size, new_hulls, 2 * NUM_HULLS * sizeof( vec3_t ) );
}
fclose( f );
}

View File

@ -0,0 +1,4 @@
( 0 0 0 ) ( 0 0 0 )
( -16 -16 -24 ) ( 16 16 32 )
( -32 -32 -32 ) ( 32 32 32 )
( -16 -16 -24 ) ( 16 16 32 )

344
hlsdk/utils/qcsg/map.c Normal file
View File

@ -0,0 +1,344 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "csg.h"
int nummapbrushes;
brush_t mapbrushes[MAX_MAP_BRUSHES];
int numbrushsides;
side_t brushsides[MAX_MAP_SIDES];
int g_nMapFileVersion;
/*
==================
textureAxisFromPlane
==================
*/
vec3_t baseaxis[18] =
{
{0,0,1}, {1,0,0}, {0,-1,0}, // floor
{0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling
{1,0,0}, {0,1,0}, {0,0,-1}, // west wall
{-1,0,0}, {0,1,0}, {0,0,-1}, // east wall
{0,1,0}, {1,0,0}, {0,0,-1}, // south wall
{0,-1,0}, {1,0,0}, {0,0,-1} // north wall
};
void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv)
{
int bestaxis;
vec_t dot,best;
int i;
best = 0;
bestaxis = 0;
for (i=0 ; i<6 ; i++)
{
dot = DotProduct (pln->normal, baseaxis[i*3]);
if (dot > best)
{
best = dot;
bestaxis = i;
}
}
VectorCopy (baseaxis[bestaxis*3+1], xv);
VectorCopy (baseaxis[bestaxis*3+2], yv);
}
/*
=================
ParseBrush
=================
*/
void ParseBrush (entity_t *mapent)
{
brush_t *b;
bface_t *f, *f2;
int planepts[3][3];
vec3_t t1, t2, t3;
int i,j;
vec_t d;
int planenum;
side_t *side;
int contents;
if (nummapbrushes == MAX_MAP_BRUSHES)
Error ("nummapbrushes == MAX_MAP_BRUSHES");
b = &mapbrushes[nummapbrushes];
nummapbrushes++;
b->firstside = numbrushsides;
b->entitynum = num_entities-1;
b->brushnum = nummapbrushes - mapent->firstbrush - 1;
mapent->numbrushes++;
do
{
if (!GetToken (true))
break;
if (!strcmp (token, "}") )
break;
if (numbrushsides == MAX_MAP_SIDES)
Error ("numbrushsides == MAX_MAP_SIDES");
side = &brushsides[numbrushsides];
numbrushsides++;
b->numsides++;
// read the three point plane definition
for (i=0 ; i<3 ; i++)
{
if (i != 0)
GetToken (true);
if (strcmp (token, "(") )
Error ("parsing brush");
for (j=0 ; j<3 ; j++)
{
GetToken (false);
side->planepts[i][j] = atoi(token);
}
GetToken (false);
if (strcmp (token, ")") )
Error ("parsing brush");
}
// read the texturedef
GetToken (false);
strcpy (side->td.name, token);
if (g_nMapFileVersion < 220)
{
GetToken (false);
side->td.shift[0] = atof(token);
GetToken (false);
side->td.shift[1] = atof(token);
GetToken (false);
side->td.rotate = atof(token);
}
else
{
// texture U axis
GetToken (false);
if (strcmp (token, "["))
{
Error("missing '[ in texturedef");
}
GetToken (false);
side->td.UAxis[0] = atof(token);
GetToken (false);
side->td.UAxis[1] = atof(token);
GetToken (false);
side->td.UAxis[2] = atof(token);
GetToken (false);
side->td.shift[0] = atof(token);
GetToken (false);
if (strcmp (token, "]"))
{
Error("missing ']' in texturedef");
}
// texture V axis
GetToken (false);
if (strcmp (token, "["))
{
Error("missing '[ in texturedef");
}
GetToken (false);
side->td.VAxis[0] = atof(token);
GetToken (false);
side->td.VAxis[1] = atof(token);
GetToken (false);
side->td.VAxis[2] = atof(token);
GetToken (false);
side->td.shift[1] = atof(token);
GetToken (false);
if (strcmp (token, "]"))
{
Error("missing ']' in texturedef");
}
// Texture rotation is implicit in U/V axes.
GetToken(false);
side->td.rotate = 0;
}
// texure scale
GetToken (false);
side->td.scale[0] = atof(token);
GetToken (false);
side->td.scale[1] = atof(token);
} while (1);
b->contents = contents = BrushContents (b);
//
// origin brushes are removed, but they set
// the rotation origin for the rest of the brushes
// in the entity
//
if (contents == CONTENTS_ORIGIN)
{
char string[32];
vec3_t origin;
b->contents = CONTENTS_SOLID;
CreateBrush (mapent->firstbrush + b->brushnum); // to get sizes
b->contents = contents;
for (i = 0; i < NUM_HULLS; i++) {
b->hulls[i].faces = NULL;
}
if (b->entitynum == 0)
{
printf ("Entity %i, Brush %i: origin brushes not allowed in world"
, b->entitynum, b->brushnum);
return;
}
VectorAdd (b->hulls[0].mins, b->hulls[0].maxs, origin);
VectorScale (origin, 0.5, origin);
sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
SetKeyValue (&entities[b->entitynum], "origin", string);
}
}
/*
================
ParseMapEntity
================
*/
qboolean ParseMapEntity (void)
{
entity_t *mapent;
epair_t *e;
if (!GetToken (true))
return false;
if (strcmp (token, "{") )
Error ("ParseEntity: { not found");
if (num_entities == MAX_MAP_ENTITIES)
Error ("num_entities == MAX_MAP_ENTITIES");
mapent = &entities[num_entities];
num_entities++;
mapent->firstbrush = nummapbrushes;
mapent->numbrushes = 0;
do
{
if (!GetToken (true))
Error ("ParseEntity: EOF without closing brace");
if (!strcmp (token, "}") )
break;
if (!strcmp (token, "{") )
ParseBrush (mapent);
else
{
e = ParseEpair ();
if (!strcmp(e->key, "mapversion"))
{
g_nMapFileVersion = atoi(e->value);
}
e->next = mapent->epairs;
mapent->epairs = e;
}
} while (1);
if ( mapent->numbrushes == 1 && mapbrushes[mapent->firstbrush].contents == CONTENTS_ORIGIN )
{
brushhull_t *hull = mapbrushes[mapent->firstbrush].hulls;
Error("Found an entity with ONLY an origin brush near(%.0f,%.0f,%.0f)!\n",
hull->mins[0], hull->mins[1], hull->mins[2] );
}
GetVectorForKey (mapent, "origin", mapent->origin);
// group entities are just for editor convenience
// toss all brushes into the world entity
if ( !onlyents && !strcmp ("func_group", ValueForKey (mapent, "classname")))
{
// this is pretty gross, because the brushes are expected to be
// in linear order for each entity
brush_t *temp;
int newbrushes;
int worldbrushes;
int i;
newbrushes = mapent->numbrushes;
worldbrushes = entities[0].numbrushes;
temp = malloc(newbrushes*sizeof(brush_t));
memcpy (temp, mapbrushes + mapent->firstbrush, newbrushes*sizeof(brush_t));
for (i=0 ; i<newbrushes ; i++)
temp[i].entitynum = 0;
// make space to move the brushes (overlapped copy)
memmove (mapbrushes + worldbrushes + newbrushes,
mapbrushes + worldbrushes,
sizeof(brush_t) * (nummapbrushes - worldbrushes - newbrushes) );
// copy the new brushes down
memcpy (mapbrushes + worldbrushes, temp, sizeof(brush_t) * newbrushes);
// fix up indexes
num_entities--;
entities[0].numbrushes += newbrushes;
for (i=1 ; i<num_entities ; i++)
entities[i].firstbrush += newbrushes;
memset (mapent,0, sizeof(*mapent));
free (temp);
}
return true;
}
/*
================
LoadMapFile
================
*/
void LoadMapFile (char *filename)
{
LoadScriptFile (filename);
num_entities = 0;
while (ParseMapEntity ())
{
}
qprintf ("Load map:%s\n", filename);
qprintf ("%5i brushes\n", nummapbrushes);
qprintf ("%5i entities\n", num_entities);
}

View File

@ -0,0 +1,172 @@
# Microsoft Developer Studio Project File - Name="qcsg" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=qcsg - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "qcsg.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "qcsg.mak" CFG="qcsg - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "qcsg - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "qcsg - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/SDKSrc/Tools/utils/qcsg", XUGBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "qcsg - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /MT /GX /O2 /I "..\..\common" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "DOUBLEVEC_T" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "qcsg - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\Debug"
# PROP Intermediate_Dir ".\Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /MTd /Gm /GX /ZI /Od /I "..\..\common" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "DOUBLEVEC_T" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
# ADD LINK32 opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386
!ENDIF
# Begin Target
# Name "qcsg - Win32 Release"
# Name "qcsg - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\brush.c
# End Source File
# Begin Source File
SOURCE=..\..\common\bspfile.c
# End Source File
# Begin Source File
SOURCE=..\..\common\cmdlib.c
# End Source File
# Begin Source File
SOURCE=..\gldraw.c
# End Source File
# Begin Source File
SOURCE=..\hullfile.c
# End Source File
# Begin Source File
SOURCE=..\map.c
# End Source File
# Begin Source File
SOURCE=..\..\common\mathlib.c
# End Source File
# Begin Source File
SOURCE=..\..\common\polylib.c
# End Source File
# Begin Source File
SOURCE=..\qcsg.c
# End Source File
# Begin Source File
SOURCE=..\..\common\scriplib.c
# End Source File
# Begin Source File
SOURCE=..\textures.c
# End Source File
# Begin Source File
SOURCE=..\..\common\threads.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=..\..\common\bspfile.h
# End Source File
# Begin Source File
SOURCE=..\..\common\cmdlib.h
# End Source File
# Begin Source File
SOURCE=..\csg.h
# End Source File
# Begin Source File
SOURCE=..\..\common\mathlib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\polylib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\scriplib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\threads.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@ -0,0 +1,37 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "qcsg"=.\qcsg.dsp - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/SDKSrc/Tools/utils/qcsg", XUGBAAAA
.
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
begin source code control
"$/SDKSrc/Tools/utils/qcsg", XUGBAAAA
.
end source code control
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@ -0,0 +1,414 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="qcsg"
ProjectGUID="{73F7C531-9735-478E-8AC2-911C11201614}"
SccProjectName="&quot;$/SDKSrc/Tools/utils/qcsg&quot;, XUGBAAAA"
SccLocalPath=".">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;DOUBLEVEC_T"
RuntimeLibrary="1"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/qcsg.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib glaux.lib"
OutputFile=".\Debug/qcsg.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/qcsg.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/qcsg.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;DOUBLEVEC_T"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/qcsg.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib glaux.lib"
OutputFile=".\Release/qcsg.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/qcsg.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/qcsg.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90">
<File
RelativePath="..\brush.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\bspfile.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\cmdlib.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\gldraw.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\hullfile.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\map.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\mathlib.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\polylib.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\qcsg.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\textures.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\threads.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd">
<File
RelativePath="..\..\common\bspfile.h">
</File>
<File
RelativePath="..\..\common\cmdlib.h">
</File>
<File
RelativePath="..\csg.h">
</File>
<File
RelativePath="..\..\common\mathlib.h">
</File>
<File
RelativePath="..\..\common\polylib.h">
</File>
<File
RelativePath="..\..\common\scriplib.h">
</File>
<File
RelativePath="..\..\common\threads.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,546 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="qcsg"
ProjectGUID="{73F7C531-9735-478E-8AC2-911C11201614}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/qcsg.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;DOUBLEVEC_T"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/qcsg.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib glaux.lib"
OutputFile=".\Debug/qcsg.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/qcsg.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/qcsg.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;DOUBLEVEC_T"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/qcsg.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
SuppressStartupBanner="true"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib glaux.lib"
OutputFile=".\Release/qcsg.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\Release/qcsg.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
>
<File
RelativePath="..\brush.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\bspfile.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\cmdlib.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\gldraw.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\hullfile.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\map.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\mathlib.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\polylib.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\qcsg.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\textures.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\threads.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd"
>
<File
RelativePath="..\..\common\bspfile.h"
>
</File>
<File
RelativePath="..\..\common\cmdlib.h"
>
</File>
<File
RelativePath="..\csg.h"
>
</File>
<File
RelativePath="..\..\common\mathlib.h"
>
</File>
<File
RelativePath="..\..\common\polylib.h"
>
</File>
<File
RelativePath="..\..\common\scriplib.h"
>
</File>
<File
RelativePath="..\..\common\threads.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

879
hlsdk/utils/qcsg/qcsg.c Normal file
View File

@ -0,0 +1,879 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// csg4.c
#include "csg.h"
/*
NOTES
-----
check map size for +/- 4k limit at load time
*/
int brushfaces;
int c_csgfaces;
FILE *out[NUM_HULLS];
int c_tiny, c_tiny_clip;
int c_outfaces;
qboolean hullfile = false;
static char qhullfile[ 256 ];
qboolean glview;
qboolean noclip;
qboolean onlyents;
qboolean wadtextures = true;
vec3_t world_mins, world_maxs;
/*
==================
NewFaceFromFace
Duplicates the non point information of a face, used by SplitFace
==================
*/
bface_t *NewFaceFromFace (bface_t *in)
{
bface_t *newf;
newf = malloc (sizeof(bface_t));
memset (newf, 0, sizeof(newf));
newf->contents = in->contents;
newf->texinfo = in->texinfo;
newf->planenum = in->planenum;
newf->plane = in->plane;
return newf;
}
void FreeFace (bface_t *f)
{
free (f->w);
free (f);
}
/*
=================
ClipFace
Clips a faces by a plane, returning the fragment on the backside
and adding any fragment to the outside.
Faces exactly on the plane will stay inside unless overdrawn by later brush
frontside is the side of the plane that holds the outside list
Precedence is necesary to handle overlapping coplanar faces.
=================
*/
#define SPLIT_EPSILON 0.3
bface_t *ClipFace (brush_t *b, bface_t *f, bface_t **outside,
int splitplane, qboolean precedence)
{
bface_t *front;
winding_t *fw, *bw;
vec_t d;
plane_t *split;
int i, count[3];
// handle exact plane matches special
if (f->planenum == (splitplane^1) )
{ // opposite side, so put on inside list
return f;
}
if ( f->planenum == splitplane )
{
// coplanar
if (precedence)
{ // this fragment will go to the inside, because
// the earlier one was clipped to the outside
return f;
}
f->next = *outside;
*outside = f;
return NULL;
}
split = &mapplanes[splitplane];
#if 0
count[0] = count[1] = count[2] = 0;
for (i=0 ; i<f->w->numpoints ; i++)
{
d = DotProduct (f->w->p[i], split->normal) - split->dist;
if (d < -SPLIT_EPSILON)
count[1]++;
else if (d > SPLIT_EPSILON)
count[0]++;
else
count[2]++;
}
if (!count[0])
{
fw = NULL;
bw = f->w;
}
else if (!count[1])
{
fw = f->w;
bw = NULL;
}
else
#endif
ClipWindingNoCopy (f->w, split->normal, split->dist, &fw, &bw);
if (!fw)
return f;
if (!bw)
{
f->next = *outside;
*outside = f;
return NULL;
}
FreeWinding (f->w);
front = NewFaceFromFace (f);
front->w = fw;
WindingBounds (fw, front->mins, front->maxs);
front->next = *outside;
*outside = front;
f->w = bw;
WindingBounds (bw, f->mins, f->maxs);
return f;
}
/*
===========
WriteFace
===========
*/
void WriteFace (int hull, bface_t *f)
{
int i, j;
winding_t *w;
static int level = 128;
vec_t light;
ThreadLock ();
if (!hull)
c_csgfaces++;
if (glview)
{
// .gl format
w = f->w;
fprintf (out[hull], "%i\n", w->numpoints);
level+=28;
light = (level&255)/255.0;
for (i=0 ; i<w->numpoints ; i++)
{
fprintf (out[hull], "%5.2f %5.2f %5.2f %5.3f %5.3f %5.3f\n",
w->p[i][0],
w->p[i][1],
w->p[i][2],
light,
light,
light);
}
fprintf (out[hull], "\n");
}
else
{
// .p0 format
w = f->w;
fprintf (out[hull], "%i %i %i %i\n", f->planenum, f->texinfo, f->contents, w->numpoints);
for (i=0 ; i<w->numpoints ; i++)
{
fprintf (out[hull], "%5.2f %5.2f %5.2f\n",
w->p[i][0],
w->p[i][1],
w->p[i][2]);
}
fprintf (out[hull], "\n");
}
ThreadUnlock ();
}
/*
==================
SaveOutside
The faces remaining on the outside list are final
polygons. Write them to the output file.
Passable contents (water, lava, etc) will generate
a mirrored copy of the face to be seen from the inside.
==================
*/
void SaveOutside (brush_t *b, int hull, bface_t *outside, int mirrorcontents)
{
bface_t *f , *next, *f2;
int i;
int planenum;
vec3_t temp;
for (f=outside ; f ; f=next)
{
next = f->next;
if (WindingArea (f->w) < 1.0)
{
c_tiny++;
qprintf ("Entity %i, Brush %i: tiny fragment\n"
, b->entitynum, b->brushnum);
continue;
}
// count unique faces
if (!hull)
{
for (f2=b->hulls[hull].faces ; f2 ; f2=f2->next)
{
if (f2->planenum == f->planenum)
{
if (!f2->used)
{
f2->used = true;
c_outfaces++;
}
break;
}
}
}
WriteFace (hull, f);
// if (mirrorcontents != CONTENTS_SOLID)
{
f->planenum ^= 1;
f->plane = &mapplanes[f->planenum];
f->contents = mirrorcontents;
// swap point orders
for (i=0 ; i<f->w->numpoints/2 ; i++) // add points backwards
{
VectorCopy (f->w->p[i], temp);
VectorCopy (f->w->p[f->w->numpoints-1-i]
, f->w->p[i]);
VectorCopy (temp, f->w->p[f->w->numpoints-1-i]);
}
WriteFace (hull, f);
}
FreeFace (f);
}
}
/*
==================
EncloseInside
Changes the contents on all faces that got clipped out
and moves them back to the outside list
==================
*/
void EncloseInside (bface_t *inside, bface_t **outside
, int contents)
{
bface_t *f, *next;
for (f=inside ; f ; f=next)
{
next = f->next;
f->contents = contents;
f->next = *outside;
*outside = f;
}
}
//==========================================================================
bface_t *CopyFace (bface_t *f)
{
bface_t *n;
n = NewFaceFromFace (f);
n->w = CopyWinding (f->w);
VectorCopy (f->mins, n->mins);
VectorCopy (f->maxs, n->maxs);
return n;
}
/*
==================
CopyFacesToOutside
Make a copy of all the faces of the brush, so they
can be chewed up by other brushes.
All of the faces start on the outside list.
As other brushes take bites out of the faces, the
fragments are moved to the inside list, so they
can be freed when they are determined to be
completely enclosed in solid.
==================
*/
bface_t *CopyFacesToOutside (brushhull_t *bh)
{
bface_t *f, *newf;
bface_t *outside;
outside = NULL;
for (f=bh->faces ; f ; f=f->next)
{
brushfaces++;
newf = CopyFace (f);
WindingBounds (newf->w, newf->mins, newf->maxs);
newf->next = outside;
outside = newf;
}
return outside;
}
//============================================================
/*
===========
CSGBrush
===========
*/
void CSGBrush (int brushnum)
{
int hull;
brush_t *b1, *b2;
brushhull_t *bh1, *bh2;
int bn;
qboolean overwrite;
int i;
bface_t *f, *f2, *next, *fcopy;
bface_t *outside, *oldoutside;
entity_t *e;
vec_t area;
SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL);
b1 = &mapbrushes[brushnum];
e = &entities[b1->entitynum];
for (hull = 0 ; hull<NUM_HULLS ; hull++)
{
bh1 = &b1->hulls[hull];
// set outside to a copy of the brush's faces
outside = CopyFacesToOutside (bh1);
overwrite = false;
for (bn=0 ; bn<e->numbrushes ; bn++)
{
// see if b2 needs to clip a chunk out of b1
if (bn==brushnum)
{
overwrite = true; // later brushes now overwrite
continue;
}
b2 = &mapbrushes[e->firstbrush + bn];
bh2 = &b2->hulls[hull];
if (!bh2->faces)
continue; // brush isn't in this hull
// check brush bounding box first
for (i=0 ; i<3 ; i++)
if (bh1->mins[i] > bh2->maxs[i]
|| bh1->maxs[i] < bh2->mins[i])
break;
if (i<3)
continue;
// divide faces by the planes of the b2 to find which
// fragments are inside
f = outside;
outside = NULL;
for ( ; f ; f=next)
{
next = f->next;
// check face bounding box first
for (i=0 ; i<3 ; i++)
if (bh2->mins[i] > f->maxs[i]
|| bh2->maxs[i] < f->mins[i])
break;
if (i<3)
{ // this face doesn't intersect brush2's bbox
f->next = outside;
outside = f;
continue;
}
oldoutside = outside;
fcopy = CopyFace (f); // save to avoid fake splits
// throw pieces on the front sides of the planes
// into the outside list, return the remains on the inside
for (f2=bh2->faces ; f2 && f ; f2=f2->next)
f = ClipFace (b1, f, &outside, f2->planenum, overwrite);
area = f ? WindingArea (f->w) : 0;
if (f && area < 1.0)
{
qprintf ("Entity %i, Brush %i: tiny penetration\n"
, b1->entitynum, b1->brushnum);
c_tiny_clip++;
FreeFace (f);
f = NULL;
}
if (f)
{
// there is one convex fragment of the original
// face left inside brush2
FreeFace (fcopy);
if (b1->contents > b2->contents)
{ // inside a water brush
f->contents = b2->contents;
f->next = outside;
outside = f;
}
else // inside a solid brush
FreeFace (f); // throw it away
}
else
{ // the entire thing was on the outside, even
// though the bounding boxes intersected,
// which will never happen with axial planes
// free the fragments chopped to the outside
while (outside != oldoutside)
{
f2 = outside->next;
FreeFace (outside);
outside = f2;
}
// revert to the original face to avoid
// unneeded false cuts
fcopy->next = outside;
outside = fcopy;
}
}
}
// all of the faces left in outside are real surface faces
SaveOutside (b1, hull, outside, b1->contents);
}
}
//======================================================================
/*
============
EmitPlanes
============
*/
void EmitPlanes (void)
{
int i;
dplane_t *dp;
plane_t *mp;
numplanes = nummapplanes;
mp = mapplanes;
dp = dplanes;
for (i=0 ; i<nummapplanes ; i++, mp++, dp++)
{
VectorCopy ( mp->normal, dp->normal);
dp->dist = mp->dist;
dp->type = mp->type;
}
}
/*
============
SetModelNumbers
============
*/
void SetModelNumbers (void)
{
int i;
int models;
char value[10];
models = 1;
for (i=1 ; i<num_entities ; i++)
{
if (entities[i].numbrushes)
{
sprintf (value, "*%i", models);
models++;
SetKeyValue (&entities[i], "model", value);
}
}
}
/*
============
SetLightStyles
============
*/
#define MAX_SWITCHED_LIGHTS 32
void SetLightStyles (void)
{
int stylenum;
char *t;
entity_t *e;
int i, j;
char value[10];
char lighttargets[MAX_SWITCHED_LIGHTS][64];
// any light that is controlled (has a targetname)
// must have a unique style number generated for it
stylenum = 0;
for (i=1 ; i<num_entities ; i++)
{
e = &entities[i];
t = ValueForKey (e, "classname");
if (Q_strncasecmp (t, "light", 5))
continue;
t = ValueForKey (e, "targetname");
if (!t[0])
continue;
// find this targetname
for (j=0 ; j<stylenum ; j++)
if (!strcmp (lighttargets[j], t))
break;
if (j == stylenum)
{
if (stylenum == MAX_SWITCHED_LIGHTS)
Error ("stylenum == MAX_SWITCHED_LIGHTS");
strcpy (lighttargets[j], t);
stylenum++;
}
sprintf (value, "%i", 32 + j);
SetKeyValue (e, "style", value);
}
}
/*
============
WriteBSP
============
*/
void WriteBSP (char *name)
{
char path[1024];
strcpy (path, name);
DefaultExtension (path, ".bsp");
SetModelNumbers ();
SetLightStyles ();
UnparseEntities ();
if ( !onlyents )
WriteMiptex ();
WriteBSPFile (path);
}
//======================================================================
/*
============
ProcessModels
============
*/
int typecontents[4] = {CONTENTS_WATER, CONTENTS_SLIME, CONTENTS_LAVA
, CONTENTS_SKY};
void ProcessModels (void)
{
int i, j, type;
int placed;
int first, contents;
brush_t temp;
vec3_t origin;
for (i=0 ; i<num_entities ; i++)
{
if (!entities[i].numbrushes)
continue;
//
// sort the contents down so stone bites water, etc
//
first = entities[i].firstbrush;
placed = 0;
for (type=0 ; type<4 ; type++)
{
contents = typecontents[type];
for (j=placed+1 ; j< entities[i].numbrushes ; j++)
{
if (mapbrushes[first+j].contents == contents)
{
temp = mapbrushes[first+placed];
mapbrushes[first+placed] = mapbrushes[j];
mapbrushes[j] = temp;
placed++;
}
}
}
//
// csg them in order
//
if (i == 0)
{
RunThreadsOnIndividual (entities[i].numbrushes, 1 , CSGBrush);
}
else
{
for (j=0 ; j<entities[i].numbrushes ; j++)
CSGBrush (first + j);
}
// write end of model marker
if (!glview)
{
for (j=0 ; j<NUM_HULLS ; j++)
fprintf (out[j], "-1 -1 -1 -1\n");
}
}
}
//=========================================
/*
============
BoundWorld
============
*/
void BoundWorld (void)
{
int i;
brushhull_t *h;
ClearBounds (world_mins, world_maxs);
for (i=0 ; i<nummapbrushes ; i++)
{
h = &mapbrushes[i].hulls[0];
if (!h->faces)
continue;
AddPointToBounds (h->mins, world_mins, world_maxs);
AddPointToBounds (h->maxs, world_mins, world_maxs);
}
qprintf ("World bounds: (%i %i %i) to (%i %i %i)\n",
(int)world_mins[0],(int)world_mins[1],(int)world_mins[2],
(int)world_maxs[0],(int)world_maxs[1],(int)world_maxs[2]);
VectorCopy (world_mins, draw_mins);
VectorCopy (world_maxs, draw_maxs);
Draw_ClearWindow ();
}
/*
============
main
============
*/
extern char qproject[];
int main (int argc, char **argv)
{
int i, j;
int hull;
entity_t *ent;
char source[1024];
char name[1024];
double start, end;
printf( "qcsg.exe v2.8 (%s)\n", __DATE__ );
printf ("---- qcsg ----\n" );
for (i=1 ; i<argc ; i++)
{
if (!strcmp(argv[i],"-threads"))
{
numthreads = atoi (argv[i+1]);
i++;
}
else if (!strcmp(argv[i],"-glview"))
{
glview = true;
}
else if (!strcmp(argv[i], "-v"))
{
printf ("verbose = true\n");
verbose = true;
}
else if (!strcmp(argv[i], "-draw"))
{
printf ("drawflag = true\n");
drawflag = true;
}
else if (!strcmp(argv[i], "-noclip"))
{
printf ("noclip = true\n");
noclip = true;
}
else if (!strcmp(argv[i], "-onlyents"))
{
printf ("onlyents = true\n");
onlyents = true;
}
else if (!strcmp(argv[i], "-nowadtextures"))
{
printf ("wadtextures = false\n");
wadtextures = false;
}
else if (!strcmp(argv[i], "-wadinclude"))
{
pszWadInclude[nWadInclude++] = strdup( argv[i + 1] );
i++;
}
else if( !strcmp( argv[ i ], "-proj" ) )
{
strcpy( qproject, argv[ i + 1 ] );
i++;
}
else if (!strcmp(argv[i], "-hullfile"))
{
hullfile = true;
strcpy( qhullfile, argv[i + 1] );
i++;
}
else if (argv[i][0] == '-')
Error ("Unknown option \"%s\"", argv[i]);
else
break;
}
if (i != argc - 1)
Error ("usage: qcsg [-nowadtextures] [-wadinclude <name>] [-draw] [-glview] [-noclip] [-onlyents] [-proj <name>] [-threads #] [-v] [-hullfile <name>] mapfile");
SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL);
start = I_FloatTime ();
CheckHullFile( hullfile, qhullfile );
ThreadSetDefault ();
SetQdirFromPath (argv[i]);
strcpy (source, ExpandArg (argv[i]));
COM_FixSlashes(source);
StripExtension (source);
strcpy (name, ExpandArg (argv[i]));
DefaultExtension (name, ".map"); // might be .reg
//
// if onlyents, just grab the entites and resave
//
if (onlyents && !glview)
{
char out[1024];
int old_entities;
sprintf (out, "%s.bsp", source);
LoadBSPFile (out);
// Get the new entity data from the map file
LoadMapFile (name);
// Write it all back out again.
WriteBSP (source);
end = I_FloatTime ();
printf ("%5.0f seconds elapsed\n", end-start);
return 0;
}
//
// start from scratch
//
LoadMapFile (name);
RunThreadsOnIndividual (nummapbrushes, true, CreateBrush);
BoundWorld ();
qprintf ("%5i map planes\n", nummapplanes);
for (i=0 ; i<NUM_HULLS ; i++)
{
char name[1024];
if (glview)
sprintf (name, "%s.gl%i",source, i);
else
sprintf (name, "%s.p%i",source, i);
out[i] = fopen (name, "w");
if (!out[i])
Error ("Couldn't open %s",name);
}
ProcessModels ();
qprintf ("%5i csg faces\n", c_csgfaces);
qprintf ("%5i used faces\n", c_outfaces);
qprintf ("%5i tiny faces\n", c_tiny);
qprintf ("%5i tiny clips\n", c_tiny_clip);
for (i=0 ; i<NUM_HULLS ; i++)
fclose (out[i]);
if (!glview)
{
EmitPlanes ();
WriteBSP (source);
}
end = I_FloatTime ();
printf ("%5.0f seconds elapsed\n", end-start);
return 0;
}

520
hlsdk/utils/qcsg/textures.c Normal file
View File

@ -0,0 +1,520 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "csg.h"
typedef struct
{
char identification[4]; // should be WAD2/WAD3
int numlumps;
int infotableofs;
} wadinfo_t;
typedef struct
{
int filepos;
int disksize;
int size; // uncompressed
char type;
char compression;
char pad1, pad2;
char name[16]; // must be null terminated
int iTexFile; // index of the wad this texture is located in
} lumpinfo_t;
int nummiptex;
lumpinfo_t miptex[MAX_MAP_TEXTURES];
int nTexLumps = 0;
lumpinfo_t *lumpinfo = NULL;
int nTexFiles = 0;
FILE *texfiles[128];
int nWadInclude;
char *pszWadInclude[128];
qboolean wadInclude[128]; // include the textures from this WAD in the BSP
void CleanupName (char *in, char *out)
{
int i;
for (i=0 ; i< 16 ; i++ )
{
if (!in[i])
break;
out[i] = toupper(in[i]);
}
for ( ; i< 16 ; i++ )
out[i] = 0;
}
/*
=================
lump_sorters
=================
*/
int
lump_sorter_by_wad_and_name( const void *lump1, const void *lump2 )
{
lumpinfo_t *plump1 = (lumpinfo_t *)lump1;
lumpinfo_t *plump2 = (lumpinfo_t *)lump2;
if ( plump1->iTexFile == plump2->iTexFile )
return strcmp( plump1->name, plump2->name );
else
return plump1->iTexFile - plump2->iTexFile;
}
int
lump_sorter_by_name( const void *lump1, const void *lump2 )
{
lumpinfo_t *plump1 = (lumpinfo_t *)lump1;
lumpinfo_t *plump2 = (lumpinfo_t *)lump2;
return strcmp( plump1->name, plump2->name );
}
/*
=================
TEX_InitFromWad
=================
*/
qboolean TEX_InitFromWad (char *path)
{
int i;
wadinfo_t wadinfo;
char szTmpPath[512];
char *pszWadFile;
strcpy(szTmpPath, path);
// temporary kludge so we don't have to deal with no occurances of a semicolon
// in the path name ..
if(strchr(szTmpPath, ';') == NULL)
strcat(szTmpPath, ";");
pszWadFile = strtok(szTmpPath, ";");
while(pszWadFile)
{
FILE *texfile; // temporary used in this loop
texfiles[nTexFiles] = fopen(pszWadFile, "rb");
if (!texfiles[nTexFiles])
{
// maybe this wad file has a hard code drive
if (pszWadFile[1] == ':')
{
pszWadFile += 2; // skip past the file
texfiles[nTexFiles] = fopen (pszWadFile, "rb");
}
}
if (!texfiles[nTexFiles])
{
printf ("WARNING: couldn't open %s\n", pszWadFile);
return false;
}
++nTexFiles;
// look and see if we're supposed to include the textures from this WAD in the bsp.
for (i = 0; i < nWadInclude; i++)
{
if (stricmp( pszWadInclude[i], pszWadFile ) == 0)
{
wadInclude[nTexFiles-1] = true;
}
}
// temp assignment to make things cleaner:
texfile = texfiles[nTexFiles-1];
printf ("Using WAD File: %s\n", pszWadFile);
SafeRead(texfile, &wadinfo, sizeof(wadinfo));
if (strncmp (wadinfo.identification, "WAD2", 4) &&
strncmp (wadinfo.identification, "WAD3", 4))
Error ("TEX_InitFromWad: %s isn't a wadfile",pszWadFile);
wadinfo.numlumps = LittleLong(wadinfo.numlumps);
wadinfo.infotableofs = LittleLong(wadinfo.infotableofs);
fseek (texfile, wadinfo.infotableofs, SEEK_SET);
lumpinfo = realloc(lumpinfo, (nTexLumps + wadinfo.numlumps)
* sizeof(lumpinfo_t));
for(i = 0; i < wadinfo.numlumps; i++)
{
SafeRead(texfile, &lumpinfo[nTexLumps], sizeof(lumpinfo_t) -
sizeof(int)); // iTexFile is NOT read from file
CleanupName (lumpinfo[nTexLumps].name, lumpinfo[nTexLumps].name);
lumpinfo[nTexLumps].filepos = LittleLong(lumpinfo[nTexLumps].filepos);
lumpinfo[nTexLumps].disksize = LittleLong(lumpinfo[nTexLumps].disksize);
lumpinfo[nTexLumps].iTexFile = nTexFiles-1;
++nTexLumps;
}
// next wad file
pszWadFile = strtok(NULL, ";");
}
qsort( (void *)lumpinfo, (size_t)nTexLumps, sizeof(lumpinfo[0]), lump_sorter_by_name );
return true;
}
/*
==================
FindTexture
==================
*/
lumpinfo_t *
FindTexture (lumpinfo_t *source )
{
lumpinfo_t *found = NULL;
if ( !( found = bsearch( source, (void *)lumpinfo, (size_t)nTexLumps, sizeof(lumpinfo[0]), lump_sorter_by_name ) ) )
printf ("WARNING: texture %s not found in BSP's wad file list!\n", source->name);
return found;
}
/*
==================
LoadLump
==================
*/
int LoadLump (lumpinfo_t *source, byte *dest, int *texsize)
{
*texsize = 0;
if ( source->filepos )
{
fseek (texfiles[source->iTexFile], source->filepos, SEEK_SET);
*texsize = source->disksize;
// Should we just load the texture header w/o the palette & bitmap?
if ( wadtextures && !wadInclude[source->iTexFile] )
{
// Just read the miptex header and zero out the data offsets.
// We will load the entire texture from the WAD at engine runtime
int i;
miptex_t *miptex = (miptex_t *)dest;
SafeRead (texfiles[source->iTexFile], dest, sizeof(miptex_t) );
for( i=0; i<MIPLEVELS; i++ )
miptex->offsets[i] = 0;
return sizeof(miptex_t);
}
else
{
// Load the entire texture here so the BSP contains the texture
SafeRead (texfiles[source->iTexFile], dest, source->disksize );
return source->disksize;
}
}
printf ("WARNING: texture %s not found in BSP's wad file list!\n", source->name);
return 0;
}
/*
==================
AddAnimatingTextures
==================
*/
void AddAnimatingTextures (void)
{
int base;
int i, j, k;
char name[32];
base = nummiptex;
for (i=0 ; i<base ; i++)
{
if (miptex[i].name[0] != '+' && miptex[i].name[0] != '-')
continue;
strcpy (name, miptex[i].name);
for (j=0 ; j<20 ; j++)
{
if (j < 10)
name[1] = '0'+j;
else
name[1] = 'A'+j-10; // alternate animation
// see if this name exists in the wadfile
for (k=0 ; k < nTexLumps; k++)
if (!strcmp(name, lumpinfo[k].name))
{
FindMiptex (name); // add to the miptex list
break;
}
}
}
if ( nummiptex - base )
printf ("added %i additional animating textures.\n", nummiptex - base);
}
/*
==================
WriteMiptex
==================
*/
void WriteMiptex(void)
{
int i, len, texsize, totaltexsize = 0;
byte *data;
dmiptexlump_t *l;
char *path;
char fullpath[1024];
int start;
texdatasize = 0;
path = ValueForKey (&entities[0], "_wad");
if (!path || !path[0])
{
path = ValueForKey (&entities[0], "wad");
if (!path || !path[0])
{
printf ("WARNING: no wadfile specified\n");
return;
}
}
strcpy(fullpath, path);
start = GetTickCount();
{
if (!TEX_InitFromWad (fullpath))
return;
AddAnimatingTextures ();
}
qprintf( "TEX_InitFromWad & AddAnimatingTextures elapsed time = %ldms\n", GetTickCount()-start );
start = GetTickCount();
{
for (i=0; i<nummiptex; i++ )
{
lumpinfo_t *found;
if ( found = FindTexture( miptex + i ) )
miptex[i] = *found;
else
{
miptex[i].iTexFile = miptex[i].filepos = miptex[i].disksize = 0;
}
}
}
qprintf( "FindTextures elapsed time = %ldms\n", GetTickCount()-start );
start = GetTickCount();
{
int final_miptex, i;
texinfo_t *tx = texinfo;
// Sort them FIRST by wadfile and THEN by name for most efficient loading in the engine.
qsort( (void *)miptex, (size_t)nummiptex, sizeof(miptex[0]), lump_sorter_by_wad_and_name );
// Sleazy Hack 104 Pt 2 - After sorting the miptex array, reset the texinfos to point to the right miptexs
for(i=0; i<numtexinfo; i++, tx++)
{
char *miptex_name = (char *)tx->miptex;
tx->miptex = FindMiptex( miptex_name );
// Free up the originally strdup()'ed miptex_name
free( miptex_name );
}
}
qprintf( "qsort(miptex) elapsed time = %ldms\n", GetTickCount()-start );
start = GetTickCount();
{
// Now setup to get the miptex data (or just the headers if using -wadtextures) from the wadfile
l = (dmiptexlump_t *)dtexdata;
data = (byte *)&l->dataofs[nummiptex];
l->nummiptex = nummiptex;
for (i=0 ; i<nummiptex ; i++)
{
l->dataofs[i] = data - (byte *)l;
len = LoadLump (miptex+i, data, &texsize);
if (data + len - dtexdata >= MAX_MAP_MIPTEX)
Error ("Textures exceeded MAX_MAP_MIPTEX");
if (!len)
l->dataofs[i] = -1; // didn't find the texture
else
{
totaltexsize += texsize;
if ( totaltexsize > MAX_MAP_MIPTEX )
Error("Textures exceeded MAX_MAP_MIPTEX" );
}
data += len;
}
texdatasize = data - dtexdata;
}
qprintf( "LoadLump() elapsed time = %ldms\n", GetTickCount()-start );
}
//==========================================================================
int FindMiptex (char *name)
{
int i;
ThreadLock ();
for (i=0 ; i<nummiptex ; i++)
if (!Q_strcasecmp (name, miptex[i].name))
{
ThreadUnlock ();
return i;
}
if (nummiptex == MAX_MAP_TEXTURES)
Error ("Exceeded MAX_MAP_TEXTURES");
strcpy (miptex[i].name, name);
nummiptex++;
ThreadUnlock ();
return i;
}
int TexinfoForBrushTexture (plane_t *plane, brush_texture_t *bt, vec3_t origin)
{
vec3_t vecs[2];
int sv, tv;
vec_t ang, sinv, cosv;
vec_t ns, nt;
texinfo_t tx, *tc;
int i, j, k;
memset (&tx, 0, sizeof(tx));
tx.miptex = FindMiptex (bt->name);
// Note: FindMiptex() still needs to be called here to add it to the global miptex array
// Very Sleazy Hack 104 - since the tx.miptex index will be bogus after we sort the miptex array later
// Put the string name of the miptex in this "index" until after we are done sorting it in WriteMiptex().
tx.miptex = (int)strdup(bt->name);
// set the special flag
if (bt->name[0] == '*'
|| !Q_strncasecmp (bt->name, "sky",3)
|| !Q_strncasecmp (bt->name, "clip",4)
|| !Q_strncasecmp (bt->name, "origin",6)
|| !Q_strncasecmp (bt->name, "aaatrigger",10))
tx.flags |= TEX_SPECIAL;
if (g_nMapFileVersion < 220)
{
TextureAxisFromPlane(plane, vecs[0], vecs[1]);
}
if (!bt->scale[0])
bt->scale[0] = 1;
if (!bt->scale[1])
bt->scale[1] = 1;
if (g_nMapFileVersion < 220)
{
// rotate axis
if (bt->rotate == 0)
{ sinv = 0 ; cosv = 1; }
else if (bt->rotate == 90)
{ sinv = 1 ; cosv = 0; }
else if (bt->rotate == 180)
{ sinv = 0 ; cosv = -1; }
else if (bt->rotate == 270)
{ sinv = -1 ; cosv = 0; }
else
{
ang = bt->rotate / 180 * Q_PI;
sinv = sin(ang);
cosv = cos(ang);
}
if (vecs[0][0])
sv = 0;
else if (vecs[0][1])
sv = 1;
else
sv = 2;
if (vecs[1][0])
tv = 0;
else if (vecs[1][1])
tv = 1;
else
tv = 2;
for (i=0 ; i<2 ; i++)
{
ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
vecs[i][sv] = ns;
vecs[i][tv] = nt;
}
for (i=0 ; i<2 ; i++)
for (j=0 ; j<3 ; j++)
tx.vecs[i][j] = vecs[i][j] / bt->scale[i];
}
else
{
tx.vecs[0][0] = bt->UAxis[0] / bt->scale[0];
tx.vecs[0][1] = bt->UAxis[1] / bt->scale[0];
tx.vecs[0][2] = bt->UAxis[2] / bt->scale[0];
tx.vecs[1][0] = bt->VAxis[0] / bt->scale[1];
tx.vecs[1][1] = bt->VAxis[1] / bt->scale[1];
tx.vecs[1][2] = bt->VAxis[2] / bt->scale[1];
}
tx.vecs[0][3] = bt->shift[0] + DotProduct( origin, tx.vecs[0] );
tx.vecs[1][3] = bt->shift[1] + DotProduct( origin, tx.vecs[1] );
//
// find the texinfo
//
ThreadLock ();
tc = texinfo;
for (i=0 ; i<numtexinfo ; i++, tc++)
{
// Sleazy hack 104, Pt 3 - Use strcmp on names to avoid dups
if ( strcmp( (char *)(tc->miptex), (char *)(tx.miptex)) != 0 )
continue;
if (tc->flags != tx.flags)
continue;
for (j=0 ; j<2 ; j++)
{
for (k=0 ; k<4 ; k++)
{
if (tc->vecs[j][k] != tx.vecs[j][k])
goto skip;
}
}
ThreadUnlock ();
return i;
skip:;
}
if (numtexinfo == MAX_MAP_TEXINFO)
Error ("Exceeded MAX_MAP_TEXINFO");
*tc = tx;
numtexinfo++;
ThreadUnlock ();
return i;
}

View File

@ -0,0 +1,140 @@
# Microsoft Developer Studio Project File - Name="qlumpy" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=qlumpy - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "qlumpy.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "qlumpy.mak" CFG="qlumpy - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "qlumpy - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "qlumpy - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/SDKSrc/Tools/utils/qlumpy", BVGBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "qlumpy - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /W2 /GX /O2 /I "..\..\common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "qlumpy - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\Debug"
# PROP Intermediate_Dir ".\Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /W2 /Gm /GX /ZI /Od /I "..\..\common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386
!ENDIF
# Begin Target
# Name "qlumpy - Win32 Release"
# Name "qlumpy - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\..\common\cmdlib.c
# End Source File
# Begin Source File
SOURCE=..\..\common\lbmlib.c
# End Source File
# Begin Source File
SOURCE=..\qlumpy.c
# End Source File
# Begin Source File
SOURCE=..\quakegrb.c
# End Source File
# Begin Source File
SOURCE=..\..\common\scriplib.c
# End Source File
# Begin Source File
SOURCE=..\..\common\wadlib.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=..\..\common\cmdlib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\lbmlib.h
# End Source File
# Begin Source File
SOURCE=..\qlumpy.h
# End Source File
# Begin Source File
SOURCE=..\..\common\scriplib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\wadlib.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@ -0,0 +1,37 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "qlumpy"=.\qlumpy.dsp - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/SDKSrc/Tools/utils/qlumpy", BVGBAAAA
.
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
begin source code control
"$/SDKSrc/Tools/utils/qlumpy", BVGBAAAA
.
end source code control
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@ -0,0 +1,286 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="qlumpy"
ProjectGUID="{9309F40E-79AF-41A7-9572-06664DEF9FEF}"
SccProjectName="&quot;$/SDKSrc/Tools/utils/qlumpy&quot;, BVGBAAAA"
SccLocalPath=".">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/qlumpy.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="2"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/qlumpy.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/qlumpy.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/qlumpy.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
RuntimeLibrary="5"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/qlumpy.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="2"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/qlumpy.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/qlumpy.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/qlumpy.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90">
<File
RelativePath="..\..\common\cmdlib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\lbmlib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\qlumpy.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\quakegrb.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\wadlib.c">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd">
<File
RelativePath="..\..\common\cmdlib.h">
</File>
<File
RelativePath="..\..\common\lbmlib.h">
</File>
<File
RelativePath="..\qlumpy.h">
</File>
<File
RelativePath="..\..\common\scriplib.h">
</File>
<File
RelativePath="..\..\common\wadlib.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,386 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="qlumpy"
ProjectGUID="{9309F40E-79AF-41A7-9572-06664DEF9FEF}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/qlumpy.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/qlumpy.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="2"
SuppressStartupBanner="true"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/qlumpy.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\Release/qlumpy.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/qlumpy.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/qlumpy.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="2"
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/qlumpy.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/qlumpy.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
>
<File
RelativePath="..\..\common\cmdlib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\lbmlib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\qlumpy.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\quakegrb.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\wadlib.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd"
>
<File
RelativePath="..\..\common\cmdlib.h"
>
</File>
<File
RelativePath="..\..\common\lbmlib.h"
>
</File>
<File
RelativePath="..\qlumpy.h"
>
</File>
<File
RelativePath="..\..\common\scriplib.h"
>
</File>
<File
RelativePath="..\..\common\wadlib.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

430
hlsdk/utils/qlumpy/qlumpy.c Normal file
View File

@ -0,0 +1,430 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#define VERSION "2.2"
#include "qlumpy.h"
#define MAXLUMP 0x50000 // biggest possible lump
extern char qproject[];
int grabbed;
byte *byteimage, *lbmpalette;
int byteimagewidth, byteimageheight;
char basepath[1024];
char lumpname[16];
char destfile[1024];
byte *lumpbuffer, *lump_p;
qboolean savesingle;
qboolean outputcreated;
qboolean do16bit;
qboolean fTransparent255;
/*
=============================================================================
MAIN
=============================================================================
*/
void GrabRaw (void);
void GrabPalette (void);
void GrabPic (void);
void GrabMip (void);
void GrabColormap (void);
void GrabColormap2 (void);
void GrabFont( void );
typedef struct
{
char *name;
void (*function) (void);
} command_t;
command_t commands[] =
{
{ "palette", GrabPalette },
{ "colormap", GrabColormap },
{ "qpic", GrabPic },
{ "miptex", GrabMip },
{ "raw", GrabRaw },
{ "colormap2", GrabColormap2 },
{ "font", GrabFont },
{ NULL, NULL } // list terminator
};
#define TRANSPARENT_R 0x0
#define TRANSPARENT_G 0x0
#define TRANSPARENT_B 0xFF
#define IS_TRANSPARENT(p) (p[0]==TRANSPARENT_R && p[1]==TRANSPARENT_G && p[2]==TRANSPARENT_B)
/*
==============
TransparentByteImage
==============
*/
void TransparentByteImage( void )
{
// Remap all pixels of color 0,0,255 to index 255 and remap index 255 to something else
byte transtable[256], *image;
int i, j, firsttrans;
firsttrans = -1;
for ( i = 0; i < 256; i++ ) {
if ( IS_TRANSPARENT( (lbmpalette+(i*3)) ) ) {
transtable[i] = 255;
if ( firsttrans < 0 )
firsttrans = i;
}
else
transtable[i] = i;
}
// If there is some transparency, translate it
if ( firsttrans >= 0 ) {
if ( !IS_TRANSPARENT( (lbmpalette+(255*3)) ) )
transtable[255] = firsttrans;
image = byteimage;
for ( j = 0; j < byteimageheight; j++ ) {
for ( i = 0; i < byteimagewidth; i++ ) {
*image = transtable[*image];
image++;
}
}
// Move palette entry for pixels previously mapped to entry 255
lbmpalette[ firsttrans*3 + 0 ] = lbmpalette[ 255*3 + 0 ];
lbmpalette[ firsttrans*3 + 1 ] = lbmpalette[ 255*3 + 1 ];
lbmpalette[ firsttrans*3 + 2 ] = lbmpalette[ 255*3 + 2 ];
lbmpalette[ 255*3 + 0 ] = TRANSPARENT_R;
lbmpalette[ 255*3 + 1 ] = TRANSPARENT_G;
lbmpalette[ 255*3 + 2 ] = TRANSPARENT_B;
}
}
/*
==============
LoadScreen
==============
*/
void LoadScreen (char *name)
{
char *expanded;
expanded = ExpandPathAndArchive (name);
printf ("grabbing from %s...\n",expanded);
LoadLBM (expanded, &byteimage, &lbmpalette);
byteimagewidth = bmhd.w;
byteimageheight = bmhd.h;
}
/*
==============
LoadScreenBMP
==============
*/
void LoadScreenBMP(char *pszName)
{
char *pszExpanded;
char basename[64];
pszExpanded = ExpandPathAndArchive(pszName);
printf("grabbing from %s...\n", pszExpanded);
if (LoadBMP(pszExpanded, &byteimage, &lbmpalette))
Error ("Failed to load!", pszExpanded);
if ( byteimage == NULL || lbmpalette == NULL )
Error("FAIL!",pszExpanded);
byteimagewidth = bmhd.w;
byteimageheight = bmhd.h;
ExtractFileBase (token, basename); // Files that start with '$' have color (0,0,255) transparent,
if ( basename[0] == '{' ) { // move to last palette entry.
fTransparent255 = true;
TransparentByteImage();
}
}
/*
================
CreateOutput
================
*/
void CreateOutput (void)
{
outputcreated = true;
//
// create the output wadfile file
//
NewWad (destfile, false); // create a new wadfile
}
/*
===============
WriteLump
===============
*/
void WriteLump (int type, int compression)
{
int size;
if (!outputcreated)
CreateOutput ();
//
// dword align the size
//
while ((int)lump_p&3)
*lump_p++ = 0;
size = lump_p - lumpbuffer;
if (size > MAXLUMP)
Error ("Lump size exceeded %d, memory corrupted!",MAXLUMP);
//
// write the grabbed lump to the wadfile
//
AddLump (lumpname,lumpbuffer,size,type, compression);
}
/*
===========
WriteFile
Save as a seperate file instead of as a wadfile lump
===========
*/
void WriteFile (void)
{
char filename[1024];
char *exp;
sprintf (filename,"%s/%s.lmp", destfile, lumpname);
exp = ExpandPath(filename);
printf ("saved %s\n", exp);
SaveFile (exp, lumpbuffer, lump_p-lumpbuffer);
}
/*
================
ParseScript
================
*/
void ParseScript (void)
{
int cmd;
int size;
fTransparent255 = false;
do
{
//
// get a command / lump name
//
GetToken (true);
if (endofscript)
break;
if (!Q_strcasecmp (token,"$LOAD"))
{
GetToken (false);
LoadScreen (token);
continue;
}
if (!Q_strcasecmp (token,"$DEST"))
{
GetToken (false);
strcpy (destfile, token);
continue;
}
if (!Q_strcasecmp (token,"$SINGLEDEST"))
{
GetToken (false);
strcpy (destfile, token);
savesingle = true;
continue;
}
if (!Q_strcasecmp (token,"$LOADBMP"))
{
GetToken (false);
fTransparent255 = false;
LoadScreenBMP (token);
continue;
}
//
// new lump
//
if (strlen(token) >= sizeof(lumpname) )
Error ("\"%s\" is too long to be a lump name",token);
memset (lumpname,0,sizeof(lumpname));
strcpy (lumpname, token);
for (size=0 ; size<sizeof(lumpname) ; size++)
lumpname[size] = tolower(lumpname[size]);
//
// get the grab command
//
lump_p = lumpbuffer;
GetToken (false);
//
// call a routine to grab some data and put it in lumpbuffer
// with lump_p pointing after the last byte to be saved
//
for (cmd=0 ; commands[cmd].name ; cmd++)
if ( !Q_strcasecmp(token,commands[cmd].name) )
{
commands[cmd].function ();
break;
}
if ( !commands[cmd].name )
Error ("Unrecognized token '%s' at line %i",token,scriptline);
grabbed++;
if (savesingle)
WriteFile ();
else
WriteLump (TYP_LUMPY+cmd, 0);
} while (!endofscript);
}
/*
=================
ProcessLumpyScript
Loads a script file, then grabs everything from it
=================
*/
void ProcessLumpyScript (char *basename)
{
char script[256];
printf ("qlumpy script: %s\n",basename);
//
// create default destination directory
//
strcpy (destfile, ExpandPath(basename));
StripExtension (destfile);
strcat (destfile,".wad"); // unless the script overrides, save in cwd
//
// save in a wadfile by default
//
savesingle = false;
grabbed = 0;
outputcreated = false;
//
// read in the script file
//
strcpy (script, basename);
DefaultExtension (script, ".ls");
LoadScriptFile (script);
strcpy (basepath, basename);
ParseScript (); // execute load / grab commands
if (!savesingle)
{
WriteWad (do16bit); // write out the wad directory
printf ("%i lumps grabbed in a wad file\n",grabbed);
}
else
printf ("%i lumps written seperately\n",grabbed);
}
/*
==============================
main
==============================
*/
int main (int argc, char **argv)
{
int i;
printf ("\nqlumpy "VERSION" by John Carmack, copyright (c) 1994 Id Software.\n");
printf ("Portions copyright (c) 1998 Valve LLC (%s)\n", __DATE__ );
if (argc == 1)
Error ("qlumpy [-archive directory] [-8bit] [-proj <project>] scriptfile [scriptfile ...]");
lumpbuffer = malloc (MAXLUMP);
do16bit = true;
for( i=1; i<argc; i++ )
{
if( *argv[ i ] == '-' )
{
if( !strcmp( argv[ i ], "-archive" ) )
{
archive = true;
strcpy (archivedir, argv[2]);
printf ("Archiving source to: %s\n", archivedir);
}
else if( !strcmp( argv[ i ], "-proj" ) )
{
strcpy( qproject, argv[ i + 1 ] );
i++;
}
else if( !strcmp( argv[ i ], "-8bit" ) )
do16bit = false;
}
else
break;
}
// rest of arguments are script files
for ( ; i<argc ; i++)
{
char szTemp[1024];
char *pszPath = argv[i];
// Fully qualify the path names before using them
if (!(pszPath[0] == '/' || pszPath[0] == '\\' || pszPath[1] == ':'))
{ // path is partial
Q_getwd (szTemp);
strcat (szTemp, pszPath);
pszPath = szTemp;
}
SetQdirFromPath(pszPath);
ProcessLumpyScript(pszPath);
}
return 0;
}

View File

@ -0,0 +1,26 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "cmdlib.h"
#include "scriplib.h"
#include "lbmlib.h"
#include "wadlib.h"
extern byte *byteimage, *lbmpalette;
extern int byteimagewidth, byteimageheight;
#define SCRN(x,y) (*(byteimage+(y)*byteimagewidth+x))
extern byte *lump_p;
extern byte *lumpbuffer;
extern char lumpname[];

View File

@ -0,0 +1,841 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "qlumpy.h"
#include "math.h"
#pragma warning (disable : 4244)
typedef struct
{
short ofs, length;
} row_t;
typedef struct
{
int width, height;
int widthbits, heightbits;
unsigned char data[4];
} qtex_t;
typedef struct
{
int width, height;
byte data[4]; // variably sized
} qpic_t;
// Font stuff
#define NUM_GLYPHS 256
const unsigned kFontMarker = 254;
typedef struct
{
short startoffset;
short charwidth;
} charinfo;
typedef struct
{
int width, height;
int rowcount;
int rowheight;
charinfo fontinfo[ NUM_GLYPHS ];
byte data[4];
} qfont_t;
extern qboolean fTransparent255;
#define SCRN(x,y) (*(byteimage+(y)*byteimagewidth+x))
void GrabPalette16( void );
extern qboolean do16bit;
/*
==============
GrabRaw
filename RAW x y width height
==============
*/
void GrabRaw (void)
{
int x,y,xl,yl,xh,yh,w,h;
byte *screen_p;
int linedelta;
GetToken (false);
xl = atoi (token);
GetToken (false);
yl = atoi (token);
GetToken (false);
w = atoi (token);
GetToken (false);
h = atoi (token);
if (xl == -1)
{
xl = yl = 0;
w = byteimagewidth;
h = byteimageheight;
}
xh = xl+w;
yh = yl+h;
screen_p = byteimage + yl*byteimagewidth + xl;
linedelta = byteimagewidth - w;
for (y=yl ; y<yh ; y++)
{
for (x=xl ; x<xh ; x++)
{
*lump_p++ = *screen_p;
*screen_p++ = 0;
}
screen_p += linedelta;
}
}
/*
==============
GrabPalette
filename PALETTE [startcolor endcolor]
==============
*/
void GrabPalette (void)
{
int start, end, length;
if (TokenAvailable())
{
GetToken (false);
start = atoi (token);
GetToken (false);
end = atoi (token);
}
else
{
start = 0;
end = 255;
}
length = 3*(end-start+1);
memcpy (lump_p, lbmpalette+start*3, length);
lump_p += length;
}
/*
==============
GrabPic
filename qpic x y width height
==============
*/
void GrabPic (void)
{
int x,y,xl,yl,xh,yh;
int width;
qpic_t *header;
GetToken (false);
xl = atoi (token);
GetToken (false);
yl = atoi (token);
GetToken (false);
xh = xl+atoi (token);
GetToken (false);
yh = yl+atoi (token);
if (xl == -1)
{
xl = yl = 0;
xh = byteimagewidth;
yh = byteimageheight;
}
if (xh<xl || yh<yl || xl < 0 || yl<0) // || xh>319 || yh>239)
Error ("GrabPic: Bad size: %i, %i, %i, %i",xl,yl,xh,yh);
//
// fill in header
//
header = (qpic_t *)lump_p;
width = xh-xl;
header->width = LittleLong(width);
header->height = LittleLong(yh-yl);
//
// start grabbing posts
//
lump_p = (byte *)header->data;
for (y=yl ; y< yh ; y++)
for (x=xl ; x<xh ; x++)
*lump_p++ = SCRN(x,y);
// New for 16bpp display
if( do16bit )
GrabPalette16();
}
/*
=============================================================================
COLORMAP GRABBING
=============================================================================
*/
/*
===============
BestColor
===============
*/
byte BestColor (int r, int g, int b, int start, int stop)
{
int i;
int dr, dg, db;
int bestdistortion, distortion;
int bestcolor;
byte *pal;
//
// let any color go to 0 as a last resort
//
bestdistortion = ( (int)r*r + (int)g*g + (int)b*b )*2;
bestcolor = 0;
pal = lbmpalette + start*3;
for (i=start ; i<= stop ; i++)
{
dr = r - (int)pal[0];
dg = g - (int)pal[1];
db = b - (int)pal[2];
pal += 3;
distortion = dr*dr + dg*dg + db*db;
if (distortion < bestdistortion)
{
if (!distortion)
return i; // perfect match
bestdistortion = distortion;
bestcolor = i;
}
}
return bestcolor;
}
/*
==============
GrabColormap
filename COLORMAP levels fullbrights
the first map is an identiy 0-255
the final map is all black except for the fullbrights
the remaining maps are evenly spread
fullbright colors start at the top of the palette.
==============
*/
void GrabColormap (void)
{
int levels, brights;
int l, c;
float frac, red, green, blue;
GetToken (false);
levels = atoi (token);
GetToken (false);
brights = atoi (token);
// identity lump
for (l=0 ; l<256 ; l++)
*lump_p++ = l;
// shaded levels
for (l=1;l<levels;l++)
{
frac = 1.0 - (float)l/(levels-1);
for (c=0 ; c<256-brights ; c++)
{
red = lbmpalette[c*3];
green = lbmpalette[c*3+1];
blue = lbmpalette[c*3+2];
red = (int)(red*frac+0.5);
green = (int)(green*frac+0.5);
blue = (int)(blue*frac+0.5);
//
// note: 254 instead of 255 because 255 is the transparent color, and we
// don't want anything remapping to that
//
*lump_p++ = BestColor(red,green,blue, 0, 254);
}
for ( ; c<256 ; c++)
*lump_p++ = c;
}
*lump_p++ = brights;
}
/*
==============
GrabColormap2
experimental -- not used by quake
filename COLORMAP2 range levels fullbrights
fullbright colors start at the top of the palette.
Range can be greater than 1 to allow overbright color tables.
the first map is all 0
the last (levels-1) map is at range
==============
*/
void GrabColormap2 (void)
{
int levels, brights;
int l, c;
float frac, red, green, blue;
float range;
GetToken (false);
range = atof (token);
GetToken (false);
levels = atoi (token);
GetToken (false);
brights = atoi (token);
// shaded levels
for (l=0;l<levels;l++)
{
frac = range - range*(float)l/(levels-1);
for (c=0 ; c<256-brights ; c++)
{
red = lbmpalette[c*3];
green = lbmpalette[c*3+1];
blue = lbmpalette[c*3+2];
red = (int)(red*frac+0.5);
green = (int)(green*frac+0.5);
blue = (int)(blue*frac+0.5);
//
// note: 254 instead of 255 because 255 is the transparent color, and we
// don't want anything remapping to that
//
*lump_p++ = BestColor(red,green,blue, 0, 254);
}
// fullbrights allways stay the same
for ( ; c<256 ; c++)
*lump_p++ = c;
}
*lump_p++ = brights;
}
/*
=============================================================================
MIPTEX GRABBING
=============================================================================
*/
typedef struct
{
char name[16];
unsigned width, height;
unsigned offsets[4]; // four mip maps stored
} miptex_t;
byte pixdata[256];
float linearpalette[256][3];
float d_red, d_green, d_blue;
int colors_used;
int color_used[256];
float maxdistortion;
byte AddColor( float r, float g, float b )
{
int i;
for (i = 0; i < 255; i++)
{
if (!color_used[i])
{
linearpalette[i][0] = r;
linearpalette[i][1] = g;
linearpalette[i][2] = b;
if (r < 0) r = 0.0;
if (r > 1.0) r = 1.0;
lbmpalette[i*3+0] = pow( r, 1.0 / 2.2) * 255;
if (g < 0) g = 0.0;
if (g > 1.0) g = 1.0;
lbmpalette[i*3+1] = pow( g, 1.0 / 2.2) * 255;
if (b < 0) b = 0.0;
if (b > 1.0) b = 1.0;
lbmpalette[i*3+2] = pow( b, 1.0 / 2.2) * 255;
color_used[i] = 1;
colors_used++;
return i;
}
}
return 0;
}
/*
=============
AveragePixels
=============
*/
byte AveragePixels (int count)
{
float r,g,b;
int i;
int vis;
int pix;
float dr, dg, db;
float bestdistortion, distortion;
int bestcolor;
byte *pal;
vis = 0;
r = g = b = 0;
for (i=0 ; i<count ; i++)
{
pix = pixdata[i];
r += linearpalette[pix][0];
g += linearpalette[pix][1];
b += linearpalette[pix][2];
}
r /= count;
g /= count;
b /= count;
r += d_red;
g += d_green;
b += d_blue;
//
// find the best color
//
// bestdistortion = r*r + g*g + b*b;
bestdistortion = 3.0;
bestcolor = -1;
for ( i=0; i<255; i++)
{
if (color_used[i])
{
pix = i; //pixdata[i];
dr = r - linearpalette[i][0];
dg = g - linearpalette[i][1];
db = b - linearpalette[i][2];
distortion = dr*dr + dg*dg + db*db;
if (distortion < bestdistortion)
{
if (!distortion)
{
d_red = d_green = d_blue = 0; // no distortion yet
return pix; // perfect match
}
bestdistortion = distortion;
bestcolor = pix;
}
}
}
if (bestdistortion > 0.001 && colors_used < 255)
{
// printf("%f %f %f\n", r, g, b );
bestcolor = AddColor( r, g, b );
d_red = d_green = d_blue = 0;
bestdistortion = 0;
}
else
{
// error diffusion
d_red = r - linearpalette[bestcolor][0];
d_green = g - linearpalette[bestcolor][1];
d_blue = b - linearpalette[bestcolor][2];
}
if (bestdistortion > maxdistortion)
maxdistortion = bestdistortion;
return bestcolor;
}
/*
==============
GrabMip
filename MIP x y width height
must be multiples of sixteen
==============
*/
void GrabMip (void)
{
int i,j,x,y,xl,yl,xh,yh,w,h;
byte *screen_p, *source, testpixel;
int linedelta;
miptex_t *qtex;
int miplevel, mipstep;
int xx, yy, pix;
int count;
GetToken (false);
xl = atoi (token);
GetToken (false);
yl = atoi (token);
GetToken (false);
w = atoi (token);
GetToken (false);
h = atoi (token);
if (xl == -1)
{
xl = yl = 0;
w = byteimagewidth;
h = byteimageheight;
}
if ( (w & 15) || (h & 15) )
Error ("line %i: miptex sizes must be multiples of 16", scriptline);
xh = xl+w;
yh = yl+h;
qtex = (miptex_t *)lump_p;
qtex->width = LittleLong(w);
qtex->height = LittleLong(h);
strcpy (qtex->name, lumpname);
lump_p = (byte *)&qtex->offsets[4];
screen_p = byteimage + yl*byteimagewidth + xl;
linedelta = byteimagewidth - w;
source = lump_p;
qtex->offsets[0] = LittleLong(lump_p - (byte *)qtex);
for (y=yl ; y<yh ; y++)
{
for (x=xl ; x<xh ; x++)
{
pix = *screen_p;
*screen_p++ = 0;
// if (pix == 255)
// pix = 0;
*lump_p++ = pix;
}
screen_p += linedelta;
}
// calculate gamma corrected linear palette
for (i = 0; i < 256; i++)
{
for (j = 0; j < 3; j++)
{
float f;
f = lbmpalette[i*3+j] / 255.0;
linearpalette[i][j] = pow(f, 2.2 ); // assume textures are done at 2.2, we want to remap them at 1.0
}
}
maxdistortion = 0;
if (!fTransparent255)
{
// figure out what palette entries are actually used
colors_used = 0;
for (i = 0; i < 256; i++)
color_used[i] = 0;
for (x = 0; x < w; x++)
{
for (y = 0; y < h; y++)
{
if (!color_used[source[ y*w + x]])
{
color_used[source[ y*w + x]] = 1;
colors_used++;
}
}
}
}
else
{
// assume palette full if it's a transparent texture
colors_used = 256;
for (i = 0; i < 256; i++)
color_used[i] = 1;
}
// printf("colors_used %d : ", colors_used );
//
// subsample for greater mip levels
//
for (miplevel = 1 ; miplevel<4 ; miplevel++)
{
int pixTest;
d_red = d_green = d_blue = 0; // no distortion yet
qtex->offsets[miplevel] = LittleLong(lump_p - (byte *)qtex);
mipstep = 1<<miplevel;
pixTest = (int)( (float)(mipstep * mipstep) * 0.4 ); // 40% of pixels
for (y=0 ; y<h ; y+=mipstep)
{
for (x = 0 ; x<w ; x+= mipstep)
{
count = 0;
for (yy=0 ; yy<mipstep ; yy++)
for (xx=0 ; xx<mipstep ; xx++)
{
testpixel = source[ (y+yy)*w + x + xx ];
// If 255 is not transparent, or this isn't a transparent pixel, add it in to the image filter
if ( !fTransparent255 || testpixel != 255 ) {
pixdata[count] = testpixel;
count++;
}
}
if ( count <= pixTest ) // Solid pixels account for < 40% of this pixel, make it transparent
{
*lump_p++ = 255;
}
else
{
*lump_p++ = AveragePixels (count);
}
}
}
}
// printf(" %d %f\n", colors_used, maxdistortion );
if( do16bit )
GrabPalette16();
}
/*
=============================================================================
PALETTE GRABBING
=============================================================================
*/
void GrabPalette16( void )
{
int i;
// Write out palette in 16bit mode
*(unsigned short *) lump_p = 256; // palette size
lump_p += sizeof(short);
memcpy( lump_p, lbmpalette, 768 );
lump_p += 768;
}
/*
=============================================================================
FONT GRABBING
=============================================================================
*/
/*
==============
GrabFont
font x y width height startglyph
==============
*/
void GrabFont( void )
{
int x, y, y2, xl, x2, yl, xh, yh, i, j;
int index, offset;
int width;
int iCurX; // current x in destination
int iMaxX; // max x in destination
byte *pbuf, *pCur;
qfont_t *header;
iMaxX = 255;
iCurX = 0;
// Set up header
header = (qfont_t *)lump_p;
memset( header, 0, sizeof(qfont_t) );
GetToken( false );
header->width = header->rowheight = atoi( token ); //mwh why does width equal rowheight?
header->height = 1;
lump_p = (byte *)header->data;
pCur = (byte *)lump_p;
memset( lump_p, 0xFF, 256 * 160);
GetToken( false );
index = atoi( token );
while( index != -1 )
{
// Get/Process source bitmap coordinates
GetToken (false);
xl = atoi (token);
GetToken (false);
yl = atoi (token);
GetToken (false);
xh = xl-1+atoi (token);
GetToken (false);
yh = atoi (token) - 1;
if (xl == -1)
{
xl = yl = 0;
xh = byteimagewidth;
yh = byteimageheight;
}
if( xh<xl || yh<yl || xl < 0 || yl<0 )
Error( "GrabFont line %1: Bad size: %i, %i, %i, %i", scriptline, xl, yl, xh, yh );
//
// Fill in font information
// Create a bitmap that is up to 256 wide and as tall as we need to accomadate the font.
// We limit the bitmap to 256 because some 3d boards have problems with textures bigger
// than that.
//
for( y=yl; y<yh; y+=header->rowheight+1 )
{
// Make sure we're at a marker
if( y != yl )
{
for( y2=y-header->rowheight; y2<yh; y2++ )
if( kFontMarker == (unsigned) SCRN(xl,y2) )
break;
if( y2 == yh )
break;
else if( y2 != y )
Error( "GrabFont line %d: rowheight doesn't seem to match bitmap (%d, %d)\n", scriptline, y, y2 );
}
for( x=xl; x<xh; )
{
// find next marker
for( x2=x+1; x2<xh; x2++ )
if( kFontMarker == (unsigned) SCRN(x2,y) )
break;
// check for end of row
if( x2 == xh )
break;
// Set up glyph information
if( index >= NUM_GLYPHS )
{
printf( "GrabFont: Glyph out of range\n" );
goto getout;
}
// Fill in glyph info
header->fontinfo[ index ].charwidth = x2 - x - 1;
// update header
// output glyph data
iCurX += header->fontinfo[index].charwidth;
// Will this glyph fit on this row?
if (iCurX >= iMaxX)
{
// Nope -- move to next row
pCur = (byte *)lump_p + 256 * header->rowheight * header->height;
header->height++;
iCurX = header->fontinfo[index].charwidth;
}
// copy over the glyph bytes
pbuf = pCur;
header->fontinfo[ index ].startoffset = pCur - (byte *) header->data;
for(j = 1; j <= header->rowheight; j++)
{
byte *psrc = byteimage + (y + j) * byteimagewidth + (x + 1);
for(i = x + 1; i < x2; i++)
*pbuf++ = *psrc++;
pbuf = pCur + j * 256;
}
// move the lump pointer to point at the next possible glyph
pCur += header->fontinfo[index].charwidth;
x = x2;
index++;
}
}
// Get next ASCII index
getout:
GetToken (false);
index = atoi (token);
}
// advance the lump pointer so that the last row is saved.
lump_p += (256 * header->rowheight) * header->height;
// JAY: Round up to the next power of 2 for GL
offset = header->height * header->rowheight;
y = (offset>128)?256:(offset>64)?128:(offset>32)?64:(offset>16)?32:16;
if ( offset != y )
{
printf("Rounding font from 256x%d to 256x%d\n", offset, y );
lump_p += (256 * (y - offset));
}
header->rowcount = header->height;
header->height = y;
if( do16bit )
GrabPalette16();
}

1723
hlsdk/utils/qrad/lightmap.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,164 @@
# Microsoft Developer Studio Project File - Name="qrad" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=qrad - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "qrad.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "qrad.mak" CFG="qrad - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "qrad - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "qrad - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/SDKSrc/Tools/utils/qrad", FVGBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "qrad - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /MT /GX /Zi /O2 /I "..\..\common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /profile /map /machine:I386
!ELSEIF "$(CFG)" == "qrad - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\Debug"
# PROP Intermediate_Dir ".\Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /MT /Gm /GX /ZI /Od /I "..\..\common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /profile /map /debug /machine:I386
!ENDIF
# Begin Target
# Name "qrad - Win32 Release"
# Name "qrad - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\..\common\bspfile.c
# End Source File
# Begin Source File
SOURCE=..\..\common\cmdlib.c
# End Source File
# Begin Source File
SOURCE=..\lightmap.c
# End Source File
# Begin Source File
SOURCE=..\..\common\mathlib.c
# End Source File
# Begin Source File
SOURCE=..\..\common\polylib.c
# End Source File
# Begin Source File
SOURCE=..\qrad.c
# End Source File
# Begin Source File
SOURCE=..\..\common\scriplib.c
# End Source File
# Begin Source File
SOURCE=..\..\common\threads.c
# End Source File
# Begin Source File
SOURCE=..\trace.c
# End Source File
# Begin Source File
SOURCE=..\vismat.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=..\..\common\bspfile.h
# End Source File
# Begin Source File
SOURCE=..\..\common\cmdlib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\mathlib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\polylib.h
# End Source File
# Begin Source File
SOURCE=.\qrad.h
# End Source File
# Begin Source File
SOURCE=..\..\common\scriplib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\threads.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@ -0,0 +1,37 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "qrad"=.\qrad.dsp - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/SDKSrc/Tools/utils/qrad", FVGBAAAA
.
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
begin source code control
"$/SDKSrc/Tools/utils/qrad", FVGBAAAA
.
end source code control
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@ -0,0 +1,374 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="qrad"
ProjectGUID="{08E4D1DC-EEE6-40F6-ADD2-1092F5075F96}"
SccProjectName="&quot;$/SDKSrc/Tools/utils/qrad&quot;, FVGBAAAA"
SccLocalPath=".">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
RuntimeLibrary="0"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/qrad.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/qrad.exe"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/qrad.pdb"
GenerateMapFile="TRUE"
MapFileName=".\Debug/qrad.map"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/qrad.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/qrad.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/qrad.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
GenerateMapFile="TRUE"
MapFileName=".\Release/qrad.map"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/qrad.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90">
<File
RelativePath="..\..\common\bspfile.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\cmdlib.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\lightmap.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\mathlib.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\polylib.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\qrad.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\threads.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\trace.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\vismat.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd">
<File
RelativePath="..\..\common\bspfile.h">
</File>
<File
RelativePath="..\..\common\cmdlib.h">
</File>
<File
RelativePath="..\..\common\mathlib.h">
</File>
<File
RelativePath="..\..\common\polylib.h">
</File>
<File
RelativePath="qrad.h">
</File>
<File
RelativePath="..\..\common\scriplib.h">
</File>
<File
RelativePath="..\..\common\threads.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,496 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="qrad"
ProjectGUID="{08E4D1DC-EEE6-40F6-ADD2-1092F5075F96}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/qrad.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/qrad.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
SuppressStartupBanner="true"
DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/qrad.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/qrad.pdb"
GenerateMapFile="true"
MapFileName=".\Debug/qrad.map"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/qrad.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/qrad.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/qrad.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateMapFile="true"
MapFileName=".\Release/qrad.map"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
>
<File
RelativePath="..\..\common\bspfile.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\cmdlib.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\lightmap.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\mathlib.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\polylib.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\qrad.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\threads.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\trace.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\vismat.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd"
>
<File
RelativePath="..\..\common\bspfile.h"
>
</File>
<File
RelativePath="..\..\common\cmdlib.h"
>
</File>
<File
RelativePath="..\..\common\mathlib.h"
>
</File>
<File
RelativePath="..\..\common\polylib.h"
>
</File>
<File
RelativePath="qrad.h"
>
</File>
<File
RelativePath="..\..\common\scriplib.h"
>
</File>
<File
RelativePath="..\..\common\threads.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

1569
hlsdk/utils/qrad/qrad.c Normal file

File diff suppressed because it is too large Load Diff

154
hlsdk/utils/qrad/qrad.h Normal file
View File

@ -0,0 +1,154 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "cmdlib.h"
#include "mathlib.h"
#include "bspfile.h"
#include "polylib.h"
#include "threads.h"
#ifdef WIN32
#include <windows.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#pragma warning(disable: 4142 4028)
#include <io.h>
#pragma warning(default: 4142 4028)
#include <fcntl.h>
#include <direct.h>
#include <ctype.h>
typedef enum
{
emit_surface,
emit_point,
emit_spotlight,
emit_skylight
} emittype_t;
typedef struct directlight_s
{
struct directlight_s *next;
emittype_t type;
int style;
vec3_t origin;
vec3_t intensity;
vec3_t normal; // for surfaces and spotlights
float stopdot; // for spotlights
float stopdot2; // for spotlights
} directlight_t;
#define TRANSFER_SCALE (1.0f/16384)
#define INVERSE_TRANSFER_SCALE 16384
typedef struct
{
unsigned short patch;
unsigned short transfer;
} transfer_t;
#define MAX_PATCHES 65536
typedef struct patch_s
{
winding_t *winding;
vec3_t mins, maxs, face_mins, face_maxs;
struct patch_s *next; // next in face
int numtransfers;
transfer_t *transfers;
vec3_t origin;
vec3_t normal;
dplane_t *plane;
float chop; // smallest acceptable width of patch face
float scale[2]; // Scaling of texture in s & t
qboolean sky;
vec3_t totallight; // accumulated by radiosity
// does NOT include light
// accounted for by direct lighting
vec3_t baselight; // emissivity only
vec3_t directlight; // direct light value
float area;
vec3_t reflectivity; // Average RGB of texture, modified by material type.
vec3_t samplelight;
int samples; // for averaging direct light
int faceNumber;
} patch_t;
extern patch_t *face_patches[MAX_MAP_FACES];
extern entity_t *face_entity[MAX_MAP_FACES];
extern vec3_t face_offset[MAX_MAP_FACES]; // for rotating bmodels
extern vec3_t face_centroids[MAX_MAP_EDGES];
extern patch_t patches[MAX_PATCHES];
extern unsigned num_patches;
extern int leafparents[MAX_MAP_LEAFS];
extern int nodeparents[MAX_MAP_NODES];
extern float lightscale;
extern float dlight_threshold;
extern float coring;
void MakeShadowSplits (void);
//==============================================
_int64 getfreespace(char *filepath);
long getfilesize(char *filename);
time_t getfiletime(char *filename);
void BuildVisMatrix (void);
void FreeVisMatrix (void);
qboolean CheckVisBit (int p1, int p2);
void TouchVMFFile (void);
//==============================================
extern qboolean extra;
extern vec3_t ambient;
extern float maxlight;
extern unsigned numbounce;
extern directlight_t *directlights[MAX_MAP_LEAFS];
extern byte nodehit[MAX_MAP_NODES];
extern float gamma;
extern float indirect_sun;
extern float smoothing_threshold;
void MakeTnodes (dmodel_t *bm);
void PairEdges (void);
qboolean IsIncremental(char *filename);
int SaveIncremental(char *filename);
int PartialHead (void);
void BuildFacelights (int facenum);
void PrecompLightmapOffsets();
void FinalLightFace (int facenum);
void PvsForOrigin (vec3_t org, byte *pvs);
int TestLine_r (int node, vec3_t start, vec3_t stop);
void CreateDirectLights (void);
void DeleteDirectLights (void);
int ProgressiveRefinement (void);
vec_t PatchPlaneDist( patch_t *patch );
void GetPhongNormal( int facenum, vec3_t spot, vec3_t phongnormal );
dleaf_t *PointInLeaf (vec3_t point);

320
hlsdk/utils/qrad/trace.c Normal file
View File

@ -0,0 +1,320 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// trace.c
#include "cmdlib.h"
#include "mathlib.h"
#include "bspfile.h"
#include "polylib.h"
// #define ON_EPSILON 0.001
typedef struct tnode_s
{
int type;
vec3_t normal;
float dist;
int children[2];
int pad;
} tnode_t;
tnode_t *tnodes, *tnode_p;
/*
==============
MakeTnode
Converts the disk node structure into the efficient tracing structure
==============
*/
void MakeTnode (int nodenum)
{
tnode_t *t;
dplane_t *plane;
int i;
dnode_t *node;
t = tnode_p++;
node = dnodes + nodenum;
plane = dplanes + node->planenum;
t->type = plane->type;
VectorCopy (plane->normal, t->normal);
t->dist = plane->dist;
for (i=0 ; i<2 ; i++)
{
if (node->children[i] < 0)
t->children[i] = dleafs[-node->children[i] - 1].contents;
else
{
t->children[i] = tnode_p - tnodes;
MakeTnode (node->children[i]);
}
}
}
/*
=============
MakeTnodes
Loads the node structure out of a .bsp file to be used for light occlusion
=============
*/
void MakeTnodes (dmodel_t *bm)
{
// 32 byte align the structs
tnodes = calloc( (numnodes+1), sizeof(tnode_t));
tnodes = (tnode_t *)(((int)tnodes + 31)&~31);
tnode_p = tnodes;
MakeTnode (0);
}
//==========================================================
byte nodehit[MAX_MAP_NODES];
/*
=============
PartialHead
=============
*/
int PartialHead (void)
{
int nodenum;
dnode_t *node;
tnode_p = tnodes;
// skip single sided nodes from root
nodenum = 0;
while (nodenum >= 0)
{
node = &dnodes[nodenum];
if ( (node->children[0] < 0) || !nodehit[node->children[0]])
nodenum = node->children[1];
else if ((node->children[1] < 0) || !nodehit[node->children[1]])
nodenum = node->children[0];
else
break;
}
return nodenum;
}
//==========================================================
int TestLine_r (int node, vec3_t start, vec3_t stop)
{
tnode_t *tnode;
float front, back;
vec3_t mid;
float frac;
int side;
int r;
if (node == CONTENTS_SOLID)
return CONTENTS_SOLID;
if (node == CONTENTS_SKY)
return CONTENTS_SKY;
if (node < 0)
return CONTENTS_EMPTY;
tnode = &tnodes[node];
switch (tnode->type)
{
case PLANE_X:
front = start[0] - tnode->dist;
back = stop[0] - tnode->dist;
break;
case PLANE_Y:
front = start[1] - tnode->dist;
back = stop[1] - tnode->dist;
break;
case PLANE_Z:
front = start[2] - tnode->dist;
back = stop[2] - tnode->dist;
break;
default:
front = (start[0]*tnode->normal[0] + start[1]*tnode->normal[1] + start[2]*tnode->normal[2]) - tnode->dist;
back = (stop[0]*tnode->normal[0] + stop[1]*tnode->normal[1] + stop[2]*tnode->normal[2]) - tnode->dist;
break;
}
if (front >= -ON_EPSILON && back >= -ON_EPSILON)
return TestLine_r (tnode->children[0], start, stop);
if (front < ON_EPSILON && back < ON_EPSILON)
return TestLine_r (tnode->children[1], start, stop);
side = front < 0;
frac = front / (front-back);
mid[0] = start[0] + (stop[0] - start[0])*frac;
mid[1] = start[1] + (stop[1] - start[1])*frac;
mid[2] = start[2] + (stop[2] - start[2])*frac;
r = TestLine_r (tnode->children[side], start, mid);
if (r != CONTENTS_EMPTY)
return r;
return TestLine_r (tnode->children[!side], mid, stop);
}
int TestLine (vec3_t start, vec3_t stop)
{
return TestLine_r (0, start, stop);
}
/*
==============================================================================
LINE TRACING
The major lighting operation is a point to point visibility test, performed
by recursive subdivision of the line by the BSP tree.
==============================================================================
*/
typedef struct
{
vec3_t backpt;
int side;
int node;
} tracestack_t;
/*
==============
TestLine
==============
*/
qboolean _TestLine (vec3_t start, vec3_t stop)
{
int node;
float front, back;
tracestack_t *tstack_p;
int side;
float frontx,fronty, frontz, backx, backy, backz;
tracestack_t tracestack[64];
tnode_t *tnode;
frontx = start[0];
fronty = start[1];
frontz = start[2];
backx = stop[0];
backy = stop[1];
backz = stop[2];
tstack_p = tracestack;
node = 0;
while (1)
{
if (node == CONTENTS_SOLID)
{
#if 0
float d1, d2, d3;
d1 = backx - frontx;
d2 = backy - fronty;
d3 = backz - frontz;
if (d1*d1 + d2*d2 + d3*d3 > 1)
#endif
return false; // DONE!
}
while (node < 0)
{
// pop up the stack for a back side
tstack_p--;
if (tstack_p < tracestack)
return true;
node = tstack_p->node;
// set the hit point for this plane
frontx = backx;
fronty = backy;
frontz = backz;
// go down the back side
backx = tstack_p->backpt[0];
backy = tstack_p->backpt[1];
backz = tstack_p->backpt[2];
node = tnodes[tstack_p->node].children[!tstack_p->side];
}
tnode = &tnodes[node];
switch (tnode->type)
{
case PLANE_X:
front = frontx - tnode->dist;
back = backx - tnode->dist;
break;
case PLANE_Y:
front = fronty - tnode->dist;
back = backy - tnode->dist;
break;
case PLANE_Z:
front = frontz - tnode->dist;
back = backz - tnode->dist;
break;
default:
front = (frontx*tnode->normal[0] + fronty*tnode->normal[1] + frontz*tnode->normal[2]) - tnode->dist;
back = (backx*tnode->normal[0] + backy*tnode->normal[1] + backz*tnode->normal[2]) - tnode->dist;
break;
}
if (front > -ON_EPSILON && back > -ON_EPSILON)
{
node = tnode->children[0];
continue;
}
if (front < ON_EPSILON && back < ON_EPSILON)
{
node = tnode->children[1];
continue;
}
side = front < 0;
front = front / (front-back);
tstack_p->node = node;
tstack_p->side = side;
tstack_p->backpt[0] = backx;
tstack_p->backpt[1] = backy;
tstack_p->backpt[2] = backz;
tstack_p++;
backx = frontx + front*(backx-frontx);
backy = fronty + front*(backy-fronty);
backz = frontz + front*(backz-frontz);
node = tnode->children[side];
}
}

569
hlsdk/utils/qrad/vismat.c Normal file
View File

@ -0,0 +1,569 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "qrad.h"
#define HALFBIT
extern char source[MAX_PATH];
extern char vismatfile[_MAX_PATH];
extern char incrementfile[_MAX_PATH];
extern qboolean incremental;
/*
===================================================================
VISIBILITY MATRIX
Determine which patches can see each other
Use the PVS to accelerate if available
===================================================================
*/
byte *vismatrix;
dleaf_t *PointInLeaf (vec3_t point)
{
int nodenum;
vec_t dist;
dnode_t *node;
dplane_t *plane;
nodenum = 0;
while (nodenum >= 0)
{
node = &dnodes[nodenum];
plane = &dplanes[node->planenum];
dist = DotProduct (point, plane->normal) - plane->dist;
if (dist > 0)
nodenum = node->children[0];
else
nodenum = node->children[1];
}
return &dleafs[-nodenum - 1];
}
void PvsForOrigin (vec3_t org, byte *pvs)
{
dleaf_t *leaf;
if (!visdatasize)
{
memset (pvs, 255, (numleafs+7)/8 );
return;
}
leaf = PointInLeaf (org);
if (leaf->visofs == -1)
Error ("leaf->visofs == -1");
DecompressVis (&dvisdata[leaf->visofs], pvs);
}
/*
==============
PatchPlaneDist
Fixes up patch planes for brush models with an origin brush
==============
*/
vec_t PatchPlaneDist( patch_t *patch )
{
return patch->plane->dist + DotProduct( face_offset[ patch->faceNumber ], patch->normal );
}
/*
==============
TestPatchToFace
Sets vis bits for all patches in the face
==============
*/
void TestPatchToFace (unsigned patchnum, int facenum, int head, unsigned bitpos)
{
patch_t *patch = &patches[patchnum];
patch_t *patch2 = face_patches[facenum];
// if emitter is behind that face plane, skip all patches
if ( patch2 && DotProduct(patch->origin, patch2->normal) > PatchPlaneDist(patch2)+1.01 )
{
// we need to do a real test
for ( ; patch2 ; patch2 = patch2->next)
{
unsigned m = patch2 - patches;
// check vis between patch and patch2
// if bit has not already been set
// && v2 is not behind light plane
// && v2 is visible from v1
if ( m > patchnum
&& DotProduct (patch2->origin, patch->normal) > PatchPlaneDist(patch)+1.01
&& TestLine_r (head, patch->origin, patch2->origin) == CONTENTS_EMPTY )
{
// patchnum can see patch m
int bitset = bitpos+m;
vismatrix[ bitset>>3 ] |= 1 << (bitset&7);
}
}
}
}
/*
==============
BuildVisRow
Calc vis bits from a single patch
==============
*/
void BuildVisRow (int patchnum, byte *pvs, int head, unsigned bitpos)
{
int j, k, l;
patch_t *patch;
byte face_tested[MAX_MAP_FACES];
dleaf_t *leaf;
patch = &patches[patchnum];
memset (face_tested, 0, numfaces);
// leaf 0 is the solid leaf (skipped)
for (j=1, leaf=dleafs+1 ; j<numleafs ; j++, leaf++)
{
if ( ! ( pvs[(j-1)>>3] & (1<<((j-1)&7)) ) )
continue; // not in pvs
for (k=0 ; k<leaf->nummarksurfaces ; k++)
{
l = dmarksurfaces[leaf->firstmarksurface + k];
// faces can be marksurfed by multiple leaves, but
// don't bother testing again
if (face_tested[l])
continue;
face_tested[l] = 1;
TestPatchToFace (patchnum, l, head, bitpos);
}
}
}
/*
===========
BuildVisLeafs
This is run by multiple threads
===========
*/
void BuildVisLeafs (int threadnum)
{
int i;
int lface, facenum, facenum2;
byte pvs[(MAX_MAP_LEAFS+7)/8];
dleaf_t *srcleaf, *leaf;
patch_t *patch;
int head;
unsigned bitpos;
unsigned patchnum;
while (1)
{
//
// build a minimal BSP tree that only
// covers areas relevent to the PVS
//
i = GetThreadWork ();
if (i == -1)
break;
i++; // skip leaf 0
srcleaf = &dleafs[i];
DecompressVis (&dvisdata[srcleaf->visofs], pvs);
#if 0
// is this valid multithreaded???
memset (nodehit, 0, numnodes);
for (j=1, leaf=dleafs+1 ; j<numleafs ; j++, leaf++)
{
if ( !( pvs[(j-1)>>3] & (1<<((j-1)&7)) ) )
continue;
n = leafparents[j];
while (n != -1)
{
nodehit[n] = 1;
n = nodeparents[n];
}
}
head = PartialHead ();
#else
head = 0;
#endif
//
// go through all the faces inside the
// leaf, and process the patches that
// actually have origins inside
//
for (lface = 0 ; lface < srcleaf->nummarksurfaces ; lface++)
{
facenum = dmarksurfaces[srcleaf->firstmarksurface + lface];
for (patch = face_patches[facenum] ; patch ; patch=patch->next)
{
leaf = PointInLeaf (patch->origin);
if (leaf != srcleaf)
continue;
patchnum = patch - patches;
#ifdef HALFBIT
bitpos = patchnum * num_patches - (patchnum*(patchnum+1))/2;
#else
bitpos = patchnum * num_patches;
#endif
// build to all other world leafs
BuildVisRow (patchnum, pvs, head, bitpos);
// build to bmodel faces
if (nummodels < 2)
continue;
for (facenum2 = dmodels[1].firstface ; facenum2 < numfaces ; facenum2++)
TestPatchToFace (patchnum, facenum2, head, bitpos);
}
}
}
}
/*
==============
getfiletime
==============
*/
time_t
getfiletime(char *filename)
{
time_t filetime = 0;
struct _stat filestat;
if ( _stat(filename, &filestat) == 0 )
filetime = max( filestat.st_mtime, filestat.st_ctime );
return filetime;
}
/*
==============
getfilesize
==============
*/
long
getfilesize(char *filename)
{
long size = 0;
struct _stat filestat;
if ( _stat(filename, &filestat) == 0 )
size = filestat.st_size;
return size;
}
/*
==============
getfiledata
==============
*/
long
getfiledata(char *filename, char *buffer, int buffersize)
{
long size = 0;
int handle;
time_t start,end;
time(&start);
if ( (handle = _open( filename, _O_RDONLY | _O_BINARY )) != -1 )
{
int bytesread;
printf("%-20s Restoring [%-13s - ", "BuildVisMatrix:", filename );
while( ( bytesread = _read( handle, buffer, min( 32*1024, buffersize - size ) ) ) > 0 )
{
size += bytesread;
buffer += bytesread;
}
_close( handle );
time(&end);
printf("%10.3fMB] (%d)\n",size/(1024.0*1024.0), end-start);
}
if (buffersize != size)
{
printf( "Invalid file [%s] found. File will be rebuilt!\n", filename );
unlink(filename);
}
return size;
}
/*
==============
getfreespace
==============
*/
_int64
getfreespace(char *filename)
{
_int64 freespace = 0;
int drive = 0;
struct _diskfree_t df;
if ( filename[0] && filename[1] == ':' )
drive = toupper(filename[0]) - 'A' + 1;
else
drive = _getdrive();
if ( _getdiskfree(drive, &df) == 0 )
{
freespace = df.avail_clusters;
freespace *= df.sectors_per_cluster;
freespace *= df.bytes_per_sector;
}
return freespace;
}
/*
==============
putfiledata
==============
*/
long
putfiledata(char *filename, char *buffer, int buffersize)
{
long size = 0;
int handle;
if ( getfreespace(filename) >= (_int64)(buffersize - getfilesize(filename)) )
{
if ( (handle = _open( filename, _O_WRONLY | _O_BINARY | _O_CREAT | _O_TRUNC, _S_IREAD | _S_IWRITE )) != -1 )
{
int byteswritten;
qprintf("Writing [%s] with new saved qrad data", filename );
while( ( byteswritten = _write( handle, buffer, min( 32*1024, buffersize - size ) ) ) > 0 )
{
size += byteswritten;
buffer += byteswritten;
if ( size >= buffersize )
break;
}
qprintf("(%d)\n", size );
_close( handle );
}
}
else
printf("Insufficient disk space(%ld) for 'incremental QRAD save file'!\n",
buffersize - getfilesize(filename) );
return size;
}
/*
==============
IsIncremental
==============
*/
qboolean
IsIncremental(char *filename)
{
qboolean status = false;
int sum;
int handle;
if ( (handle = _open( filename, _O_RDONLY | _O_BINARY )) != -1 )
{
if ( _read( handle, &sum, sizeof(sum) ) == sizeof(sum) && sum == dmodels_checksum
&& _read( handle, &sum, sizeof(sum) ) == sizeof(sum) && sum == dvertexes_checksum
&& _read( handle, &sum, sizeof(sum) ) == sizeof(sum) && sum == dplanes_checksum
&& _read( handle, &sum, sizeof(sum) ) == sizeof(sum) && sum == dleafs_checksum
&& _read( handle, &sum, sizeof(sum) ) == sizeof(sum) && sum == dnodes_checksum
&& _read( handle, &sum, sizeof(sum) ) == sizeof(sum) && sum == texinfo_checksum
&& _read( handle, &sum, sizeof(sum) ) == sizeof(sum) && sum == dclipnodes_checksum
&& _read( handle, &sum, sizeof(sum) ) == sizeof(sum) && sum == dfaces_checksum
&& _read( handle, &sum, sizeof(sum) ) == sizeof(sum) && sum == dmarksurfaces_checksum
&& _read( handle, &sum, sizeof(sum) ) == sizeof(sum) && sum == dsurfedges_checksum
&& _read( handle, &sum, sizeof(sum) ) == sizeof(sum) && sum == dedges_checksum
&& _read( handle, &sum, sizeof(sum) ) == sizeof(sum) && sum == dtexdata_checksum
&& _read( handle, &sum, sizeof(sum) ) == sizeof(sum) && sum == dvisdata_checksum )
status = true;
_close( handle );
}
return status;
}
/*
==============
SaveIncremental
==============
*/
int
SaveIncremental(char *filename)
{
long size = 0;
int handle;
int expected_size = 13*sizeof(int);
if ( getfreespace(filename) >= expected_size )
{
if ( (handle = _open( filename, _O_WRONLY | _O_BINARY | _O_CREAT | _O_TRUNC, _S_IREAD | _S_IWRITE )) != -1 )
{
qprintf("Writing [%s] with new saved qrad data", filename );
if ( _write( handle, &dmodels_checksum, sizeof(int) ) == sizeof(int) && (size += sizeof(int))
&& _write( handle, &dvertexes_checksum, sizeof(int) ) == sizeof(int) && (size += sizeof(int))
&& _write( handle, &dplanes_checksum, sizeof(int) ) == sizeof(int) && (size += sizeof(int))
&& _write( handle, &dleafs_checksum, sizeof(int) ) == sizeof(int) && (size += sizeof(int))
&& _write( handle, &dnodes_checksum, sizeof(int) ) == sizeof(int) && (size += sizeof(int))
&& _write( handle, &texinfo_checksum, sizeof(int) ) == sizeof(int) && (size += sizeof(int))
&& _write( handle, &dclipnodes_checksum, sizeof(int) ) == sizeof(int) && (size += sizeof(int))
&& _write( handle, &dfaces_checksum, sizeof(int) ) == sizeof(int) && (size += sizeof(int))
&& _write( handle, &dmarksurfaces_checksum, sizeof(int) ) == sizeof(int) && (size += sizeof(int))
&& _write( handle, &dsurfedges_checksum, sizeof(int) ) == sizeof(int) && (size += sizeof(int))
&& _write( handle, &dedges_checksum, sizeof(int) ) == sizeof(int) && (size += sizeof(int))
&& _write( handle, &dtexdata_checksum, sizeof(int) ) == sizeof(int) && (size += sizeof(int))
&& _write( handle, &dvisdata_checksum, sizeof(int) ) == sizeof(int) && (size += sizeof(int)) )
{
qprintf("(%d)\n", size );
}
else
{
qprintf("...failed!");
}
_close( handle );
}
}
else
printf("Insufficient disk space(%ld) for incremental file[%s]'!\n",
expected_size, filename );
return size;
}
/*
==============
BuildVisMatrix
==============
*/
void BuildVisMatrix (void)
{
int c;
HANDLE h;
#ifdef HALFBIT
c = ((num_patches+1)*(((num_patches+1)+15)/16));
#else
c = num_patches*((num_patches+7)/8);
#endif
qprintf ("visibility matrix: %5.1f megs\n", c/(1024*1024.0));
if ( h = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, c ) )
vismatrix = GlobalLock( h );
else
Error ("vismatrix too big");
strcpy(vismatfile, source);
StripExtension (vismatfile);
DefaultExtension(vismatfile, ".r1");
if ( !incremental
|| !IsIncremental(incrementfile)
|| getfilesize(vismatfile) != c
|| getfiledata(vismatfile,vismatrix, c) != c )
{
// memset (vismatrix, 0, c);
RunThreadsOn (numleafs-1, true, BuildVisLeafs);
}
// Get rid of any old _bogus_ r1 files; we never read them!
unlink(vismatfile);
}
void FreeVisMatrix (void)
{
if ( vismatrix )
{
HANDLE h = GlobalHandle(vismatrix);
GlobalUnlock(h);
GlobalFree(h);
vismatrix = NULL;
}
}
/*
==============
touchfile
=============
*/
void
TouchFile(char *filename)
{
int handle;
if ( (handle = _open( filename, _O_RDWR | _O_BINARY )) != -1 )
{
char bytebuffer;
qprintf("Updating saved qrad data <%s> with current time.\n", filename);
_read( handle, &bytebuffer, sizeof(bytebuffer));
_lseek(handle,0,SEEK_SET);
_write( handle, &bytebuffer, sizeof(bytebuffer));
_close( handle );
}
}
/*
==============
CheckVisBit
==============
*/
qboolean CheckVisBit (int p1, int p2)
{
int t;
int bitpos;
if (p1 > p2)
{
t = p1;
p1 = p2;
p2 = t;
}
#ifdef HALFBIT
bitpos = p1 * num_patches - (p1*(p1+1))/2 + p2;
#else
bitpos = p1 * num_patches + p2;
#endif
if (vismatrix[bitpos>>3] & (1<<(bitpos&7)))
return true;
return false;
}

View File

@ -0,0 +1,55 @@
// ServerCtrl.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "ServerCtrl.h"
#include "ServerCtrlDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CServerCtrlApp
BEGIN_MESSAGE_MAP(CServerCtrlApp, CWinApp)
//{{AFX_MSG_MAP(CServerCtrlApp)
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CServerCtrlApp construction
CServerCtrlApp::CServerCtrlApp()
{
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CServerCtrlApp object
CServerCtrlApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CServerCtrlApp initialization
BOOL CServerCtrlApp::InitInstance()
{
// Standard initialization
CServerCtrlDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
}
else if (nResponse == IDCANCEL)
{
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}

View File

@ -0,0 +1,59 @@
// ServerCtrl.h : main header file for the ServerCtrl application
//
#if !defined(AFX_ServerCtrl_H__E2974CA6_EF9F_11D3_A4D9_00105A1727F3__INCLUDED_)
#define AFX_ServerCtrl_H__E2974CA6_EF9F_11D3_A4D9_00105A1727F3__INCLUDED_
#if _MSC_VER > 1000
#ifdef _WIN32
#ifndef __MINGW32__
#pragma once
#endif /* not __MINGW32__ */
#endif
#endif // _MSC_VER > 1000
#if defined _MSC_VER && _MSC_VER >= 1400
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif
#pragma warning(disable: 4996) // deprecated functions
#endif
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// CServerCtrlApp:
// See ServerCtrl.cpp for the implementation of this class
//
class CServerCtrlApp : public CWinApp
{
public:
CServerCtrlApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CServerCtrlApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CServerCtrlApp)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_ServerCtrl_H__E2974CA6_EF9F_11D3_A4D9_00105A1727F3__INCLUDED_)

View File

@ -0,0 +1,179 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
"#ifdef _WIN32\r\n"
"LANGUAGE 9, 1\r\n"
"#pragma code_page(1252)\r\n"
"#endif //_WIN32\r\n"
"#include ""res\\serverctrl.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
"#include ""afxres.rc"" // Standard components\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON DISCARDABLE "res\\serverctrl.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_SERVERCTRL_DIALOG DIALOGEX 0, 0, 549, 281
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Valve Server Controller"
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "Execute",IDC_BTN_EXECUTE,160,7,48,12
PUSHBUTTON "Get Text",IDC_BTN_GET,159,24,48,12
PUSHBUTTON "Start Server",IDC_BTN_START,478,54,64,12
DEFPUSHBUTTON "OK",IDOK,492,7,50,14
EDITTEXT IDC_EDIT_COMMANDS,7,7,144,12,ES_AUTOHSCROLL
EDITTEXT IDC_EDIT_CONSOLE,7,56,434,218,ES_MULTILINE |
ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY
END
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0"
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "serverctrl MFC Application\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "serverctrl\0"
VALUE "LegalCopyright", "Copyright (C) 2000\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "serverctrl.EXE\0"
VALUE "ProductName", "serverctrl Application\0"
VALUE "ProductVersion", "1, 0, 0, 1\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_SERVERCTRL_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 542
TOPMARGIN, 7
BOTTOMMARGIN, 274
END
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE 9, 1
#pragma code_page(1252)
#endif //_WIN32
#include "res\serverctrl.rc2" // non-Microsoft Visual C++ edited resources
#include "afxres.rc" // Standard components
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

Some files were not shown because too many files have changed in this diff Show More